Operators need to see live values alongside the equipment and connections they describe.
Updated September 10, 2026
Problem
Operators understand equipment through its connections. A list of separate values makes them reconstruct those relationships each time they look.
Solution
Show a simple diagram of the process, with live values near the relevant equipment. Preserve the connections and direction of flow even when the layout simplifies physical distances.
Use flat, readable shapes and keep normal equipment visually quiet. Mark abnormal states with labels or symbols as well as color.
Organize large processes into linked views with a clear route between them. Keep the diagram aligned with changes to the actual system.
Use when
People understand the process and need to read component values in the context of their connections.
Don’t use when
There is no physical referent. Drawing a schematic of an abstract system invents a spatial arrangement that carries false meaning, and viewers will read adjacency as relationship whether it is one or not.
Trade-offs
Diagrams take effort to build and keep accurate. Large processes need several views, and fixed spatial layouts adapt poorly to small screens. Decorative realism can make the important states harder to notice.
Checklist
Is the layout faithful to process flow, and is geometric fidelity helping or hurting?
Is the base graphic greyscale, with colour reserved for abnormal states?
Does anything animate, and does the animation encode real information?
Is equipment state readable without colour alone?
What happens when a value is stale or its source is unreachable?
How many linked displays exist, and how does an operator move between them?
What keeps the diagram in step with the physical plant when it changes?
Is the display readable from where the operator actually sits?
Are alarm states distinguishable from setpoint deviations?
Does a new operator get taught this display, or expected to absorb it?
Compare
Ignition, WinCC and the other industrial SCADA platforms are where this pattern lives, and their template libraries have been steadily stripped of the 3D chrome that characterised them a decade ago as ISA-101 took hold. Grafana has a canvas panel that can approximate a mimic by placing elements freely and binding them to data, which brings the pattern into general observability and lacks the alarm-state model that makes an industrial version safe. Building management and energy systems use the same encoding for chillers, air handlers and circuits, with the same drift problem when the building is modified. Service map is the closest thing in software, and it differs in a way worth noting: its topology is discovered from traffic rather than drawn by an engineer, so it cannot go stale in the way a mimic can.
Related
Grayscale with alerts keeps warnings prominent. Gauge may match a familiar instrument. Semantic status color defines equipment states.
Service map shows software dependencies. Wallboard mode addresses shared and distant viewing.
Wireframe — the pattern's anatomy, not any one product's version of it
Implementation
A schematic of the physical plant with live values on it. The layout is the operator's mental model, so it must not be rearranged for visual balance the way a dashboard grid can be.
ProcessMimic.tsxEquipment as coordinates, pipes as polylines, readings by tag. Neutral until a status leaves nominal, and the glyph travels with the colour.
import { cn } from "@/lib/utils";/** The closed set. Nothing else may be styled as a status. */export type Status = "nominal" | "warn" | "critical" | "unknown";/** Colour only leaves neutral for an abnormal state, and never alone: the glyph goes with it. */const STATUS: Record<Status, { stroke: string; text: string; glyph: string | null }> = { nominal: { stroke: "stroke-border", text: "fill-foreground", glyph: null }, warn: { stroke: "stroke-status-warn", text: "fill-status-warn", glyph: "▲" }, critical: { stroke: "stroke-status-critical", text: "fill-status-critical", glyph: "▲" }, unknown: { stroke: "stroke-status-unknown", text: "fill-status-unknown", glyph: "?" },};export type Kind = "vessel" | "valve" | "pump" | "instrument" | "outlet";/** A piece of plant, placed where the operator expects it. The tag is the one printed on the equipment. */export type Equipment = { tag: string; kind: Kind; x: number; y: number; w?: number; h?: number };export type Reading = { value: number; unit: string; status: Status; stale?: boolean };const fmt = (r: Reading) => (r.unit === "%" ? `${r.value}%` : `${r.value} ${r.unit}`);const Value = ({ x, y, r, className, anchor = "middle" }: { x: number; y: number; r?: Reading; className?: string; anchor?: "start" | "middle" }) => r ? ( <text x={x} y={y} textAnchor={anchor} className={cn("text-[11px] tabular-nums", r.stale ? "fill-muted-foreground" : STATUS[r.status].text, className)}> {STATUS[r.status].glyph && <tspan>{STATUS[r.status].glyph} </tspan>} {fmt(r)} {r.stale && <tspan className="text-[9px]"> stale</tspan>} </text> ) : null;/** * Flat and grey, with live values where the instruments are. The layout is * the operator's mental model, so it arrives as coordinates and is drawn as * given, never rearranged for balance. A vessel's level is its fill height. */export function ProcessMimic({ equipment, pipes, readings, width = 440, height = 230 }: { equipment: Equipment[]; /** Polylines between equipment, in the same coordinate space. */ pipes: [number, number][][]; readings: Record<string, Reading>; width?: number; height?: number;}) { return ( <svg viewBox={`0 0 ${width} ${height}`} width={width} height={height} className="max-w-full" role="img" aria-label="process mimic"> {pipes.map((p, i) => ( <polyline key={i} points={p.map(([x, y]) => `${x},${y}`).join(" ")} fill="none" className="stroke-border" strokeWidth={2} /> ))} {equipment.map((e) => { const r = readings[e.tag]; const st = r?.stale ? "stroke-border" : STATUS[r?.status ?? "nominal"].stroke; const dash = r?.stale ? "4 3" : undefined; const tag = <text className="fill-muted-foreground text-[9px]" textAnchor="middle">{e.tag}</text>; switch (e.kind) { case "vessel": { const w = e.w ?? 70, h = e.h ?? 92; const level = r ? Math.min(1, Math.max(0, r.value / 100)) * h : 0; return ( <g key={e.tag}> <rect x={e.x} y={e.y + h - level} width={w} height={level} className="fill-muted" /> <rect x={e.x} y={e.y} width={w} height={h} rx={3} fill="none" className={st} strokeWidth={r?.status === "nominal" ? 1.5 : 2} strokeDasharray={dash} /> <text x={e.x + w / 2} y={e.y - 8} textAnchor="middle" className="fill-muted-foreground text-[9px]">{e.tag}</text> <Value x={e.x + w / 2} y={e.y + h / 2} r={r} /> </g> ); } case "valve": return ( <g key={e.tag}> <circle cx={e.x} cy={e.y} r={9} className={cn("fill-card", st)} strokeWidth={1.5} /> <path d={`M${e.x - 5} ${e.y - 4} L${e.x + 5} ${e.y + 4} M${e.x - 5} ${e.y + 4} L${e.x + 5} ${e.y - 4}`} className="stroke-muted-foreground" /> <g transform={`translate(${e.x} ${e.y + 26})`}>{tag}</g> </g> ); case "pump": return ( <g key={e.tag}> <path d={`M${e.x} ${e.y - 12} L${e.x + 26} ${e.y} L${e.x} ${e.y + 12} Z`} className={cn("fill-muted", st)} strokeWidth={1.5} /> <Value x={e.x + 13} y={e.y - 20} r={r} className="text-[10px]" /> <g transform={`translate(${e.x + 13} ${e.y + 30})`}>{tag}</g> </g> ); case "outlet": return ( <g key={e.tag}> <rect x={e.x} y={e.y} width={e.w ?? 88} height={e.h ?? 30} rx={3} fill="none" className="stroke-border" strokeWidth={1.5} /> <text x={e.x + (e.w ?? 88) / 2} y={e.y + (e.h ?? 30) / 2 + 4} textAnchor="middle" className="fill-muted-foreground text-[9px]">{e.tag}</text> </g> ); case "instrument": return ( <g key={e.tag}> <text x={e.x} y={e.y} className="fill-muted-foreground text-[9px]">{e.tag}</text> <Value x={e.x} y={e.y + 16} r={r} className="text-[10px]" anchor="start" /> </g> ); } })} </svg> );}
demo.tsxHow it is called: the plant as data, and the readings with one vessel in warn.
Screenshots are grouped by product and include the capture date.
Dashed boxes highlight this pattern. Notes appear below each screenshot and when you hover over a box.
Water Treatment / Overview September 11, 2026Ignition Perspective public demo, Water Treatment (signed out)dense · dark · desktop-web
The demo uses simulated plant data in a process diagram arranged from incoming water through treatment and storage. Values appear beside the relevant equipment. Green means running, while stopped filters are gray and explicitly labeled. This makes normal operation colorful, unlike a display that reserves color for warnings. Repeated filter panels and clear process connections help people compare equipment.
Process mimicEquipment and values follow the process flow.