TermMosaic v1.0.0

v1.0.0 is the first release that makes a stability promise: the public API freezes here and Semantic Versioning applies in earnest — with one documented exception: widgets/widgettest is excluded from that promise, because it must evolve with the framework. Read the limitations before you rely on anything here.

Widgets widgets/viz

Meter

A budget with named zones, a threshold marker and the active zone's name in words.

A budget with named zones, a threshold marker and the active zone’s name in words.

Package widgets/viz. API reference: pkg.go.dev/widgets/viz.

Meter is a bounded value with named zones and a threshold marker.

Rendered output

Meter rendered by cmd/capture through widgettest.Capture: colour at 3 widths (40, 80, 120 columns), and the exact plain-text cell grid at the widest of them.

MinSize() returns 18 × 3 cells. That is the whole widget including its own chrome, and it is the widget's assertion about itself — below it, Draw clips rather than blanks, and what to do about that is the application's decision.

40 columns × 3 rows

╭ disk ────────────────────────────────╮
│used                   + █  |+   78   │
╰──────────────────────────────────────╯

80 columns × 3 rows

╭ disk ────────────────────────────────────────────────────────────────────────╮
│used                                           +         █    |  +       78   │
╰──────────────────────────────────────────────────────────────────────────────╯

120 columns × 3 rows

╭ disk ────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│used                                                                   +                █       |    +           78   │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Plain text — the exact cell grid, trimmed per line. This is the honest form: Braille and block-element glyphs can take a different advance width in a web font than a terminal gives them, which breaks the alignment they depend on.

# Meter — A budget with named zones, a threshold marker and the active zone's name in words.
# package: widgets/viz
# constructor: viz.NewMeter(r buffer.Rect) *viz.Meter
# 120 columns x 3 rows, rendered through widgettest.Capture

╭ disk ────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│used                                                                   +                █       |    +           78   │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

What you are looking at. This is the cell grid the renderer produced, in a web page. It is not a screenshot of a terminal, and it cannot show interaction, resize or animation — a capture is one settled frame after N frames of settling. Braille and Block Elements can take a different advance width in your browser's font than in a terminal, so if a gauge or a sparkline above looks wrong, the plain-text form below it is the exact output and the colour one is the decoration. The colour frames are at 40, 80, 120 columns; the plain-text frame is at 120. More on this.

About this capture. Two non-colour signals: the zone boundaries are drawn as ‘+’, the threshold as ‘|’, and the active band is named in text.

Package context

Package viz provides the catalog’s measurement and display widgets: ProgressBar, Gauge, Meter, Sparkline and BarChart.

  • Its space is Bounds(), never buf.Size() (ADR 0007 §1 rule 1).
  • It repaints its whole Bounds() before drawing content (rule 3), by composing widgets/block.Block, whose Draw fills the rect in Background before anything else. No widget here draws a border, a corner or a title itself.
  • Its Draw is allocation-free (ADR 0008 §4). Everything derived from the size — which regions survived the budget, where the axis labels go, the glyph ramp for a sparkline — is computed in the size-change check, cached against the rect, and only read in Draw.

Constructing it

viz.NewMeter(r buffer.Rect) *viz.Meter

NewMeter takes a rect; Zones is a slice of named ranges and Threshold a single value.

  • Zones — []Zone — named ranges across the track. The zone boundaries are drawn as +.
  • Threshold — float64 — the marker, drawn as |. A separate value from the zones: a zone boundary is a range edge, a threshold is a limit.
  • ThresholdVisible — bool — show the threshold marker at all.
  • ShowName — bool — draw the active zone’s name in words. This is the signal that makes the meter readable without colour.
  • ShowValue — bool, via SetShowValue(on) — print the reading beside the bar. It was an exported field until v0.5.0, and assigning it left the cached layout budget stale: the number painted over the zone name. The setter drops the cache, so the bar re-solves where it starts. Read it back with ShowValue().

More on accessibility

Three non-colour signals, which is more than any other viz widget: zone boundaries are +, the threshold is |, and the active band is named in text. SetShowValue(true) adds the number. A meter is designed to be read correctly on a monochrome terminal, and this is why it is the one widget here whose meaning does not depend on the colour capture at all.

When not to use it

Do not use it for work in progress. It reads a bounded value against zones; it does not track progress toward a completion. That is ProgressBar.

Do not use it without setting Zones. Without named zones the bar is a progress bar with a threshold, and the threshold marker alone will not tell a reader what “over” means.

Do not use it where the value is unbounded. The whole widget is the range. Clamp it yourself or use a Sparkline.

Do not use it to compare several series. One meter is one bounded value. For several, either several meters in a Split or a BarChart.

Do not turn ShowName off. It is the accessibility affordance, and turning it off leaves a coloured band with no legend on screen.

Instead: ProgressBar for progress, BarChart for comparison across categories.