Skip to content

Gauge

ChartsSince 0.4.0
import { Gauge } from '@absoluteui/components/gauge';
import '@absoluteui/components/gauge/style.css';

Using Angular? See Gauge for Angular.

A radial gauge for one value within a known range, drawn on a 240 deg arc: a track, the value arc, optional qualitative bands (for example poor / fair / good) outside the track, an optional target marker, and the formatted value in the center with the current band’s name under it. The SVG is role="meter" with aria-valuenow, aria-valuemin, aria-valuemax, and a value text that names the band and the target, so the meaning never depends on color. It is a static reading: not focusable, no tooltip. Like Sparkline it does not use the chart frame, so it stays small. No animation.

  • One key value against a known range (utilization, score, completion) on dashboards and cards.
  • When qualitative bands or a target give the value its meaning.
  • Comparing several values: use Bar Chart or Bullet Chart (lengths compare more accurately than angles).
  • Progress of a task: use Progress Bar.
  • Values without a meaningful range.

Gauge with bands, a target, and percent values

Section titled “Gauge with bands, a target, and percent values”
import { Gauge } from '@absoluteui/components/gauge';
const host = document.createElement('div');
document.body.append(host);
const gauge = Gauge.create(host, {
label: 'CPU load',
value: 72,
bands: [
{ to: 50, label: 'Normal', color: 3 },
{ to: 80, label: 'Busy', color: 5 },
{ to: 100, label: 'Critical', color: 2 },
],
target: 60,
valueFormat: { style: 'unit', unit: 'percent' },
});
host.dataset.reading = gauge.valueText;

Custom range and a value updated over time

Section titled “Custom range and a value updated over time”
import { Gauge } from '@absoluteui/components/gauge';
const host = document.querySelector<HTMLElement>('#nps');
if (host) {
const gauge = Gauge.create(host, { label: 'Net promoter score', value: null, min: -100, max: 100, showRange: true, description: 'Last 30 days' });
gauge.update({ value: 38 });
}
import { Gauge } from '@absoluteui/components/gauge';
import '@absoluteui/components/gauge/style.css';
const host = document.querySelector<HTMLElement>('#score');
if (host) {
const gauge = Gauge.create(host, { label: 'Quality score', value: null, bands: [{ to: 40, label: 'Poor' }, { to: 70, label: 'Fair' }, { to: 100, label: 'Good' }] });
gauge.update({ value: 64 });
}
import { Gauge } from '@absoluteui/components/gauge';
const host = document.createElement('div');
document.body.append(host);
Gauge.create(host, {
label: 'CPU',
value: 72,
bands: [{ to: 50, label: 'Low' }, { to: 80, label: 'Busy' }, { to: 100, label: 'Critical' }],
target: 60,
valueFormat: { style: 'unit', unit: 'percent' },
});
<div class="aui-gauge aui-gauge--c2">
<div class="aui-gauge__title" id="T">CPU</div>
<svg class="aui-gauge__svg" role="meter" aria-labelledby="T" aria-valuemin="0" aria-valuemax="100" aria-valuenow="72"
aria-valuetext="72% (0% to 100%), Busy, target 60%" viewBox="0 0 200 150">
<path class="aui-gauge__track" aria-hidden="true"/>
<path class="aui-gauge__band aui-gauge__band--c1" aria-hidden="true"/>...
<path class="aui-gauge__value" aria-hidden="true"/>
<path class="aui-gauge__target" aria-hidden="true"/>
<text class="aui-gauge__reading" aria-hidden="true">72%</text>
<text class="aui-gauge__band-label" aria-hidden="true">Busy</text>
<text class="aui-gauge__range" aria-hidden="true">0%</text> <text class="aui-gauge__range" aria-hidden="true">100%</text>
</svg>
<p class="aui-gauge__description" hidden></p>
</div>
Gauge.create(host: HTMLElement, options: GaugeOptions): Gauge

