Gauge
A meter with bands, a target and honest out-of-range handling. Plain SVG: no chart engine.
Install
It needs no chart engine: the whole install is a few small files of React and SVG.
Plain SVG (no chart engine)
npx shadcn@latest add https://beautifulcharts.dev/r/instrument-gauge.jsonimport { Gauge } from "@/components/beautiful-charts/themes/instrument/gauge";
Example
A complete client module. Paste it into your app after installing the component.
"use client";
import { Gauge } from "@/components/beautiful-charts/themes/instrument/gauge";
// Out-of-range values pin to the end of the arc and keep their true number in the readout.
export function Uptime() {
return (
<Gauge
title="Uptime, last 30 days"
value={99.62}
min={98}
max={100}
target={99.5}
bands={[
{ from: 98, to: 99, tone: "bad", label: "below target" },
{ from: 99, to: 99.5, tone: "warn", label: "at risk" },
{ from: 99.5, to: 100, tone: "good", label: "healthy" },
]}
valueFormatter={(v) => `${v.toFixed(2)}%`}
/>
);
}
Gauge props
Generated from InstrumentGaugeProps in the installed source, so this table and your editor's hints always agree. * marks a required prop.
| Prop | Type | Description |
|---|---|---|
| value* | number | null | The reading. A value outside min–max pins to the end of the scale and keeps its true number. |
| min | number | Start of the scale (default 0). |
| max | number | End of the scale (default 100). |
| bands | GaugeBand[] | Coloured ranges along the scale, e.g. good / warn / bad. |
| target | number | null | A tick across the scale. |
| variant | "semi" | "arc" | "semi" is a half circle; "arc" a 240° arc. |
| valueFormatter | (value: number) => string | Formats the reading and scale labels. |
| motion | MotionPreference | "full" (default), "subtle" or "off". Reduced-motion settings always win. |
| eyebrow | ReactNode | Small label above the title. |
| footer | ReactNode | A line or action at the bottom of the card. |
| title | ReactNode | Card title. A string also names the stat for screen readers. |
| description | ReactNode | A line under the title. |
| unit | ReactNode | A word under the number, e.g. "uptime". |
| loading | boolean | Show the loading state. |
| error | string | null | An error message; shows the error state. |
| density | Density | "comfortable" (default) or "compact". |
| className | string | Classes on the card. |
| palette | "theme" | "shadcn" | "theme" (default) or "shadcn" to use your --chart-N colours. |
Parts and styling hooks
Each part carries a data-slot attribute. Theme rules inside the chart are one attribute selector deep, so a selector such as .my-chart [data-slot="chart-title"] overrides them. These are the slots in the files this chart installs; parts a chart doesn't use are simply absent from its markup.
chartchart-bodychart-descriptionchart-eyebrowchart-footerchart-headerchart-headingchart-legendchart-legend-itemchart-legend-labelchart-legend-swatchchart-legend-valuechart-livechart-mainchart-plotchart-readoutchart-statchart-stat-notechart-stat-valuechart-statechart-state-boxchart-state-messagechart-statschart-tablechart-table-scrollchart-takeawaychart-titlechart-tooltipgaugekpi-emptyodometerodometer-digitodometer-glyphsodometer-reelodometer-signpartial-notereadout-deltareadout-unitreadout-valuesr-onlyProps every chart shares
Header, states, legend, tooltip, formatting, motion, sound and controlled interaction state. They work the same on every Instrument chart and both engines. The guide explains colours, controlled state and accessibility.
Show all 2 shared props
| Prop | Type | Description |
|---|---|---|
| locale | string | BCP 47 locale. Defaults to "en-US" so server and client render the same text. |
| timeZone | string | IANA time zone for dates. Defaults to "UTC" so server and client agree. |