termino
~/docs/custom/ring-chart

RingChartcustom

Donut with a centered total and legend

~/custom/ring-chart
live
$ termino ring-chart — donut + center total
100
mem 52%
cpu 28%
io 12%
net 8%
ring center shows Σ — like a k8s status dial

##API

PieChart's renderer with `innerRatio 0.55`: the core is punched out and the total (or any `center` string) is drawn in the hole. The center label is only shown when a center is provided — pass `center=""` to keep it empty.

properties
proptypedefaultdescription
data{ label, value, color }[]-Slices
width / heightnumber21 / 11Donut size
legendbooleantrueLegend rows
centerstringΣ of valuesText in the hole
centerColorstring"#c0caf5"Center text color

##Keymap

~/keymap
Display only

##Notes

  • The center is sized to the hole — long totals get clipped visually.
  • Great for status dials: green/yellow/red slices + a count in the middle.

##Source

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

tsxring-chart.tsx
1import { createElement as h, useMemo } from "react";
2import { Canvas } from "./canvas";
3import { renderDonut, type Slice } from "./chart";
4
5export interface RingChartProps {
6 data: Slice[];
7 width?: number;
8 height?: number;
9 legend?: boolean;
10 center?: string;
11 centerColor?: string;
12}
13
14export function RingChart({
15 data,
16 width = 21,
17 height = 11,
18 legend = true,
19 center,
20 centerColor,
21}: Readonly<RingChartProps>) {
22 const total = useMemo(() => data.reduce((a, s) => a + s.value, 0), [data]);
23 const rows = useMemo(
24 () =>
25 renderDonut(data, width, height, {
26 innerRatio: 0.55,
27 legend,
28 center: center ?? String(total),
29 centerColor,
30 }),
31 [data, width, height, legend, center, centerColor, total],
32 );
33 return h(
34 "box",
35 { flexDirection: "column", gap: 0, width: width + 14 },
36 h(Canvas, { rows, width: width + 14 }),
37 );
38}
39