Global configuration key: gauge (see Configuration).

Option Type Default Description
label string What is measured: visible title and the accessible name of the meter (aria-labelledby). Required.
hideLabel boolean false Visually hide the title; it stays the accessible name.
description string Visible text below the gauge (text only). Not referenced by aria-describedby.
value number | null Current value. null (or a non-finite number) shows an em dash and the value text “No value”; aria-valuenow is removed. Values outside min-max are clamped on the arc and in aria-valuenow; the value text keeps the real value. Required.
min number 0 Range start (finite).
max number 100 Range end (finite, greater than min).
bands readonly GaugeBand[] Qualitative bands { to: number, label: string, color?: 1-8 } in ascending to order; the first band starts at min. Drawn as a thin arc outside the track; the current band’s label is printed under the reading and appended to the value text.
target number Target value marked across the arc; appended to the value text (“target 60%”).
color 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 Palette slot of the value arc. Default: the current band’s color (its color, else its position), else 1.
valueFormat Intl.NumberFormatOptions Number format for the reading, range ends, target, and value text.
formatValue (value: number) => string Custom value text; overrides valueFormat everywhere.
valueText string Replaces the generated aria-valuetext.
showRange boolean true Print the formatted min and max under the ends of the arc. Globally configurable.
locale string "en-US" Number and message locale. Globally configurable. Inherited from common configuration.
direction 'ltr' | 'rtl' "ltr" Accepted for configuration consistency; the gauge is not mirrored (min at the lower left, clockwise to max at the lower right). Globally configurable. Inherited from common configuration.
Property Type Description
host HTMLElement The host element.
element SVGSVGElement The svg role=“meter”.
valueText string The accessible value text (aria-valuetext: generated or valueText).
Method Description
update(options: Partial<GaugeOptions>): void Merge, validate, and re-render.
destroy(): void Remove rendering, host classes, and the configuration subscription.

All rules live in the aui.components cascade layer, so application styles override them without specificity battles.

Class Purpose
aui-gauge Host; inline grid, 12rem wide by default (set inline-size to resize; the SVG scales through its viewBox).
aui-gauge--c1 ... --c8 Value arc palette slot; sets –aui-gauge-color.
aui-gauge__title / __title--hidden / __description Title (accessible name) and description.
aui-gauge__svg The svg role=“meter”.
aui-gauge__track / __value Background arc and value arc (aria-hidden).
aui-gauge__band / __band--c1 ... --c8 Band arcs and their palette slots (aria-hidden).
aui-gauge__target Target marker line (aria-hidden).
aui-gauge__reading / __band-label / __range Center reading, current band name, and range ends (aria-hidden).

Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.

--aui-color-chart-1 | --aui-color-chart-2 | --aui-color-chart-3 | --aui-color-chart-4 | --aui-color-chart-5 | --aui-color-chart-6 | --aui-color-chart-7 | --aui-color-chart-8 | --aui-color-chart-grid | --aui-color-text | --aui-color-text-muted | --aui-font-family-sans | --aui-font-size-md | --aui-font-size-sm | --aui-font-weight-semibold | --aui-line-height-tight | --aui-space-1

type GaugeColor = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
interface GaugeConfig { showRange: boolean }
interface GaugeBand { to: number; label: string; color?: GaugeColor }
interface GaugeOptions extends Partial<GaugeConfig> {
label: string;
hideLabel?: boolean;
description?: string;
value: number | null;
min?: number;
max?: number;
bands?: readonly GaugeBand[];
target?: number;
color?: GaugeColor;
valueFormat?: Intl.NumberFormatOptions;
formatValue?: (value: number) => string;
valueText?: string;
locale?: string;
direction?: 'ltr' | 'rtl';
}

Pattern: Static meter: svg role=“meter” (WAI-ARIA 1.2) named by the title, with aria-valuenow/min/max and an aria-valuetext that names the band and the target.

