Plot
Line charts drawn as light on glass, or as ink on a panel: gridlines faint, two traces at most, a red line for now.
Kit part · Charts
A strip-chart recorder: gridded paper advancing under a pen that rides a rail, drawing the live value as the paper moves and printing the time in the margin. For p95 latency, tokens per second, grid frequency, a cold room’s log.
Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.
Aluminium
| Part | Running | Stopped · pens up | Alarm | Off the scale |
|---|---|---|---|---|
| Recorder |
Graphite
| Part | Running | Stopped · pens up | Alarm | Off the scale |
|---|---|---|---|---|
| Recorder |
| Name | Kind | Values | What it does |
|---|---|---|---|
| <tui-recorder> | element | — | The recorder: builds the head, the paper window, the pens and the scale inside itself. |
| label | attribute | text | The chart’s name, printed in the head and read as the figure’s name. |
| unit | attribute | e.g. "ms", "Hz" | Printed on the display and the scale, and read out with every figure. |
| min · max | attribute | 0 · 100 | The scale. A reading beyond it pins the pen to its stop; the display still shows it. |
| high · low | attribute | number | Set-points: an index on the scale, a dashed line on the paper, and the red lamp while pen 1 is past one. |
| divisions · precision | attribute | auto | Major divisions on the scale (the first of 5, 4, 6, 8, 10 that gives a round step) and the decimals of a reading. |
| pen · pen2 | attribute | names | The pens’ names in the legend. Naming pen2 brings the second pen, dashed, on its own rail. |
| speed | attribute | seconds, 5 | How long one division of paper takes to pass the pen. The paper keeps time whether or not readings arrive. |
| advance | attribute | "time" · "sample" | Time moves the paper by the clock; sample moves it one division for each reading, for data that arrives in batches. |
| stopped | attribute | boolean | The chart drive is off: the paper halts and the pens lift. Readings still reach the display. |
| values · values2 · interval | attribute | numbers · seconds | A history from markup, oldest first, ending now; interval is the time between readings. |
| .push(value, value2) | method | numbers | A reading for each pen, now. Anything not a number lifts that pen until the next. |
| .setData(values, { values2, interval, end }) | method | arrays · seconds · Date | Replaces the paper with a history, oldest first, ending at end (now). |
| .start() · .stop() · .clear() | method | — | Run or stop the chart drive; blank the paper. |
| .value · .value2 · .running | property | number · boolean | The latest readings, and whether the paper is moving. |
| alarm | event | detail { level, was, value } | Pen 1 crossed a set-point: level is "high", "low" or "ok". |
| --tui-recorder-h | CSS property | 200px | The height of the paper window. |
| data-level · data-lifted | attribute | set by the part | Where pen 1 is against the set-points; present while the pens are up. |
<tui-recorder label="p95 latency · api-gateway" unit="ms"
min="0" max="500" high="300"
pen="p95" pen2="p50" speed="1"></tui-recorder>import '/kit/kit.mjs'; // defines <tui-recorder>
const rec = document.querySelector('tui-recorder');
// A reading for each pen, whenever one arrives.
socket.addEventListener('message', (e) => {
const { p95, p50 } = JSON.parse(e.data);
rec.push(p95, p50);
});
// Or a whole history at once: oldest first, one reading every 5 s, ending now.
rec.setData(history.p95, { values2: history.p50, interval: 5 });
rec.addEventListener('alarm', (e) => page(e.detail.level, e.detail.value));
rec.stop(); // the paper halts, the pens lift
rec.start();Needs kit.css and kit.mjs. How to install the kit.
figure named by its printed label. The paper is one role="img" whose name states the data, rewritten at most every two seconds: “p95 latency, last 2 minutes: p95 now 182 ms; lowest 121 ms, highest 342 ms; p50 now 96 ms. Under 300 ms.” A name that changes is not announced, so a live chart never floods a screen reader.One custom element. The paper is a plate-coloured strip in a window cut into the panel; a canvas over it draws the printed grid (square, fine and major lines), the dashed set-points, the ink of each pen, and the times the recorder prints in the margin as each major line passes the pen. The ink is the finish’s own printing colour, read from the page, so the chart is ink on paper in aluminium and light printing on black in graphite, and lit inside glass. Readings are stored with the paper position they were made at; the paper position comes from the clock, so a recorder that was off screen catches up exactly. The paper moves a whole device pixel at a time, on a timer, the way a stepper drive feeds it. The pens are elements: a nib, an arm and a carriage on a steel rail, moved by a critically damped servo, all casting one shadow down and to the right; stopped, they lift and the shadow opens. The tear edge is a gradient: a dark edge, a lit crest, a shadow thrown right.
Give it a scale that fits the reading, set-points where they matter, and let the paper keep time.
5 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.
Line charts drawn as light on glass, or as ink on a panel: gridlines faint, two traces at most, a red line for now.
Dark display glass for plots and live readouts, whatever the finish around it. Everything printed inside it is lit.
A value that changes, on grey-green liquid crystal, with a ghost of the unlit segments behind it: clocks, battery, counters.