Skip to content

Gauge

A read-only level drawn along an arc - a speedometer, a CPU load, a battery ring. It holds a fraction of the sweep in 0..1, not a value in your own units.

ui.gauge

new UiGauge
{
Key = "cpu",
Level = UiValue.From(() => cpu.Value / 100.0),
Thickness = 0.08,
LevelColor = "#2b6cee",
Fallback = new UiRangeBar { Key = "cpuBar", Start = 0, End = UiValue.From(() => cpu.Value / 100.0), StartColor = "#2b6cee", EndColor = "#2b6cee" },
}

A three-quarter arc open at the bottom, filled in blue to 70 percent over a grey track

The default sweep runs from -135 to 135 degrees: three quarters of a turn, open at the bottom.

new UiGauge { Key = "battery", Level = 0.4, StartAngle = 0, EndAngle = 360, Thickness = 0.1, LevelColor = "#34c759" }

A full ring in grey, filled in green clockwise from twelve o’clock to 40 percent

Angles are degrees clockwise from twelve o’clock. The sweep is EndAngle - StartAngle, so an end before the start runs counterclockwise; its size is clamped to one full turn.

new UiLayer
{
Key = "ring",
Children =
[
new UiGauge { Key = "level", Level = 0.8, StartAngle = 0, EndAngle = 360, Thickness = UiLength.OfParent(0.085, 0.01) },
new UiTextRun { Key = "percent", Text = "80 %", Size = UiLength.OfParent(0.18, 0.03) },
],
}

Thickness is a fraction of the widget, so a ring in a grid cell keeps the stroke of the whole widget. A length relative to the containing box keeps it a fraction of the ring’s own cell; put the rings in a grid with MinCellSize and one tree fits any widget shape. See Sizing.

The unfilled track follows the theme unless you set TrackColor, for a ring on a custom background:

new UiGauge { Key = "battery", Level = 0.85, StartAngle = 0, EndAngle = 360, LevelColor = "#ffffff", TrackColor = "#3a3a3c" }

A reader from before trackColor ignores it and draws the theme’s track.

Property Values Default (absent) Meaning
Level (level) 0..1 0 The filled fraction of the sweep.
StartAngle (startAngle) double, degrees -135 Where the arc begins, clockwise from twelve o’clock.
EndAngle (endAngle) double, degrees 135 Where the arc ends.
LevelColor (levelColor) #rrggbb The reader’s own accent colour The filled arc’s colour.
TrackColor (trackColor) #rrggbb The reader’s tertiary surface colour The unfilled track’s colour.
Thickness (thickness) length Left to the reader The arc’s width.
MainSize (mainSize), Fill (fill) - - Shared with every leaf - see Sizing.

LevelColor and TrackColor are literal colours, not theme roles - see Colours and text. ui.dial has no TrackColor; its track always follows the theme.

None. ui.gauge is never interactive - use ui.dial for the same picture the user can turn.

None. ui.gauge is a leaf. Put a ui.text over it in a layer to show the reading in the middle.

A gauge has no content extent: on its parent’s main axis it takes MainSize or Fill, and without either it is 0 long. The arc is drawn in the largest centred square the box allows. See Sizing.

The geometry is normative; see the UiGauge remarks.

  • The sweep is endAngle - startAngle, signed, with its magnitude clamped to 360.
  • The arc is centred in the box, thickness wide, with a centreline radius of (min(width, height) - thickness) / 2 and fully rounded caps.
  • The track covers the whole sweep in trackColor, or the reader’s tertiary surface colour when that is absent. The filled arc runs from the start over level of the sweep in levelColor or the accent colour; level is clamped to 0..1, and 0 paints no filled arc.
  • A reader that does not know ui.gauge draws the node’s fallback, typically a ui.range-bar at the same level:
{
"type": "ui.gauge",
"properties": { "level": 0.7, "thickness": { "basis": 0.08 }, "levelColor": "#2b6cee" },
"fallback": {
"type": "ui.range-bar",
"properties": { "start": 0, "end": 0.7, "startColor": "#2b6cee", "endColor": "#2b6cee" }
}
}