v1.2.0
  1. ds
  2. Data display
  3. Gauge and ring

Gauge and ring

One value against a range or a target.

One value against a range. A gauge shows where a reading sits between a floor and a ceiling, with the zones that matter marked on the rim. A ring shows a single share, small enough for a table cell.

64%CPU, 5 min
0100%
88%Disk /data
02 TB
412conn of 1,300
01,300
Show code
<div class="gauge" role="meter" aria-valuemin="0" aria-valuemax="100" aria-valuenow="64" aria-label="CPU, 5 min">
  <svg viewBox="0 0 100 56" aria-hidden="true"><path class="zone c-warn" d="M1.5 50A48.5 48.5 0 0 1 98.5 50" pathLength="100" stroke-dasharray="15.00 100" stroke-dashoffset="-70.00"/><path class="zone c-down" d="M1.5 50A48.5 48.5 0 0 1 98.5 50" pathLength="100" stroke-dasharray="15.00 100" stroke-dashoffset="-85.00"/><path class="track" d="M8 50A42 42 0 0 1 92 50" pathLength="100"/><path d="M8 50A42 42 0 0 1 92 50" pathLength="100" stroke-dasharray="64.00 100"/></svg>
  <div class="gauge-c"><b>64%</b><span>CPU, 5 min</span></div>
  <div class="gauge-ends"><span>0</span><span>100%</span></div>
</div>
<div class="gauge c-down" role="meter" aria-valuemin="0" aria-valuemax="100" aria-valuenow="88" aria-label="Disk /data">
  <svg viewBox="0 0 100 56" aria-hidden="true"><path class="zone c-warn" d="M1.5 50A48.5 48.5 0 0 1 98.5 50" pathLength="100" stroke-dasharray="15.00 100" stroke-dashoffset="-70.00"/><path class="zone c-down" d="M1.5 50A48.5 48.5 0 0 1 98.5 50" pathLength="100" stroke-dasharray="15.00 100" stroke-dashoffset="-85.00"/><path class="track" d="M8 50A42 42 0 0 1 92 50" pathLength="100"/><path d="M8 50A42 42 0 0 1 92 50" pathLength="100" stroke-dasharray="88.00 100"/></svg>
  <div class="gauge-c"><b>88%</b><span>Disk /data</span></div>
  <div class="gauge-ends"><span>0</span><span>2 TB</span></div>
</div>
<div class="gauge c-ok" role="meter" aria-valuemin="0" aria-valuemax="100" aria-valuenow="31" aria-label="conn of 1,300">
  <svg viewBox="0 0 100 56" aria-hidden="true"><path class="track" d="M8 50A42 42 0 0 1 92 50" pathLength="100"/><path d="M8 50A42 42 0 0 1 92 50" pathLength="100" stroke-dasharray="31.00 100"/></svg>
  <div class="gauge-c"><b>412</b><span>conn of 1,300</span></div>
  <div class="gauge-ends"><span>0</span><span>1,300</span></div>
</div>

The arc is one path with pathLength="100", so stroke-dasharray="64 100" fills 64%. Zones are a thin arc outside the track, drawn the same way. When the reading crosses into a zone, give the gauge that zone's class so the value takes its colour.

Ring

72 86 99.9%
Code
<span class="ring-w"><span class="ring sm" style="--v:.42"></span></span>
<span class="ring-w"><span class="ring" style="--v:.72"></span><b>72</b></span>
<span class="ring-w"><span class="ring c-warn" style="--v:.86"></span><b>86</b></span>
<span class="ring-w"><span class="ring lg c-ok" style="--v:.999"></span><b>99.9%</b></span>

A conic gradient with a radial mask, so it is one element and scales with --size and --sw. The label sits beside the masked element in a .ring-w wrapper, or it would be masked too.

NodeCPUMemoryPods
ip-10-0-12-41 38% 61%24
ip-10-0-14-7 79% 55%31
ip-10-0-9-200 94% 82%38
Show code
<table class="table compact">
  <thead><tr><th>Node</th><th>CPU</th><th>Memory</th><th class="n">Pods</th></tr></thead>
  <tbody>
    <tr><td>ip-10-0-12-41</td><td><span class="ring-w"><span class="ring sm" style="--v:.38"></span></span> 38%</td><td><span class="ring-w"><span class="ring sm" style="--v:.61"></span></span> 61%</td><td class="n">24</td></tr>
    <tr><td>ip-10-0-14-7</td><td><span class="ring-w"><span class="ring sm c-warn" style="--v:.79"></span></span> 79%</td><td><span class="ring-w"><span class="ring sm" style="--v:.55"></span></span> 55%</td><td class="n">31</td></tr>
    <tr><td>ip-10-0-9-200</td><td><span class="ring-w"><span class="ring sm c-down" style="--v:.94"></span></span> 94%</td><td><span class="ring-w"><span class="ring sm c-warn" style="--v:.82"></span></span> 82%</td><td class="n">38</td></tr>
  </tbody>
</table>
ClassOnWhat it does
.gaugedivThe frame. --size (11rem). Colour from a series or status class.
pathsvgd="M8 50A42 42 0 0 1 92 50" with pathLength="100". .track for the background, .zone for thin rim arcs on a 48.5 radius.
.gauge-c / .gauge-endsdivThe value and label under the arc; the floor and ceiling at each end.
.ringspanA share as a ring. --v from 0 to 1, --size, --sw. Sizes: sm, lg.
.ring-wspanWraps a ring with its label in b, centred.
gauge()src/lib/viz.tsBuilds the SVG from a value, label, ends and zones.
Do
  • Mark the zones where someone should act.
  • Put the unit and the window in the label: "CPU, 5 min".
  • A ring next to its number in tables.
Don't
  • A row of gauges for a dashboard overview: KPI tiles say more in less space.
  • Gauges for values with no meaningful maximum, like request counts.
  • Needles.

Accessibility

  • A gauge is a role="meter" with aria-valuenow, min and max, and the label. Keep the number visible beside a ring.