Zopra/Charts
Guide
Getting startedAll chartsWhich chart to use?Domain specific
Base charts7
XY ChartTrendCandlestickHeatmapState TimelineFlame GraphBar Gauge
Derived charts73
Time SeriesHistogramStatus HistoryStatGaugeHoneyCombTracesNode GraphHeikin-AshiRenkoKagiPoint & FigureParetoIshikawaControl ChartBland-AltmanLollipopDumbbellSlopeBumpBack-to-BackWaterfallBulletFunnelMekkoForestBarcodeBeeswarmRidgelineHorizonSpectrogramAttention MapWaffleVennUpSetWarped WaffleWord CloudGanttSankeySankey MatrixTreemap ForceChord DiagramCircosArc DiagramAlluvialSankey FunnelDendrogramIcicleSunburstSpiderNightingale RoseParallel CoordinatesOscilloscopeEfficient FrontierPhase PortraitPoincaré MapBifurcationH-R DiagramRamachandranHarkerRoot LocusRadiation PatternQuiverHodographSmith ChartEye DiagramSequence LogoTernaryTernary ContourPiperStüveTephigramChoropleth

Charts/Core charts

Gauge

<Gauge /> · 13 examples

A value on a dial, between a minimum and a maximum, with the limits marked on the rim.

Overview

The gauge is the oldest chart in the building that still works. Long before dashboards, a needle on a dial told you the boiler pressure, and the part that mattered was not the number. It was the red zone painted near the end. You did not need to read anything to know you were close to a bad afternoon.

That is the idea the gauge chart keeps: a value is not just a quantity, it is a position in a range, and some parts of the range are worse than others. Grafana's Gauge panel, which this chart ports, replaced the needle with a bar that fills along an arc and puts a thin ring of threshold colours on the outside. You see how full it is, and how far to the next colour.

It also has the faults of its ancestors. A dial spends a lot of ink on one number, which is why dashboards that are all gauges look like the cockpit of an aircraft designed by a committee. Used once or twice, where the range is real, it is excellent. Used twenty times, it is wallpaper.

Props

API

<Gauge> shows a value as a bar along an arc or a ring, between a minimum and a maximum, with threshold markers, labels and a sparkline. It is a port of Grafana 12's Gauge panel; see Coming from Grafana.

use zopra_charts::*;
  • <Gauge>
  • Shape and bar
  • Thresholds and colour
  • Effects
  • Text and sparkline
  • Several gauges
  • Enums and types
  • Coming from Grafana

Not sure which option fits? See the guide.


<Gauge>

<Gauge data={samples} value={|s: &Sample| s.cpu} x={|s: &Sample| s.time} format={percent} />
PropTypeDefault
dataVec<T>, Signal<Vec<T>>, Frame<N>, Signal<Frame<N>>, or your own Datasetrequired
value, name, reduce, fields, x, x_fieldas on <Stat>the last value of every field
shapeGaugeShapeGauge: a 220° arc
bar_shapeBarShapeFlat
bar_width_factorf32: bar thickness relative to the radius0.5
segment_countusize: split the bar into this many segments1
segment_spacingf32, 0.0–1.0: the gap between segments0.3
effectsGaugeEffectsnone
endpoint_markerEndpointMarkerPoint
show_threshold_markersbool: a thin ring of threshold colourstrue
show_threshold_labelsbool: threshold values around the arcfalse
neutralf64: the value the bar grows frommin
sizingSizing: Auto or Manual { min_width, min_height, .. }Auto
sparklinebooltrue
text_modeTextModeAuto
orientationBarOrientationAuto
title_size, value_sizePixelsfitted to the gauge
min, maxf640. and 100.
thresholdsThresholdsyour theme's good colour, then its bad colour from 80
colorGaugeColorThresholds
mappings&'static ValueMappingsnone
formatFn(f64) -> SharedStringnone
decimalsusizeup to 3, trailing zeros dropped
class, key

Shape and bar

  • GaugeShape::Gauge draws a 220° arc open at the bottom; Circle a full ring starting at the top. Both start from min and run clockwise.
  • The bar fills the arc from min to the value; the rest is a grey track. With neutral, the bar runs from the neutral value to the value in either direction, for balances, deltas and temperatures around zero.
  • bar_width_factor sets the thickness: the bar is bar_width_factor × radius ÷ 3 wide.
  • BarShape::Rounded gives the bar round ends. The Point endpoint marker, a small dot at each end, only shows on rounded bars.
  • segment_count above 1 splits the arc into separate segments. Each lit segment takes the colour its own value would have, so thresholds show as bands. Segments are never drawn thinner than 3 px; the count is reduced to fit.

