Annotations
Thresholds, target zones, markers, and callouts are written as children and drawn in the host chart's own coordinate space.
Annotations give the reader something to compare the data against: a limit, a normal range, the moment a deploy landed.
They're plain children (<Threshold>, <TargetZone>, <Marker>, <Callout>) that the host chart draws in its own
coordinate space, so the same child lands identically on any chart that accepts it. Reference ink stays quieter than
data ink: hairlines stroke at 0.7 opacity, labels take the muted --mc-neutral label ink, and a target band uses the
same faint --mc-band fill the charts do.
Install
The annotation layer is its own ~1.5 kB entry. The mark renderers ship with this import, so a host that renders no annotations pays only a small children walker.
import { Threshold, TargetZone, Marker, Callout } from "@microcharts/react/annotations";The vocabulary
<Threshold y={65} label="SLA" />— a dashed reference hairline at a data-spacey.<TargetZone y={[40, 60]} />— a normal-range band, always drawn beneath the data ink. It takes alabeltoo.<Marker x={8} label="deploy" />— a vertical moment mark;xaddresses the host's primary axis (the data index on index-based charts like Sparkline and SparkBar).<Marker x={8} celebrate />— six deterministic particles burst once on entrance, for milestone crossings only; under reduced motion they render as a static starburst.<Callout x={5} y={45} label="dip" />— a labeled point on an elbow hairline.labelis required;yis optional and defaults to the frame's mid-height.
label is optional on the other three, and all four take a color to override the reference ink on that one mark. A
fragment works as a container (<><Threshold … /><Marker … /></>); the host's walker unwraps it.
The same child, any host
Annotation children carry no chart-specific geometry; they resolve against the host's scale. Move the exact
<TargetZone> and <Threshold> from a line onto bars and they land in the same data-space, unchanged.
Every value-series host
Every value-series chart hosts annotations: the charts with a continuous value axis and an index / slot / time
x-axis, where a data-space x and y map cleanly onto the frame. That's Sparkline, SparkBar, MiniBar, CyclePlot,
CitySkyline, ChangePoint, DualSparkline, SpreadBand, ForecastCone, ControlStrip, QueueDepth, BurnChart, Waterfall,
PercentileTrace, RetentionCurve, WinProbWorm, ErrorBudget, NetFlow, Horizon, EnsembleGhosts, PairedBars (vertical), and
Slope. The same <Threshold> or <Marker> lands in each chart's own data-space, unchanged. (MiniBar and PairedBars
host in their default vertical orientation, where value lives on the y-axis; a horizontal layout flips the axes, so
annotation children pass through.)
Charts without a single continuous value axis don't host them: there's no shared y for a <Threshold> to land on.
| Why it can't host | Examples |
|---|---|
| Scalar readout — no axis | Delta, FatDigits, StatusDot, Thermometer |
| Part-to-whole — y is a share | MicroDonut, SegmentedBar, Funnel |
| Value encoded as color | HeatStrip, ActivityGrid, the calendars |
| Value against value | QuadrantDot, MicroScatter, BiasStrip |
| Pure timeline — no value axis | the event/phase timelines |
Most still accept children as a plain pass-through, so an annotation placed inside one renders nothing and warns in dev. A few take no children at all, Delta among them, and passing one is a type error.
Rendering rules
- A coordinate outside the host's domain clamps to the edge at 0.4 opacity, so it reads as off-scale instead of being dropped.
- Annotations never change the auto summary, which describes the data alone. To describe an annotation on a static
chart, pass an explicit
summarystring. celebrateparticles are seeded from the marker'sxand the host's size, neverMath.random, so server and client render the same burst.- A
labelyou supply is the one text the containment rule can't pre-reserve a gutter for, so two mechanisms keep it inside the chart.Threshold,TargetZoneandCallouttruncate: a label longer than its available run is cut and given a trailing….Markerflips its anchor instead, drawing a label near the right edge leftward from the mark, so a moment mark never loses characters. - Reference hairlines draw at a fixed 1-unit weight, exempt from
--mc-density, so tightening the density never thickens the context ink along with the data. TheCalloutelbow is the exception, drawn a shade lighter at 0.75, because it's a leader line pointing at data rather than a reference the reader measures against.
Composition
How to place a chart in a sentence, a table cell, a KPI card, or a tab, and how SparkGroup puts a row of charts on one shared scale.
Theming
How to theme microcharts by setting a --mc-* custom property at any scope, applying a named preset, or deriving a whole palette from one accent with defineTheme().