Views & Layout
A view is one screen. Views live in a project, are addressed by slug, and are composed from components arranged by a layout mode.
Layout modes
Choose per view. The choice is not cosmetic — it determines how the screen behaves on a display size you did not anticipate.
| Mode | Positioning | Best for |
|---|---|---|
| Coordinate | Absolute X/Y within a fixed design size, scaled to fit | P&ID mimics, plant overviews, anything where spatial relationships are the information |
| Grid | Rows and columns, items snap to cells | Dashboards, KPI walls, tabular layouts |
| Flex | Flow layout, items size and wrap | Responsive screens, forms, lists, anything viewed on varied displays |
| Breakpoint 1.0.4 | A separate authored screen per width tier | A screen whose phone version is genuinely different, not merely narrower |
Coordinate
The classic SCADA canvas. You place a pump exactly where the pump is on the line, draw pipes between equipment, and the whole view scales to the display.
Use it when position carries meaning. Do not use it for a dashboard that must look right on both a 55" wall panel and a tablet — that is what flex is for.
Grid
Components occupy grid cells and can be dragged and resized within the grid. Good for dashboards where alignment matters more than exact position, and where a maintainer will add a tile later.
Flex
Components flow, size and wrap. This is the mode that survives contact with an unexpected screen size. Use it for forms, lists, side panels and anything that will be viewed on more than one device class.
Breakpoint New in 1.0.4
Where flex adapts one layout, breakpoint replaces it. Each width tier — mobile, tablet,
desktop by default — gets its own panel, and the container renders exactly one of them. A tier can
also mirror another, so a fresh view costs two authored screens rather than three.
Use it when the wide and narrow versions differ in what they show, not just how it is arranged: a desktop trend, alarm table and control strip against three numbers and an acknowledge button on a phone.
The cost is that every tier you author is a screen you maintain, which is why flex remains the right default. → Breakpoint layout
Containers
| Container | Purpose |
|---|---|
| FlexContainer | A flow container inside any view — the workhorse for grouping. |
| TabContainer | Multiple panes behind tabs. |
| EmbeddedView | Renders another view inside this one. |
| FlexRepeater | Repeats a view once per item in a bound array. |
Nest deliberately. Two or three levels of container is readable; six is a layout nobody will maintain.
Embedded views
The single most valuable pattern in the Designer.
Author MotorFaceplate once, with a parameter for the tag path:
MotorFaceplate params: { tagPath }
Text → {tagPath}/Name
Gauge → {tagPath}/Speed
Indicator → {tagPath}/Running
AlarmEvent → {tagPath}
Then embed it wherever a motor appears:
EmbeddedView MotorFaceplate { tagPath: "Line1/Filler/Motor1" }
EmbeddedView MotorFaceplate { tagPath: "Line1/Filler/Motor2" }
EmbeddedView MotorFaceplate { tagPath: "Line1/Capper/Motor1" }
One change to the faceplate updates every motor on every screen. This is the visualization counterpart of a UDT, and the two are designed to be used together.
Repeaters
A FlexRepeater takes an array and renders an embedded view per item, passing the item as parameters.
FlexRepeater
bound to → query: SELECT path, name FROM active_equipment
renders → EquipmentCard { tagPath: item.path, label: item.name }
The screen then grows and shrinks with the plant instead of being rebuilt when equipment is added.
Navigation
| Mechanism | Use |
|---|---|
| HorizontalMenu / VerticalMenu | Persistent site navigation |
| Link | An inline navigation target |
| navigate event action | Navigation from any component's event, with parameters |
| TabContainer | Switching within one screen |
Navigation passes parameters, so one detail view serves every instance:
Overview → navigate("equipment-detail", { tagPath: "Line1/Filler/Motor1" })
The view tab strip New in 1.0.0
Open views sit on a strip along the bottom of the Designer. A view with unsaved changes shows a dot where its close button goes; reach for the close and the dot becomes the button, so a tab never loses its unsaved indicator to a hover.
The strip does not scroll. A horizontal scrollbar in a 40-pixel bar is a four-pixel target that is present in the DOM and undiscoverable in practice, and it leaves the view you are editing off-screen with nothing to say it exists. Instead the strip shows a window over the tabs — the run that fits — with a control on each side that appears only when something is hidden behind it, and a list button for every open view.
Tabs are sized by their title, capped and then ellipsised, rather than dealt equal shares of the row: Home and Line 3 Kiln Preheater Detail are not the same size, and forcing them to be wastes the row on the short one while truncating the long one for nothing.
Closing a tab activates its neighbour, not the last tab on the strip. Closing tab 3 of 20 and landing on tab 20 reads as a teleport, and with a windowed strip it scrolls the whole thing out from under you. Closing an inactive tab never moves focus at all.
Screen structure that scales
Overview plant-wide status and alarm summary
Line1/Overview line status, embedded equipment cards
Line1/Detail equipment detail, parameterised
Diagnostics connection health, service status
- One overview per level of the plant hierarchy.
- One parameterised detail view per equipment class, not per instance.
- A diagnostics screen that shows connection and service health, so the first question after "the screen is blank" has an answer.
Design size and scaling
Coordinate views declare a design size and scale to the display. Author at the resolution of the primary target (typically the control-room panel) and verify on the smallest device that will use it.
For screens that must genuinely adapt rather than scale, use flex — scaling a coordinate view down makes text unreadable long before it makes the layout wrong.
Performance
| Symptom | Cause | Fix |
|---|---|---|
| Slow to open | Very many components, or many bindings resolving at once | Split into embedded views; load detail on demand |
| Sluggish while running | High-rate bindings on many widgets | Raise tag deadbands; not every value needs 250 ms |
| Charts stutter | Too many series, or too long a window at full resolution | Reduce series; let the historian aggregate |
| Video stutters | Several full-resolution streams | Use sub-streams |
Screen performance is usually a data problem, not a rendering problem. Look at binding rates and tag deadbands first.
Export and import
Exporting and importing a project's view tree both require Manage the Designer.
Use it to promote screens from development to production, or to template a standard line.