Gauge A gauge spends a lot of space on one number and is usually the wrong choice. It earns its place only where there is a fixed, known range and a person reading it at a distance. Tokens this needs: --foreground, --card, --muted, --muted-foreground, --border, --chart-1, --status-nominal, --status-warn, --status-critical The status, chart, scale, state and direction names are an extension, not a rename. shadcn has --destructive and five --chart-* and nothing else in this territory. ──────────────────────────────────────────────────────────────────────── // Gauge.tsx ──────────────────────────────────────────────────────────────────────── type Props = { value: number; /** The real limit of the quantity, never a number someone picked. A gauge * of "requests per second" has invented its own maximum and is lying * about the scale, which is why there is no default. */ max: number; min?: number; label: string; /** How the value prints. The number is always printed: an arc is a reading * at a distance, and someone close up needs the figure. */ format?: (v: number) => string; /** The same thresholds the page's other panels use, in the value's units. * Without them the arc is one neutral colour. */ thresholds?: { warn: number; critical: number }; width?: number; }; const R = 54; const CX = 80; const CY = 74; /** A point on the half circle, `frac` of the way from the left end to the right. */ const point = (frac: number) => { const a = Math.PI * (1 - frac); return `${(CX + R * Math.cos(a)).toFixed(1)} ${(CY - R * Math.sin(a)).toFixed(1)}`; }; /** A half circle, clockwise from the left end. Position within a bounded * range is the one thing this shape encodes, and the only thing it does. */ export function Gauge({ value, max, min = 0, label, format = (v) => `${v}%`, thresholds, width = 160 }: Props) { const frac = Math.min(0.9999, Math.max(0, (value - min) / (max - min))); const status = !thresholds ? "none" : value >= thresholds.critical ? "critical" : value >= thresholds.warn ? "warn" : "nominal"; const stroke = { none: "stroke-chart-1", nominal: "stroke-status-nominal", warn: "stroke-status-warn", critical: "stroke-status-critical", }[status]; return (
); } ──────────────────────────────────────────────────────────────────────── // demo.tsx ──────────────────────────────────────────────────────────────────────── import { Gauge } from "./Gauge"; /** * Disk used is the case a gauge survives: the range is a real limit and * everyone reading it knows what full means. */ export default function Demo() { return (
); }