Skip to content
KONIGI Patterns

Dashboards / Charts and data displays / Gauge and dial

‹ 7 of 22 ›

Gauge and dial

People need to see where a value sits within a known range.

Updated September 10, 2026

Problem

People need a quick sense of where a value sits within a familiar, bounded range.

Solution

Show the value as a position on a simple arc, with clear endpoints and a readable number. Use meaningful limits rather than inventing a maximum to fill the dial.

Keep decoration minimal and label any threshold regions. A gauge can fit a familiar physical instrument or a small summary row, but check whether a linear bar would show the same information more compactly.

Add a separate trend when the direction of change matters.

Use when

The range has meaningful bounds and the value’s position within it is the main question.

Don’t use when

You have more than about six, the maximum is invented, or the viewer needs to compare gauges against each other. Comparing angles across a grid is the task human perception is worst at, and it’s the task a grid of gauges sets.

Trade-offs

A gauge takes substantial space for one value and shows no history. Comparing angles is harder than comparing aligned lengths. Repeated dials can crowd out more useful information.

Checklist

  • Is the maximum a real limit or a number someone picked?
  • Would a bullet graph carry the same information in a tenth of the space?
  • How many gauges are on this page, and are viewers comparing them to each other?
  • Does the gauge show a target as well as a value?
  • Where do the threshold colours come from, and are they the same ones the charts use?
  • Is there any history, or only the instantaneous value?
  • Is the number also printed, for people who need precision?
  • Does it stay readable at the size this panel actually renders at?
  • Would a colourblind reader get the same reading from the arc?
  • If this mirrors a physical instrument, does it match the one in the room?

Compare

Grafana ships the gauge as a first-class panel wired into the same threshold system as everything else, which makes it consistent and makes it easy to scatter across a dashboard where a stat panel would serve better. Tableau has no native gauge and the community builds them from stacked pie charts, which is a quiet statement of position from a tool whose analyst audience took Few’s argument seriously. Netdata favours a compact value with a live chart behind it over a radial reading, on the grounds that a per-second trend answers more questions than a position in an arc. Industrial HMI software, working to ISA-101 conventions, keeps the round instrument where it matches plant equipment and strips its decoration to a thin arc, which is the version of this pattern with the strongest justification.

Target and progress provides a compact linear alternative. KPI tile shows the number with context. Threshold line places limits on a time chart.

Semantic status color defines warning regions. Process mimic may use a gauge to match a physical instrument.

Gauge and dial anatomy A gauge and a bullet graph given the same area on the page. The gauge encodes one value along one dimension. The bullet graph, in the same rectangle, encodes the value, the target and three qualitative ranges, and still leaves room for the label. The same area, twice 61% Disk used 0 100 One value, one dimension Disk used Percent 0 50 100 Value, target, three ranges 1 2 1 WHAT THE ARC COSTS A square to encode one value. On a page of twelve panels, space is the scarce resource, and on area alone the gauge loses. 2 WHY FEW BUILT THIS A linear, no-frills display giving a rich reading in a small space. It was designed specifically to replace the gauge. Three cases where the arc still survives that. When the range is genuinely bounded and familiar, so the endpoints mean something. When it is the only radial thing on the page and the contrast is doing the work. And when it mimics an instrument the operator already reads on real plant.
Wireframe — the pattern's anatomy, not any one product's version of it

Implementation

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
--foreground--card--muted--muted-foreground--border--chart-1--status-nominal--status-warn--status-critical

Gauge.tsxA half-circle arc with the number printed. The maximum is a required prop, and the arc takes its colour from the page's thresholds when it is given them.

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 (
    <figure className="m-0 inline-block" role="img" aria-label={`${label} ${format(value)} of ${format(max)}`}>
      <svg viewBox="0 0 160 90" width={width} height={(width * 90) / 160} aria-hidden="true">
        <path d={`M${point(0)} A ${R} ${R} 0 0 1 ${point(1)}`} fill="none" className="stroke-muted" strokeWidth="14" strokeLinecap="round" />
        <path d={`M${point(0)} A ${R} ${R} 0 0 1 ${point(frac)}`} fill="none" className={stroke} strokeWidth="14" strokeLinecap="round" />
        <text x={CX} y="66" textAnchor="middle" className="fill-foreground text-[17px] tabular-nums">{format(value)}</text>
        <text x="18" y="84" textAnchor="end" className="fill-muted-foreground text-[8px] tabular-nums">{min}</text>
        <text x="142" y="84" className="fill-muted-foreground text-[8px] tabular-nums">{max}</text>
        <text x={CX} y="88" textAnchor="middle" className="fill-muted-foreground text-[8px]">{label}</text>
      </svg>
    </figure>
  );
}

demo.tsxHow it is called: disk used, 61 of 100.

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 (
    <div className="flex h-[140px] items-center justify-center rounded-lg border bg-card">
      <Gauge value={61} max={100} label="Disk used" />
    </div>
  );
}
What it renders. Identical markup in both panes, with only the token values changing.

Examples

Screenshots are grouped by product and include the capture date. Dashed boxes highlight this pattern. Notes appear below each screenshot and when you hover over a box.

Ignition

A process-monitoring demo uses simulated plant data and offers simple or realistic equipment rendering.

Water Treatment / Overview September 11, 2026 Ignition Perspective public demo, Water Treatment (signed out) dense · dark · desktop-web
The demo uses simulated plant data in a process diagram arranged from incoming water through treatment and storage. Values appear beside the relevant equipment. Green means running, while stopped filters are gray and explicitly labeled. This makes normal operation colorful, unlike a display that reserves color for warnings. Repeated filter panels and clear process connections help people compare equipment.
Show 3 more examples Hide the rest

Grafana

Examples of panel grids, shared selectors, stat tiles, and chart configuration.

Examples / Gauge September 10, 2026 Grafana Play (signed out; no version string exposed) medium · dark · desktop-web
The showcase includes several gauges with similar disk values. Comparing them requires reading the numbers, while each arc uses substantial space. A compact set of bars would make those values easier to compare. Elsewhere, different values share the same red treatment, making the threshold definition important to understanding the result. The examples also mix color ramps, sparklines, and threshold bands.

Netdata

A large collection of system charts with per-chart controls and anomaly-rate views.

Metrics / System September 10, 2026 Netdata Agent v2.10.0-686-nightly (public registry node, signed out) dense · dark · desktop-web
The navigation reports 720 charts organized by the metrics collected from the system. The main page follows the same nested structure, giving broad coverage but little indication of which charts matter most to a particular task. Search helps navigate that volume. The header also distinguishes live and stale nodes, making missing updates visible instead of presenting every node as current.
Metrics / System › Compute › CPU September 10, 2026 Netdata Agent (public registry node, signed out) dense · dark · desktop-web
This section follows several nested levels of the generated metric hierarchy. Leading dashes indicate depth, while a breadcrumb identifies the current CPU section. Each chart includes its own grouping and aggregation controls. The Anomaly Rate option is visible but switched off, so this capture demonstrates the control rather than the resulting anomaly display.