Bullet
One measured value against a target tick, over qualitative bands, in a single row.
- encodes
- position (measure length vs a target tick)
- precision
- high
- nodes
- ≤ 6
Quota attainment is 72 against a target of 80. Bullet puts the measure, the target tick, and the qualitative bands (poor / okay / good) on one row, for progress, SLAs, budgets, and quotas. The bands sit lowest and graduate in shade by step, because they are context and the measure bar has to read as the loudest mark on the row. The measure is a thin band centered in the track (Few's proportion, not a full-height fill), so the bands stay legible on both sides of it.
Install
import { Bullet } from "@microcharts/react/bullet";<Bullet value={72} target={80} bands={[50, 90]} title="Quota" />Try it
When to use it
Use it for progress to a goal, a value against a target, and KPIs with thresholds. For trends over time use Sparkline; it is not a distribution chart.
Sizing
width and height are viewBox units that also set the rendered pixel box — a bullet reads best wide and short. Omit
them and drive the width from CSS to fill a table cell or card column; the viewBox keeps the aspect ratio.
Variants
Edge cases
Four homes
Accessibility
Bullet announces its value against its target — "72 of 80 target.". No color is required to read whether the target was met: the measure's length and the target tick encode it by position, and the qualitative bands sit behind them. The target is a tick rather than a second bar: a distinct shape at a distinct position, so the comparison survives grayscale print and never depends on two colors staying apart. The interactive entry reads the value and target on hover and focus.
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 measured value. |
| target | number | Target tick to compare against. |
| bands | number[] | Ascending qualitative thresholds. |
| domain | [number, number] | Explicit [0, max]; auto-fit otherwise. |
| label | "none" | "value" | "target" | "both" | Value/target readout in a right gutter (default none). |
| title | string | Accessible name; joins the auto summary. |
| summary | string | false | Override or disable the auto summary. |
| 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.