Skip to main content
Version: Next

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.

ModePositioningBest for
CoordinateAbsolute X/Y within a fixed design size, scaled to fitP&ID mimics, plant overviews, anything where spatial relationships are the information
GridRows and columns, items snap to cellsDashboards, KPI walls, tabular layouts
FlexFlow layout, items size and wrapResponsive screens, forms, lists, anything viewed on varied displays
Breakpoint 1.0.4A separate authored screen per width tierA 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

ContainerPurpose
FlexContainerA flow container inside any view — the workhorse for grouping.
TabContainerMultiple panes behind tabs.
EmbeddedViewRenders another view inside this one.
FlexRepeaterRepeats 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.

MechanismUse
HorizontalMenu / VerticalMenuPersistent site navigation
LinkAn inline navigation target
navigate event actionNavigation from any component's event, with parameters
TabContainerSwitching within one screen

Navigation passes parameters, so one detail view serves every instance:

Overview → navigate("equipment-detail", { tagPath: "Line1/Filler/Motor1" })

Event actions

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

SymptomCauseFix
Slow to openVery many components, or many bindings resolving at onceSplit into embedded views; load detail on demand
Sluggish while runningHigh-rate bindings on many widgetsRaise tag deadbands; not every value needs 250 ms
Charts stutterToo many series, or too long a window at full resolutionReduce series; let the historian aggregate
Video stuttersSeveral full-resolution streamsUse 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.

Next

Property bindings