Gauge
A radial dial for a single value — with threshold zones, an optional needle, ticks, and a target.
@garn/ui/gaugeOn this page
Default
A full-ring dial with a centre readout.
Thresholds
Threshold zones auto-colour the arc + reading; a target tick.
Needle
A half-circle speedometer with ticks + scale.
Sizes
sm / md / lg, with a delta.
Installation
garn is copy-in — the garn CLI writes this component's source into your project, so you own and can edit it. It resolves any base files and installs the npm dependencies below for you.
npx garn-ui add gauge- Registry
gauge- Deps
d3-shaped3-scale- Registry deps
utils
Import
import { Gauge } from "@garn/ui/gauge";Props
The component's public props and their types.
color- Description
- Single-tone fallback when there are no `thresholds`. Token reference.
- Type
string- Default
"var(--garn-chart-1)"
delta- Description
- Optional trend readout under the value (e.g. a delta).
- Type
React.ReactNode
endAngle- Description
- Arc end in degrees, clockwise from 12 o'clock.
- Type
number- Default
135
label- Description
- Caption under the value (e.g. the metric name).
- Type
React.ReactNode
max- Description
- High end of the scale.
- Type
number- Default
100
min- Description
- Low end of the scale.
- Type
number- Default
0
numberFormat- Description
- `Intl.NumberFormat` options for the value and scale labels.
- Type
Intl.NumberFormatOptions
showScale- Description
- Show min / max end labels on the scale.
- Type
boolean- Default
false
showValue- Description
- Show the centre value readout.
- Type
boolean- Default
true
size- Description
- Dial size.
- Type
"lg" | "md" | "sm"- Default
"md"
startAngle- Description
- Arc start in degrees, clockwise from 12 o'clock (default sweep is a 270° dial).
- Type
number- Default
-135
target- Description
- A reference marker on the arc; folded into the accessible reading.
- Type
number | { value: number; label?: string; }
thresholds- Description
- Colour zones — auto-colour the arc + reading, and draw the track bands.
- Type
GaugeThreshold[]
ticks- Description
- Number of tick intervals around the arc (0 = none).
- Type
number- Default
0
valueRequired- Description
- The current reading; clamped into `[min, max]` for the arc and the announced value.
- Type
number
valueLabel- Description
- Overrides the centre readout — use when the number needs custom formatting or a unit.
- Type
React.ReactNode
variant- Description
- Filled progress arc, or a speedometer needle over the zones.
- Type
"arc" | "needle"- Default
"arc"
Plus 279 inherited native <div> attributes.
Styling
Target these data-slots and states, and remap these tokens, to restyle without forking the component.
[data-slot="gauge"]When to use
Show a single value on a dial against thresholds/target — capacity, score, throughput, health.
Reach for something else when
- Comparing many KPIs or fitting a dense table (use Bullet)
- simple linear progress (use Progress)
- a trend (use Sparkline).
Overview
Gauge is the KPI dial: a single value on a radial scale, read against optional threshold zones (calm → warning → critical) that colour the arc and the accessible reading. It shows as a filled arc or a speedometer needle, with optional ticks, a scale, and a target marker. It's pure d3-shape SVG — no charting engine — and a meter for assistive tech, so the value is announced.
Guidelines
Use it for one prominent value. A gauge earns its space as a single, glanceable dial; to compare many KPIs or fit a table, a Bullet is denser. For simple linear progress, Progress is lighter.
Let zones do the colouring. Pass thresholds and the arc auto-colours by the active zone and folds the zone label into the reading — don't hand-set color per value. Zones double-encode as bands so the state reads without relying on hue.
Announce the value. It's a meter: give it an aria-label; the value, active zone, and target are folded into aria-valuetext.
Best practices
- Pass
thresholdsfor auto-zone colouring; give it anaria-label. - Use
variant="needle"for a speedometer; settargetfor a reference.
- Don't hand-colour per value when zones express the meaning.
- Don't line up many gauges where bullets would compare better.
Troubleshooting
aria-valuenow sits outside [min,max].
Cause. The value exceeds the bounds.
Fix. It's clamped for aria; the readout can still show the raw value via valueLabel.
Needle reads oddly on a full ring.
Cause. Needle suits ≤270° sweeps.
Fix. Use the default arc for full rings; needle for half/three-quarter dials.
Accessibility
- Role
meter
- role=meter with aria-valuenow (clamped into [min,max]) / aria-valuemin / aria-valuemax; pass an `aria-label`.
- aria-valuetext folds in the value, the active zone label, and the target (e.g. "94%, Critical, target 80").
- The centre readout + SVG are decorative; zone colour is paired with the zone label so meaning isn't colour-only.