Thresholds and colour

  • The bar's colour comes from a matching mapping, otherwise from color, as in Bar Gauge.
  • show_threshold_markers draws a thin ring outside the bar in each threshold step's colour, so you can see how close the value is to the next step. It is hidden when min equals max.
  • show_threshold_labels writes min, each threshold and max around the arc, formatted with format / decimals. Percentage thresholds are written as percentages. With neutral, its value is labelled too.

Effects

GaugeEffects switches on Grafana's three visual effects:

effects={GaugeEffects::new().gradient().bar_glow()}
effects={GaugeEffects::all()}
EffectLook
gradientthe bar is shaded along the arc: through the threshold colours, along the scheme, or from a darker to a lighter tone of the value's colour
bar_glowa soft halo around the bar
center_glowa faint radial glow of the value's colour inside the gauge

EndpointMarker::Glow adds a bright spot at the end of the bar, in dark themes.

Text and sparkline

  • The value is centred in the gauge and sized to fit. text_mode Auto adds the name when there are several gauges or a name accessor; Name, Value, ValueAndName and None choose directly. value_size and title_size fix the sizes.
  • With sparkline and several rows, a small chart of the history sits under the value, in the value's colour.

Several gauges

Every value gets its own gauge. BarOrientation::Auto packs them into the grid that keeps them closest to square; Horizontal stacks them as rows; Vertical places them side by side. Sizing::Manual { min_width, min_height, .. } stops them from shrinking below that size. With several gauges, all values use the size of the longest text, so they line up.

Enums and types

TypeValues
GaugeShapeGauge (default), Circle
BarShapeFlat (default), Rounded
EndpointMarkerPoint (default), Glow, None
GaugeEffects{ bar_glow, center_glow, gradient }, built with new(), all(), .bar_glow(), .center_glow(), .gradient()

Coming from Grafana

Grafana optionHere
Calculation, Fields, Show, Limitreduce, fields
Style: shape, bar shape, bar widthshape, bar_shape, bar_width_factor
Segments, Segment spacingsegment_count, segment_spacing
Effects: gradient, bar glow, center gloweffects
Endpoint markerendpoint_marker
Show threshold markers, Show threshold labelsshow_threshold_markers, show_threshold_labels
Neutralneutral
Gauge size, Min width, Min heightsizing
Sparkline, Text mode, Orientationsparkline, text_mode, orientation
Text sizetitle_size, value_size
Min, Max, Thresholds, Color scheme, Value mappingsmin, max, thresholds, color, mappings
Unit, Decimalsformat, decimals

Not available here: units from Grafana's unit registry and data links. Threshold labels are written horizontally rather than along the arc.

Run them

13 examples

Press Run to load an example into the live render at the top of the page. Open one to read its code.

How to read it

  1. 01Start with the number in the middle: the gauge writes it large and fits it to the dial.
  2. 02Look at the bar's colour and how far it runs. Its end position against the arc tells you the share of the range used.
  3. 03Check the thin ring outside the bar. It shows each threshold step in its own colour, so you can see how much room is left before the next one.
  4. 04If threshold labels are on, they give the limits as numbers. The small sparkline below the value, when present, shows where the value has been.

When to use it, and when not to

Reach for it when

  • The value has a real, known range with named limits: a temperature against its rating, disk usage against capacity, battery from 0 to 100.
  • You want a status that reads at a distance. The ring of threshold colours tells people how close the next step is without a single label.
  • Values can be on either side of a reference, such as a balance or a deviation. Set neutral and the bar grows from there.
  • You have a handful of these, a few per panel, each representing a different resource.

Skip it when

  • The range is made up. A gauge from 0 to 1000 for a metric that sits between 3 and 7 is a very large dial with a very small needle.
  • The history matters more than the current value. The built-in sparkline helps, but Time Series is the chart for trends.
  • You have dozens of values to rank. Arcs are hard to compare precisely. Use Bar Gauge, where lengths line up on a common baseline.
  • You only need the number. A Stat tile takes less room and shows it bigger.

The math behind it

From value to angle

Given a value vvv and a range [a,b][a, b][a,b] (min and max, default 0 and 100), the fraction of the arc to fill is the clamped position of vvv in the range. The default shape is not a full circle: the arc starts at 250 degrees and sweeps 220 degrees clockwise, leaving a gap at the bottom. GaugeShape::Circle sweeps the full 360.

Here θ\thetaθ is the total sweep (220 or 360). The filled part is an arc of length fθf\thetafθ starting at the start of the track.

