KQ-1614 · DRUM/PLOTTER
Drum Plotter
A chart recorder whose graph paper is wrapped round a drum turning about a vertical axis, drawn as a real cylinder in Canvas 2D so the squares crowd into shade at both rims while the paper carries the inked trace left, away from a pen on a rail. The pen follows each reading on the snap spring's constants scaled by penResponse, so a step is drawn with one small overshoot; a series change lifts it on flick, glides the carriage to the new level while the ink changes to the next in the rack, and drops it on recoil, where a blot spreads into the paper. Hover reads the value under the pointer as the paper passes; the drum is a slider whose arrow keys move the same readout along the trace (Page Up and Down five seconds, Home the oldest ink, End the pen, Escape to hide it), and the legend is a radio group.
Gaugeworks · cold store B
Live, four readings a second
Move over the drum, or use the arrow keys, to read the trace. Page Up and Page Down move five seconds, Home the oldest ink, End the pen.
plotting temp · red ink · 36 px/s
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/drum-plotter
Props
- series
- { id: string; label: string; unit?: string; samples?: number[]; min?: number; max?: number; decimals?: number; ink?: string }[]
- default three cold-store series
- The series the pen can plot; samples play back in a loop when no live reading is given.
- value / defaultValue
- string
- default the first series
- The series being plotted, by id, controlled or initial.
- onValueChange
- (id: string) => void
- default —
- Fires from the legend press or key that picked a series.
- reading
- number
- default —
- Live mode: the pen follows this reading, in the series' units, instead of its samples.
- sampleRate
- number
- default 4
- Samples per second when playing a series' samples.
- paperSpeed
- number
- default 36
- How fast the paper travels across the front of the drum, px per second.
- inkColor
- "red" | "blue" | "green" | "violet" | string
- default "red"
- The first ink in the rack, or any CSS colour; later series take the next inks.
- gridStyle
- "graph" | "ruled" | "dots" | "plain"
- default "graph"
- The paper: fine graph paper, ruled lines, a dot grid or plain.
- penResponse
- number
- default 0.5
- How the pen answers a change, 0 (heavy and slow) to 1 (light and quick); 0.5 rides the snap spring.
- penAt
- number
- default 0.74
- Where the pen sits across the drum's face, 0.55 to 0.9 of its width.
- lineWidth
- number
- default 1.6
- Width of the inked line, px.
- legend
- boolean
- default true
- Show the series legend, with the live value in the active chip.
- scale
- boolean
- default true
- Show the value scale beside the drum.
- paused
- boolean
- default false
- Stop the drum; the readout still works.
- onReadout
- (readout: { series: string; value: number; secondsAgo: number } | null) => void
- default —
- Fires when the hovered or keyboard reading changes, and with null when it hides.
- label
- string
- default "Chart recorder"
- The recorder's accessible name.
- dpr
- number
- default 2
- Highest device pixel ratio the drum is drawn at.
- disabled
- boolean
- default false
- No legend, hover or keys; the drum keeps plotting.
- className
- string
- default —
- Sizes the recorder; it is 224px tall and full width by default.
| Prop | Type | Default | Description |
|---|---|---|---|
| series | { id: string; label: string; unit?: string; samples?: number[]; min?: number; max?: number; decimals?: number; ink?: string }[] | three cold-store series | The series the pen can plot; samples play back in a loop when no live reading is given. |
| value / defaultValue | string | the first series | The series being plotted, by id, controlled or initial. |
| onValueChange | (id: string) => void | — | Fires from the legend press or key that picked a series. |
| reading | number | — | Live mode: the pen follows this reading, in the series' units, instead of its samples. |
| sampleRate | number | 4 | Samples per second when playing a series' samples. |
| paperSpeed | number | 36 | How fast the paper travels across the front of the drum, px per second. |
| inkColor | "red" | "blue" | "green" | "violet" | string | "red" | The first ink in the rack, or any CSS colour; later series take the next inks. |
| gridStyle | "graph" | "ruled" | "dots" | "plain" | "graph" | The paper: fine graph paper, ruled lines, a dot grid or plain. |
| penResponse | number | 0.5 | How the pen answers a change, 0 (heavy and slow) to 1 (light and quick); 0.5 rides the snap spring. |
| penAt | number | 0.74 | Where the pen sits across the drum's face, 0.55 to 0.9 of its width. |
| lineWidth | number | 1.6 | Width of the inked line, px. |
| legend | boolean | true | Show the series legend, with the live value in the active chip. |
| scale | boolean | true | Show the value scale beside the drum. |
| paused | boolean | false | Stop the drum; the readout still works. |
| onReadout | (readout: { series: string; value: number; secondsAgo: number } | null) => void | — | Fires when the hovered or keyboard reading changes, and with null when it hides. |
| label | string | "Chart recorder" | The recorder's accessible name. |
| dpr | number | 2 | Highest device pixel ratio the drum is drawn at. |
| disabled | boolean | false | No legend, hover or keys; the drum keeps plotting. |
| className | string | — | Sizes the recorder; it is 224px tall and full width by default. |