Key Context Action
None Any Not focusable (a static reading); screen readers reach the meter in browse mode.
Element Role
svg.aui-gauge__svg meter
arcs, target marker, reading, band name, range ends aria-hidden (the value text carries the meaning)
Attribute Element Value
aria-labelledby svg id of the visible (or visually hidden) title
aria-valuemin / aria-valuemax svg min and max (defaults 0 and 100)
aria-valuenow svg The value clamped to min-max; removed when the value is null
aria-valuetext svg Localized “{value} ({min} to {max}), {band}, target {target}”, for example “72% (0% to 100%), Busy, target 60%”; “No value” (plus the target) when the value is null; or valueText

Not focusable.

Criterion Level Note
1.1.1 Non-text Content A
1.3.1 Info and Relationships A
1.4.1 Use of Color A
1.4.3 Contrast (Minimum) AA
1.4.11 Non-text Contrast AA
4.1.2 Name, Role, Value A

Automated test results: Accessibility and compliance.

  • Meaning never depends on color: the value is printed in the center, the current band’s name is printed under it and included in the value text, and the target is named in the value text.
  • The value arc (color-chart-<slot>) meets 3:1 against surfaces; the track (color-chart-grid) only frames it.
  • Forced colors: the value arc uses Highlight, the track GrayText, bands, target, and text CanvasText.
  • No animation.
  • role=“meter” is ARIA 1.2 and support varies across screen readers and browsers.
  • The description is visible text only; it is not referenced by aria-describedby.
  • Manual screen-reader verification is pending.

default, with bands (current band named), with target, no value (null: “-”, “No value”, no aria-valuenow), value out of range (clamped on the arc and in aria-valuenow).

From Trigger To
any update({ value }) re-rendered; new aria-valuenow and value text
value update({ value: null }) no value
any configuration change (showRange, locale) re-rendered
  • Meaning never depends on color: the reading is printed, the band name is printed and in the value text, and the target is named in the value text.
  • Not focusable by design (a static reading, like Progress Bar); put interactive detail elsewhere.
  • The value arc meets 3:1 against surfaces; the track only frames it.
  • Forced colors: value arc Highlight, track GrayText, bands, target, and text CanvasText.
  • role="meter" is ARIA 1.2; support varies. No animation. Manual screen-reader verification is pending.

Scales with its inline size through the viewBox (200 x 150 units); text scales with it.

Not mirrored: min is always at the lower left and the arc runs clockwise to max at the lower right. direction is accepted for configuration consistency. Title and description follow the document direction.

Value arc color-chart-<slot>; bands color-chart-<n>; track color-chart-grid; target and reading color-text; band name and range color-text-muted.

configureAbsoluteUI({ components: { gauge: { showRange: false } } });

Instance options override global and theme defaults. All options are dynamic.

Text uses textContent and attribute values; SVG uses createElementNS; colors are classes. No innerHTML or style attributes.

No persistence, network access, or telemetry.

Budget: Gauge.create < 2 ms per instance in headless Chromium (e2e performance test). No layout reads and no resize observer.

One value per instance; dozens of instances per page.

  • null or non-finite values: “-” in the center, “No value”, no value arc, no band.
  • Values below min or above max: clamped on the arc and in aria-valuenow; the reading and value text keep the real value; the first / last band applies.
  • A value equal to min draws no value arc.
  • Bands need not reach max; values above the last band’s to (but within the range) name no band.
Code Category Cause
GAUGE_OPTIONS configuration Missing label; value not a number or null; non-finite min; max <= min; bands without labels or not in ascending to order above min; invalid colors, target, text options, or formatters.
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION configuration Invalid or unknown configuration.

A failed construction leaves the host untouched.

  • Fixed 240 deg arc; no needle or intermediate ticks.
  • Not interactive; not mirrored in RTL.
  • Manual screen-reader verification is pending.
  • Several values or needles; semicircle, full-circle, or linear variants.
  • Editing the value.