...
The choice isn't about aesthetics — it's about the question the operator is answering when they open the page.
| Operator question | Canvas | Dashboard |
|---|
| "Where in the plant is this happening?" |
?| x |
|
| "Is flow going through path A or path B?" |
?| x |
|
| "What's the state of equipment X right now?" |
? ? | x (if ungrouped KPI) |
| "How is KPI X trending?" | x (possible) |
?| x |
| "Which area has the most alarms?" |
?| x (possible) | x |
| "Is the plant running within normal bounds today?" | x (possible) |
?| x |
| "I need to click on a valve / pump / tank." |
? | x (better here) | x (possible) |
| "I need a one-glance shift summary." |
?Rule of thumb: if removing the equipment layout and putting the same data in a grid of tiles would lose meaning, it's a Canvas. If the layout is indifferent to plant geometry, it's a Dashboard. Most plants need both — a Canvas per process area, and a Dashboard for the plant as a whole.
...
- Divide the canvas into zones. Rectangular regions for each process section (Intake, Treatment, Distribution) or each info panel (Equipment Detail, Live Metrics, Identity).
- Lay zone background Rectangles first. These are the visual scaffolding — operators read the display by scanning zones, not individual shapes.
- Place elements WITHIN zone coordinates. Everything in a zone has its Left/Top relative to the zone's origin.
- Connect zones with flow indicators. Arrows, pipe lines, direction markers.
Canvas sizes
| Canvas | Width × Height | When |
|---|
| Standard HD | 1366 × 728 | Default, works everywhere |
| Wide | 1600 × 900 | Modern control-room monitors |
| Full HD | 1920 × 1080 | Dedicated operator displays |
| 4K scaled | 3840 × 2160 | Rare — prefer 1920×1080 with StretchFill |
Zone math (any canvas size, N zones)
...
Call list_elements('Shapes') for the authoritative shape catalog in the current release. Common primitives — all Canvas-only, all theme-aware (Fill/FillTheme, Stroke/StrokeTheme, StrokeThickness):
| Shape | Required | Use when |
|---|
| Rectangle | — | Panels, status bars, tank bodies, bars, backgrounds. Has RadiusX/RadiusY for rounded corners. |
| Ellipse | — | Tank caps (top/bottom), status LEDs, sight glasses, pump bodies. Circle when Width=Height. |
| Polygon | Points ≥ 3 | Arrows, funnels, hoppers, diamonds. Auto-closes. Set Stretch: "None" to preserve exact point coords. |
| Polyline | Points ≥ 2 | Open curved lines. Doesn't close. Prefer Gridline for pipes. |
| Path | Data | Any curve, arc, complex shape. SVG mini-language (M L H V C Q A Z). |
| Gridline | Points ≥ 2 | Use for pipes and orthogonal connections. Constrained to horizontal/vertical segments. The P&ID convention. |
| Spline | Points ≥ 2 | Smooth curves through control points (Catmull-Rom). Rare — Path covers most cases. |
Pipe segment pattern
json { "Type": "Gridline", "Left": 300, "Top": 200, "Points": "0,0 100,0 100,60 200,60", "StrokeTheme": "Water", "StrokeThickness": 6, "StrokeLineJoin": "Round", "StrokeLineCap": "Round" }
...
These are first-class shape primitives that write with just Type + geometry + colors. The platform auto-injects the underlying Path/Polygon geometry on save. Massive productivity win over composing from primitives. Call list_elements('Shapes') for the authoritative list in the current release. Common auto-shapes:
| Type | Default geometry | Use for |
|---|
| Cylinder | Vertical cylinder with elliptical caps | Tanks, vessels, drums, silos |
| Gear | 8-tooth gear | Machinery icons, manual/auto toggles |
| Arrow | Right-pointing arrow | Flow direction, callouts (rotate via RotateDynamic for other directions) |
| Cloud | Puffy cloud outline | MQTT broker, cloud service, weather |
| Star | 5-pointed star | Favorites, highlights, quality marker |
| Hexagon | Regular hexagon | Node diagrams, honeycomb layouts |
| Pentagon | Regular pentagon | Rare — use for ANSI warning signs |
| Trapezoid | Isosceles trapezoid | Hoppers, funnels, cone-bottom tank sections |
<ac:structured-macro ac:name="code"> <ac:parameter ac:name="language">json</ac:parameter> ac:plain-text-body{ "Type": "Cylinder", "Left": 300, "Top": 200, "Width": 80, "Height": 180, "FillTheme": "ElementBlue" }</ac:plain-text-body> </ac:structured-macro>
...
Section 4 — Containers (ShapeGroup, SvgGroup, Group)
| Container | Children | Dynamics apply to | Use for |
|---|
| ShapeGroup | Shapes only | ALL children uniformly | "The whole vessel turns alarm red when Running=0" |
| SvgGroup | Auto-parsed from inline SVG string | ALL children (normalized to ShapeGroup on write) | "I have an SVG, I want dynamics per element" |
| Group | Any element type | Each child has independent dynamics | "Interactive panel with chart+buttons that moves as a unit" |
ShapeGroup — compose equipment with unified state
...
ActionDynamic action types
| ActionType | Extra fields | What it does |
|---|
OpenDisplay | ObjectLink: "DisplayName" | Navigate to another display |
ToggleValue | ObjectLink: "@Tag.X" | Flip a boolean tag |
SetValue | ObjectLink: "@Tag.X", ObjectValueLink: value | Write a specific value |
RunScript | ActionScript: "MethodName" | Run a CodeBehind method |
Mouse events beyond MouseLeftButtonDown: MouseRightButtonDown, MouseDoubleClick, MouseEnter, MouseLeave. Each is a top-level key on the ActionDynamic.
...