termino
~/docs/custom/gauge

Gaugecustom

Semicircle arc with warn/danger zones and needle

~/custom/gauge
live
$ termino gauge — warn/danger zones
· ·
cpu 42 / 100 42%

##API

Upper-half arc from left to right. The arc is colored per-cell by its value fraction: under `warnAt` base color, under `dangerAt` warn color, else danger color. A bright needle sweeps from the center and a footer row prints `label value/max %`. Value renders as filled arc cells — not a solid track.

properties
proptypedefaultdescription
valuenumber-Current value (clamped to min..max)
min / maxnumber0 / 100Scale bounds
width / heightnumber26 / 9Arc size
color / warnColor / dangerColorstringgreen / yellow / redZone colors
warnAt / dangerAtnumber0.66 / 0.88Zone thresholds as fractions
showTicksbooleantrueQuarter ticks on the outer edge
labelstring-Footer label

##Keymap

~/keymap
Display only

##Notes

  • Zone colors are computed per arc cell, so the frontier is exact — no banded steps.
  • Needle glyphs are `│` along the radius with a `▌` tip on the arc.

##Source

Real implementation — this is the code that runs in your terminal.

tsxgauge.tsx
1import { createElement as h, useMemo } from "react";
2import { Canvas } from "./canvas";
3import { renderGauge, DIM } from "./chart";
4
5export interface GaugeProps {
6 value: number;
7 min?: number;
8 max?: number;
9 width?: number;
10 height?: number;
11 color?: string;
12 warnColor?: string;
13 dangerColor?: string;
14 warnAt?: number;
15 dangerAt?: number;
16 showTicks?: boolean;
17 label?: string;
18}
19
20/** Colour of the percentage readout under the dial: red past the danger
21 * threshold, amber past the warning one, green below both. */
22function zoneColor(pct: number, dangerAt: number, warnAt: number): string {
23 if (pct >= dangerAt) return "#f7768e";
24 if (pct >= warnAt) return "#e0af68";
25 return "#9ece6a";
26}
27
28export function Gauge({
29 value,
30 min = 0,
31 max = 100,
32 width = 26,
33 height = 9,
34 color,
35 warnColor,
36 dangerColor,
37 warnAt,
38 dangerAt,
39 showTicks,
40 label,
41}: Readonly<GaugeProps>) {
42 const rows = useMemo(
43 () =>
44 renderGauge(value, min, max, width, height, {
45 color,
46 warnColor,
47 dangerColor,
48 warnAt,
49 dangerAt,
50 showTicks,
51 }),
52 [value, min, max, width, height, color, warnColor, dangerColor, warnAt, dangerAt, showTicks],
53 );
54 const pct = max > min ? Math.round(((value - min) / (max - min)) * 100) : 0;
55 return h(
56 "box",
57 { flexDirection: "column", gap: 0, width },
58 h(Canvas, { rows, width }),
59 h(
60 "box",
61 { flexDirection: "row", gap: 1, width },
62 h("text", { fg: DIM }, label ? ` ${label}` : ""),
63 h("text", { fg: "#e0e6fa" }, `${value} / ${max}`),
64 h("text", { fg: zoneColor(pct, dangerAt ?? 0.88, warnAt ?? 0.66) }, ` ${pct}%`),
65 ),
66 );
67}
68