CometTrail
CometTrail marks the current value with a bright head dot and fades the recent positions behind it by age.
- encodes
- head position (now) + opacity-fading positional trail
- precision
- medium
- nodes
- trail + 2
CometTrail plots the current value as a bright head dot, with recent points trailing behind it and fading with age. In the interactive entry the head eases to each new value and the old head steps down into the trail, so a live stream draws a comet and a stall goes still. Opacity encodes age only; the y position carries the value. The trail is recency context, not data you have to decode.
Install
import { CometTrail } from "@microcharts/react/comet-trail";// rollingWindow — real values under “Sample data” below<CometTrail data={rollingWindow} title="Latency" />Sample data
const rollingWindow = [40, 45, 50, 55, 60, 65, 70, 72, 75, 78, 80, 84, 87];Try it
Motion, and reduced motion
Motion happens only on a data change; there is no idle loop. When a new value arrives the head eases (~200 ms, the
library's canonical strong ease-out) from its old position to the new one, and the previous head steps down into the
trail. A continuous stream produces the comet; a stalled stream goes still, which is itself the signal. The head never
simulates phantom positions between updates: it eases to each real value. Under prefers-reduced-motion the head
repositions instantly, since the static encoding is already complete. The same holds off-screen — one shared viewport
check means the ease only runs while the chart is in view.
When to use it
Use it for a live price or metric with a little recency context, a realtime KPI that should show momentum, or per-stream
"where is it now" in a table. For the full history or an exact multi-point comparison reach for Sparkline (or
DotPlot); for discrete events, HeartbeatBlip.
Sizing
width and height are viewBox units that also set the rendered pixel box — they default to 60 × 16, sized to sit in
a table cell or beside a line of text. Omit them and drive the width from CSS to fill a column; the viewBox keeps the
aspect ratio. trail controls how many recent points the tail carries, which is a density decision rather than a size
one. It is capped at 20: past that the trail stops being a trail and becomes a sparkline, which is the better tool for
the full history.
Variants
label="last" is on by default, so the head always prints its number. Changing trail gives you more or less recency
context without changing the head read, because opacity encodes age and nothing else.
Edge cases
Empty data draws just the frame, with "No data." as the summary. A single point has no trail to fade: the head alone,
and "Now 52." A trail larger than the data never backfills or pads. It shows every point there is.
Four homes
Accessibility
The accessible name is the now-value and the recent trend: "Now 62, rising over the last 3 updates." With a single
point it is the value alone, as in the edge case above: "Now 52." Arrow keys step back through the trail ("3 updates
ago: 78.") and return toward now. Motion is gated on prefers-reduced-motion, and no reading depends on decoding the
fade.
The interactive entry follows the shared interaction contract:
arrow keys rove between units on both axes, Home and End jump to the ends, and a click, tap, Enter or
Space selects a unit — pinning its readout so it survives blur, until you select it again or press Escape.
On touch, a tap pins and a drag scrubs.
Props
| Prop | Type | Notes |
|---|---|---|
| data* | number[] | The rolling window, oldest → newest (last = now). |
| trail | number | Points kept visible (default 12, cap 20). |
| label | "last" | "none" | Numeral after the head (default last). |
| fontSize | number | Type size of the numeral after the head, in viewBox units. Defaults from `height`. |
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.