Drawing & Symbols
Beyond widgets, the Designer gives you vector drawing tools, a P&ID and electrical symbol library, and a library of your own symbols for building process mimics and control schematics — the view of a plant that operators read at a glance.
Drawing tools
Nine tools draw directly on the canvas. Every shape is a real component: bindable, animatable and event-capable, exactly like a widget.
| Tool | Draws |
|---|---|
| Line | Straight line with optional arrow heads, dash patterns and animation |
| Arrow | A line with a flippable arrow head at its centre |
| CurvedLine | Cubic Bézier curve with optional arrow heads |
| Rectangle | Rectangle with fill, stroke, rounded corners |
| Ellipse | Ellipse or circle |
| Polygon | Arbitrary vertex list |
| Freehand | Smooth freehand stroke with pressure-style tapering |
| Cylinder | Database/vessel cylinder with an elliptical rim |
| Cube | Isometric cube |
Full property tables are in the component reference.
Grouped properties Changed in 1.0.8
A shape's settings are grouped by what they are about, rather than listed flat. On a Line or Arrow:
| Group | Holds |
|---|---|
routing | style (how the points are joined) and corner |
stroke | color, width, dash, cap, opacity |
lineType | kind, spacing, count, scale, reverse — see line types |
pipe | The pipe look |
markers | start, end, mid, midFlip, size |
fittings | items, size — see fittings |
flow · fault | The live pipe bindings |
animation | type, duration, easing, active, direction, pivotX, pivotY |
The other tools carry the same stroke and animation groups, plus fill (or brush for
Freehand) where it applies.
Views saved by 1.0.7 are converted when they are first opened, and nothing on the canvas changes.
What is not rewritten is anything that names a property by its old flat name — a script writing
self.props.flowSource, a binding targeting strokeWidth, a copied path. Address the grouped name
instead: flowSource is now flow.source, strokeWidth is stroke.width, lineType is
lineType.kind, lineTypeSpacing is lineType.spacing, animationType is animation.type.
Routing
Lines and arrows support routing styles (routing.style), which determine how a connection gets
from A to B:
| Routing | Path |
|---|---|
straight | Direct, through the points as drawn |
orthogonal | Right angles — the P&ID convention for pipe runs |
horizontal / vertical | Leaves the origin along that axis first |
isometric | 30° isometric, matching the Cube and isometric symbols |
curved | Smooth |
entityRelation | ER-diagram style |
Use orthogonal for pipes and isometric for isometric plant views. straight is for annotation.
Selecting, turning and resizing Changed in 1.0.8
A selected shape or widget has square handles, a rotate knob, and a dashed outline drawn outside its painting, so a rectangle's own stroke no longer hides the selection. A rotated widget's selection turns with it and resizes along its own sides, with the opposite side held in place.
Turning snaps: hold Shift for 15° steps, and a turn that ends within 4° of level or upright lands exactly on it. Rotation lives on the selection now; double-clicking a shape edits its points, and only on shapes that have points.
Geometry
Shape geometry is stored normalized 0–1 within the shape's box, so a shape scales cleanly with its container and with the view. Omit the geometry properties to get sensible defaults — a diagonal line, a box-filling rectangle or ellipse. New shapes start at a 2.5 px line (Freehand 6 px).
Hold Shift while drawing a line, arrow or freehand stroke to constrain it to 45° increments. Drawing tools snap to points and outlines from the first hover, before you press.
Curves on a line 1.0.8. Double-click a line to edit its points, then
double-click a point to make it smooth — it grows Bézier handles and the segments either side
bend through them; double-click again for a corner. Curves draw on straight routing only, so a
routed line is switched to straight when you smooth a point.
Connecting a line to equipment
A line endpoint can bind to a component instead of sitting at a fixed point. Bound, it snaps to that component and follows it: drag the pump and the pipe stays attached, which is the difference between a drawing that is correct when authored and one that stays correct.
| Property | What it does |
|---|---|
startBindNode / endBindNode | The component this end attaches to. Set it and the matching x1Norm/y1Norm (or x2Norm/y2Norm) stop being used. Empty means a free point. |
startBindPort / endBindPort | Where on that component to attach. auto (the default) picks the nearest point on the component's drawn outline facing the other end, so the line touches the symbol body rather than its bounding box. |
Use a fixed port — top, right, bottom, left, centre or a corner — when the nozzle elevation
carries meaning. A bottoms line must leave the bottom of the column, and auto will not know
that.
Named ports 1.0.8. A symbol of your own can declare named ports — its nozzles and terminals. While you drag a line end, the snap highlight shows them as dots, and an end dropped within 12 px of one pins to it and stays there through move, resize, rotate and flip.
Branches 1.0.8. A line end can also land part-way along another line. It binds to that point along the other line's path, so the branch follows when the main run moves. A line drawn off a pipe takes the pipe's look, and where a pipe branch meets a pipe the joint is drawn as a mitred tee rather than one pipe stopping on top of the other. With Shift held, a straight branch ends where it crosses the pipe.
For anything more than a straight run, add waypoints: intermediate points the routed path passes
through, edited by dragging on the canvas. Combined with orthogonal routing, that is how a pipe run
gets around the equipment between its two ends.
Fittings that ride the pipe New in 1.0.1
A flange, orifice plate, strainer or spectacle blind is an in-line device: it belongs to the run,
not beside it. Set the line's fittings.items and each one sits on the pipe and moves with it:
fittings.items: [email protected] [email protected]!
Each token is a symbol key, @, and a position from 0 to 1 along the routed path. A trailing
! flips the fitting. The fittings menu on the line's toolbar lists every fitting in one scrolling
list.
The position is normalised arc length, not a page coordinate, which is the whole point: drag the pipe, add an orthogonal bend, or change the routing mode, and each fitting keeps its place along the pipe rather than being left behind at a coordinate that no longer means anything.
fittings.size (default 22 px) sets how large they are drawn. Unlike a line-type mark it does
not scale with the stroke width — a fitting is a component whose size you chose, not an ornament
on the stroke. Fittings are not drawn on a pipe.
Correct for a flange, an orifice plate or a blind, and slightly wrong for a reducer. Breaking the stroke would collide with the line type's dash and with the flow animation's marching dash, so it is deliberately not done. Dragging a fitting along its pipe is not available either — set the position numerically.
P&ID line types New in 1.0.1
ISA-5.1 tells signal lines apart by a repeated glyph, not by colour — and only one of them,
electric, is expressible as a dash. So a line's meaning is a property of its own, lineType.kind,
rather than another entry in the dash list. The line-style picker lists them under P&ID line
type.
| Type | Drawn as | Means |
|---|---|---|
| None (use dash) | Whatever stroke.dash says | The default. No P&ID meaning imposed. |
| Process (Plain line) | Solid, unornamented | A pipe — and the plain line. |
| Electric | Dashed | An electric / electronic instrument signal. The default for 4–20 mA. |
| Electric (binary) | Dashed, with a single backward slant | An on/off signal — open/closed, run/stop, permissive. |
| Pneumatic | Solid, with double slanted hash marks | Instrument air, e.g. 3–15 psig. |
| Pneumatic (binary) | The pneumatic hash, crossed | On/off instrument air rather than a modulating signal. |
| Data link | Solid, with small hollow circles | A software or digital link: fieldbus, Ethernet, any digital protocol. |
| Hydraulic | Solid, with "L" marks | A hydraulic signal. |
| Capillary | Solid, with X marks | A filled thermal system — a bulb-and-capillary temperature element. |
| Electromagnetic / sonic | Solid, carrying a wave | Radar, ultrasonic, radiometric. The guided form. |
| Mechanical link | Solid, with small filled dots | A physical linkage — lever, cable, shaft. Not a signal. |
| Flow arrows 1.0.8 | Short arrows, no line | Which way the line flows — see below. |
Three settings tune how the marks are drawn:
| Property | Default | Effect |
|---|---|---|
lineType.spacing | 0 | Gap in px between marks. 0 uses the type's own interval. The readable interval depends on your sheet scale. |
lineType.count | 0 | Draw exactly this many marks, spread evenly. 0 = auto, so the count grows with the line's length. Overrides the spacing. |
lineType.scale | 1 | Size multiplier for the marks. Grows the mark, not its stroke weight. |
The default is none, deliberately. Every line drawn before this existed predates the property,
and any other default would restyle drawings nobody asked to change. none also keeps a live pipe's
flow animation alive — a type that forced an empty dash would stop the marching dashes dead.
A type owns the dash pattern and the glyph and nothing else. ISA draws signal lines thinner than process lines, but enforcing that here would silently overwrite a stroke weight you chose on purpose, so the thinner weight stays a recommendation rather than a rule.
Data link and Mechanical link are read as hollow versus filled, so they are drawn at the same size on purpose. A size difference would make them look like two unrelated marks rather than the two halves of one distinction.
Flow arrows New in 1.0.8
Flow arrows, in the Flow group of the line-style picker, replace the line with a row of short
arrows — a stem and a solid head, in the line colour — pointing the way the line was drawn.
Reverse direction (lineType.reverse) turns them round.
They move only while the line flows: while its flow animation runs (animation.type is flow)
or while a bound flow.source reads as flowing. Otherwise they hold still, still pointing the way
the material goes — which is why they are arrows rather than dashes: direction stays readable on a
stopped line and on a thin stroke. A negative flow (with flow.direction on auto) turns them round
while it lasts. Under the operator's reduced-motion setting they stay still.
A new arrow arrives every animation.duration ÷ 4 seconds (2 s by default, so one every half
second). The arrows grow with the stroke width and the spacing grows with them, so a thick line's
arrows never run into each other; a hand-set lineType.spacing is opened up to a clear gap.
Pipes New in 1.0.8
Set pipe.look to round and a Line or Arrow is drawn as a shaded round pipe, its shading
following every bend. Use stroke.width as the diameter — 8 to 14 px reads as a pipe.
| Setting | Effect |
|---|---|
pipe.shading | line shades in the line colour, and follows live flow, idle and fault colours. A material — steel, stainless, copper, pvc, iron, insulated — or custom (edge, middle, centre colours) uses its own gradient. |
pipe.arrows | Flow arrows inside the pipe: flow (the default — only while it flows, moving), always (also when still, holding), none |
pipe.arrowSize · arrowSpacing · arrowReverse · arrowColor | Size (0.25–4×), gap (0 = auto), direction and colour (empty = translucent white) of those arrows |
On a pipe, arrow markers become shaded pipe heads, the dash is ignored, and line types and fittings are not drawn. The Symbol Editor draws pipes the same way.
Live pipes
A line can show flow without a single number on it. Point flow.source at a tag — a flow rate, or a
run/stop flag — and the line becomes live:
| Property | Purpose |
|---|---|
flow.source | The tag that drives the pipe. Leave it empty for a static line. |
flow.compare / flow.threshold | How that value is tested for "flowing" — > 0 by default. |
flow.color | Stroke while flowing. Muted by default, not vivid — an HP HMI screen where everything normal is loud has nothing left to say when something is wrong. |
flow.idleColor | Stroke while stopped. |
flow.direction | Which way it flows. auto takes it from the value's sign, so a negative flow reverses. |
fault.source / fault.color | A tag whose truthy value turns the pipe the alarm colour — a broken or discordant flow path. Wins over flow. |
While flowing, a plain line marches its dash; flow arrows and a pipe's inner arrows move instead.
For other motion — blink, pulse, glow, rotate — use the animation group, and bind
animation.active to a tag to animate only while it is true.
The symbol library
1048 symbols in two disciplines, drawn to industry convention: 485 process (P&ID) symbols across 21 categories, 529 electrical 1.0.4 across 24, and 34 arrows. The Symbol Library palette separates them into Process, Electrical and Arrows tabs, so you are never scrolling past capacitors to reach a centrifuge. A fourth tab, Imported 1.0.8, holds your own symbols.
A symbol left on its default line colour draws in the same ink as the built-in Tank's outline, so symbols, tanks and scales match in both themes 1.0.8. A colour you choose, or a state colour, still wins.
Process (P&ID) — 485
| Category | Symbols | Category | Symbols |
|---|---|---|---|
| Misc | 82 | Flow Sensors | 16 |
| Vessels | 63 | Crushers & Grinding | 13 |
| Piping | 43 | Agitators | 10 |
| Pumps | 37 | Centrifuges | 8 |
| Fittings | 35 | Driers | 8 |
| Instruments | 32 | Engines | 8 |
| Valves | 31 | Shaping Machines | 7 |
| Heat Exchangers | 23 | Apparatus Elements | 6 |
| Compressors | 20 | Feeders | 5 |
| Separators | 18 | Mixers | 4 |
| Filters | 16 |
Electrical — 529 New in 1.0.4
| Category | Symbols | Category | Symbols |
|---|---|---|---|
| Connectors & Misc | 67 | Rotating & Mechanical | 17 |
| Switches & Contacts | 52 | Capacitors | 16 |
| Functional Blocks | 45 | Opto-electronics | 15 |
| Inductors & Transformers | 39 | Transmission Lines | 13 |
| MOSFETs | 36 | Diodes | 13 |
| Logic Gates | 34 | Radio & Antennas | 11 |
| Resistors | 23 | Operational Amplifiers | 10 |
| Transistors | 23 | Relays & Coils | 8 |
| Waveforms | 23 | Thermionic Devices | 7 |
| Signal Processing | 21 | Signalling & Indication | 6 |
| Power Semiconductors | 21 | PLC Ladder | 6 |
| Signal Sources | 18 | Meters | 5 |
Enough for a single-line diagram, a control schematic, a ladder rung or a motor-starter panel — alongside the process symbols, on the same canvas, in the same view.
Symbols that show their state
77 symbols carry an operating state you can bind to a tag, and the artwork changes with it. A contact really opens; a coil really lights.
| Vocabulary | Symbols | Shown by | Typical |
|---|---|---|---|
open · closed | 44 | The artwork swaps | Contacts, breakers, isolators, limit and pressure switches |
off · on | 19 | The body fills | Lamps, LEDs, coils, bells, buzzers |
false · true | 6 | The outline recolours | PLC ladder elements |
p1 … pN | 7 | The artwork swaps, one drawing per position | 2-, 3-, 4- and 6-position selectors |
open · closedUpper · closedLower | 1 | The artwork swaps | Two Way Contact — it rests neutral and throws either way |
Bind the symbol's state property like any other:
Make Contact
state → map(Line1/MCC/K101/Aux): 0 → open, 1 → closed
Pilot Light
state → map(Line1/MCC/K101/Run): 0 → off, 1 → on
The fill-versus-recolour split is not a setting: a coil or lamp is a closed body that can be filled, while a ladder rung or a bell is open line art where a fill would paint nothing.
The second state is authored as a geometry delta — "rotate this blade about that pivot" — not as a second hand-drawn symbol. Both variants therefore share a viewBox and terminal positions, so a symbol does not jump when the tag flips, and a line you connected to it stays connected. The snap outline resolves the same variant the canvas is showing, so the highlight can never trace one state while you look at another.
A symbol with no state bound renders its default — bolded in the component reference — and a state a symbol does not define falls back to that same default rather than rendering nothing.
Symbols are components like any other: bind their colour to a state tag, attach a click event to open a faceplate, scale them with the view.
The complete list, by discipline and category, is in the component reference.
Your own symbols New in 1.0.8
When the plant has equipment no standard draws — a vendor's pump, a particular kiln — import its SVG drawing, or draw it, in the Symbol Editor. Name its parts, declare parameters, and give the parts rules: spin while running, fill to the level, turn red in fault, swing open and closed. Declare ports for its nozzles and terminals. The symbol joins the Imported tab of the palette, for every project, and a placed copy binds its parameters to tags like any property.
Right-click a placed symbol of your own and pick Edit Symbol to change it.
Building a mimic
- Choose a coordinate view. Position carries meaning in a mimic. → Layout modes
- Place equipment symbols — vessels, pumps, valves, heat exchangers.
- Connect them with orthogonal lines for pipe runs, ending on the equipment so they stay attached.
- Bind colours to state. A
maptransform from a state tag to a colour is the whole technique. → Property bindings - Animate flowing lines where material is moving — bind
flow.source. - Add value displays at the points an operator actually reads.
- Attach click events so each symbol opens the faceplate for its equipment.
Pump symbol
fill → map(Line1/P101/State): 0 → grey, 1 → green, 2 → red
click → Navigate("pump-detail", { tagPath: "Line1/P101" })
Discharge line
lineType → Flow arrows
flow.source → Line1/P101/Running (compare: truthy)
Colour conventions
Consistency matters more than the specific palette. A workable convention:
| State | Colour |
|---|---|
| Stopped / off / closed | Grey |
| Running / open / flowing | Green |
| Alarm / faulted | Red |
| Warning / transitioning | Amber |
| Bad quality / unknown | Hatched, or a distinct neutral |
Give bad quality its own appearance. A grey pump that means "stopped" and a grey pump that means "we have no idea" is the failure mode operators remember.
Check the palette against colour-vision deficiency: roughly 8% of men cannot separate your red from your green. Pair colour with shape, an icon or a label for anything safety-relevant.
Rendering notes
Vector shapes paint outside their nominal bounding box — stroke width, arrow markers and animations all extend beyond it. The Designer accounts for this, which is why a shape near a container edge is never clipped in LiveView the way a naïvely-clipped element would be.
Shapes use currentColor by default, so they inherit the surrounding text colour. That is what
makes a mimic look correct in both light and dark themes without a second set of colours.
Performance
- A few hundred shapes on a view is comfortable; several thousand is not. Split large plants across an overview plus per-area detail views.
- Animate the lines that carry meaning, not every line.
- Freehand strokes are the most expensive shape — fine for annotation, not for structure.