Constellation
Constellation places a handful of rare events by time and value, sized by magnitude and joined in time order.
- encodes
- position (x = time, y = value) + area-true dot size
- precision
- medium
- nodes
- n+1
Four incidents, the largest of them in September. Constellation places each event as a dot by time (x) and value (y),
with an optional magnitude driving its size by area (r ∝ √m), because area is how the eye reads magnitude. A hairline
connects the events in time order, so a handful of incidents shows its sequence. It is built for rare events, a dozen
or fewer; dense streams belong to Seismogram or EventTimeline.
Install
import { Constellation } from "@microcharts/react/constellation";<Constellation data={[ { x: 0, y: 40, m: 2 }, { x: 2, y: 90, m: 7 }, { x: 5, y: 30, m: 3 }, { x: 8, y: 65, m: 5 }, ]} title="Incidents"/>Try it
When to use it
Use it for sparse incidents or outages on a timeline, milestones carrying a magnitude, or any rare events where the
sequence is the story. For dense event streams reach for Seismogram or EventTimeline; for a continuous trend,
Sparkline. Skip it when you need precise value comparison, since dot area is a low-precision channel.
Sizing
Variants
connect is on by default, since with rare events the order and rhythm are usually the story. Turn it off for a plain
scatter, or set label="max" to print the largest event's value.
Edge cases
Empty data draws no marks at all, just the sized box, with "No data." as the summary. A single event has no line to
draw: one dot, and the summary says "1 event at …" rather than forcing a range. When every point omits y, the vertical
position is deterministic jitter that encodes nothing — it spreads the dots so they do not stack. In that mode the
connector's slope carries no meaning (it still runs in time order), and neither the summary nor the interactive readout
mentions vertical position. The x position is never jittered, so simultaneous events sit at the same x.
Four homes
Accessibility
The accessible name states the count, the span, and the largest event: "4 events between 0 and 8; largest at 8." The interactive entry lets you arrow through the events chronologically, each announced with its time, value, and magnitude through a polite live region; a hover readout shows the same. Dot area is a low-precision channel, so magnitude is always carried by a number as well, never by size alone.
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* | { x: number; y?: number; m?: number }[] | Events: x = time, y = value, m = magnitude (area-true size). |
| connect | boolean | The faint chronology line (default true). |
| label | "max" | "none" | Numeral at the largest event. |
| xFormat | (x: number) => string | Formats time for the summary (e.g. a month name). |
| xDomain | [number, number] | Time (x) extent (default: data extent). |
| rBase | number | Base dot radius in viewBox units (default 1.6). |
| fontSize | number | Type size of the peak label, in viewBox units. Defaults from `height`. |
| 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.