f=clamp⁡ ⁣(v−ab−a, 0, 1),filled angle=f θf = \operatorname{clamp}\!\left(\frac{v - a}{b - a},\,0,\,1\right), \qquad \text{filled angle} = f\,\thetaf=clamp(b−av−a​,0,1),filled angle=fθ

Neutral point

With a neutral value nnn the bar does not grow from the start of the arc but from nnn. Let fnf_nfn​ be the fraction of nnn computed the same way. The bar then covers the angles between the two fractions, in whichever direction the value lies.

This is what makes the gauge usable for balances, temperature differences and anything that can be above or below a reference.

start=min⁡(f,fn) θ,length=∣f−fn∣ θ\text{start} = \min(f, f_n)\,\theta, \qquad \text{length} = |f - f_n|\,\thetastart=min(f,fn​)θ,length=∣f−fn​∣θ

Geometry and segments

The radius is whatever fits: the largest circle that fits the width, or, for the open arc, the height measured from the top to the lowest point of the arc. The bar is w=bar_width_factor×r/3w = \text{bar\_width\_factor} \times r/3w=bar_width_factor×r/3 wide (never under 2 px), so the default factor of 0.5 gives a bar about a sixth of the radius thick. Threshold labels, markers and glows take room from the inside before the final radius is fixed.

With segment_count =m= m=m, the arc is cut into mmm pieces. A segment is never drawn under 3 px plus its gap, so the count is reduced if the arc is too short to hold them. Each lit segment is coloured by the value its own position stands for, so thresholds show up as bands in the bar.

The colour of the whole bar comes from a matching value mapping first, otherwise from color, which by default is the threshold step the value has reached.

Real life usage

A tank, a dial, a Sunday

Tobias looked after the cooling system of a small brewery, which in practice meant a laptop, a pager and four fermentation tanks that each held a month of somebody's work and had no sense of humour. His old monitoring page was a table of numbers. It was accurate and nobody read it.

The yeast cares about one thing above all others: temperature. Between 18 and 21 degrees the beer is happy. Above 24 it develops opinions, and below 14 it goes to sleep. Tobias needed the brewers, none of whom wanted to read a table, to see on a glance whether each tank was inside its band.

A line chart was no use for that. It would show the history but make you work out whether the latest point was good. What the brewers needed was a dial for each tank, with the good zone drawn on it, and a clear signal when the needle drifted toward the end.

He wired the sensor feed into a small desktop app built on zopra, and put one <Gauge> over a frame with a field per tank. He set min to 10 and max to 30, thresholds at 14, 18, 21 and 24, and turned on show_threshold_labels so the numbers were printed on the rim. A fifth tank, which was only ever a cold store, got neutral set at its target so its bar grew in both directions around it.

On the first Sunday after it went up, tank three crept past 22 while Tobias was out. Nobody had to read anything. A brewer walking past saw a bar nudging into the amber band and a ring that was nearly red, and turned the chiller up. The tank peaked at 23.4.

Over that season the brewery lost no batches to temperature, against two the year before, one of which had been given a name by the staff. The table of numbers is still there, in a tab nobody opens.

Tobias says the best review he got was a brewer asking whether the gauges could be made bigger, which in monitoring is the equivalent of applause.

Pitfalls

  • Range is part of the message. The same reading looks fine on 0 to 1000 and alarming on 0 to 10. Set min and max to real limits, not to whatever makes the bar look good.
  • Thresholds in the wrong order. The colour is the step the value has reached, so bad-at-the-low-end metrics (battery, free space) need their steps reversed with the bad colour first.
  • Clamping. A value above max fills the arc completely and no further. The printed number is still the true one, but the bar cannot tell you how far over you are.
  • Too many segments. Past about 20, segments get thinner than the 3 px floor and the chart silently shows fewer of them than you asked for.
  • Glows on busy pages. bar_glow and center_glow look good on a dark wall display and noisy in a grid of twelve.

From around the web

Watch and read

YouTubeBeginners guide - Visualizing Gauges | GrafanaGrafanaOfficial Grafana walkthrough of the gauge panel and thresholds.

Keep going

Related charts

StatWhen you only need the number, large, with a sparkline.Bar GaugeWhen you want several values compared on one scale with exact lengths.BulletWhen you need a target marker and qualitative bands in a compact strip.
PreviousStatNextHoneyComb

On this page

  • Live
  • Overview
  • API
  • Examples
  • How to read it
  • When to use it
  • The math
  • Story
  • Pitfalls
  • Watch and read
  • Related