TapeGauge
TapeGauge reads a live value against zones on a scrolling tape, with chevrons for the rate of change.
- encodes
- position on a moving scale = level; chevron count = rate (a separate channel)
- precision
- high
- nodes
- 1 pointer + 1 tick path + ≤4 zone rects
Airspeed is 142 and climbing, and the reading you need is the current one. TapeGauge parks the value at a fixed center pointer and scrolls the scale past it, so the current reading is always in the same place. It is the aviation primary-flight-display tape at word size, and it suits any single live reading: airspeed, throughput, temperature, queue depth. Semantic zones mark the safe, caution, and danger bands. A stack of chevrons encodes the rate of change on a channel separate from the level, so a fast climb and a high value never read as the same thing. The visible span stays fixed while the value updates, so a jump renders as motion of the scale rather than a silent rescale.
Install
import { TapeGauge } from "@microcharts/react/tape-gauge";// zones — real values under “Sample data” below<TapeGauge value={142} rate={1} zones={zones} span={60} title="Airspeed" />Sample data
const zones = [ { from: 100, to: 130, tone: "pos" }, { from: 130, to: 150, tone: "warn" }, { from: 150, to: 200, tone: "neg" },];Try it
When to use it
Use it for a live changing reading with a safe/caution band, where you need the value and its trend together. A history you want to scan belongs in Sparkline, and a single static number in Delta.
Sizing
Variants
format also takes Intl.NumberFormatOptions. With a locale, both the in-gauge readout and the accessible summary
follow that locale's own grouping ("14.200" in German, not "14,200").
Edge cases
A non-finite value renders an empty gauge: no pointer, no readout. zones are optional, and without them the gauge
still tracks level and rate.
Four homes
Accessibility
The accessible name states the level, the trend word, and the containing zone: "Now 142, rising; in the 130–150 zone." The interactive entry re-announces the reading through a polite live region, throttled so a rapidly changing value never floods a screen reader, and focus reads the full summary on demand.
This chart is a single unit, so there is nothing to rove between: a click, tap, Enter or Space selects it
and fires onSelect, and no selection stays pinned. That is the scalar half of the shared
interaction contract.
Hover or focus also reveals the reading itself in a floating chip, for the sizes and label modes where the mark
does not print it; readout={false} drops the chip and keeps everything else.
Props
| Prop | Type | Notes |
|---|---|---|
| value* | number | The current level; parked at the pointer. |
| rate | number | Signed units/tick; drives the chevrons. |
| zones | { from, to, tone }[] | Semantic bands on the scale. |
| span | number | Visible scale extent; fixed while live. |
| rateTiers | [number, number] | Thresholds for 1 and 2 chevrons (default [span/60, span/15]). |
| orientation | "vertical" | "horizontal" | Tape direction (default vertical). |
| announceEvery | number | interactiveMinimum ms between live-region announcements as the value streams (default 5000). |
| animate | boolean | interactiveOpt-in entrance motion when the chart mounts client-side — add import "@microcharts/react/motion" once. Inert on the server, on hydrated server HTML, and under prefers-reduced-motion. |
Plus the shared grammar — data, domain, color, title, summary, format — and the layout props (width, height, className, style) that every chart accepts. Interactive entries also share animate and live, and — wherever a chart has more than one navigable unit — onActive, onSelect, selectedIndex and defaultSelectedIndex; and — wherever the chart shows a hover value — readout. See the shared grammar.