termino
~/docs/custom/bar-chart

BarChartcustom

Vertical bars with gridlines, value and category labels

~/custom/bar-chart
live
$ termino bar-chart — weekly traffic
──────────────90────────────────────
76 ████ 74 ████
────████57████65──────████████
44 ████ ████ ████ ████ 46 ████ ████
████████████████████████████████
████████████████████████████████
████ ████ ████ ████ ████ ████ ████ ████
████ ████ ████ ████ ████ ████ ████ ████
mon tue wed thu fri sat sun
live bars jitter — gridlines + value labels

##API

Column bars over a half-block grid (`height*2` pixel resolution). Bars grow from the baseline, lerp `color → fill` by depth, and sit on optional `─` gridlines from niceTicks. Values float above the bar tops, category labels center under each column group.

properties
proptypedefaultdescription
data{ label?, value, color? }[]-Bar values; per-bar color overrides `color`
width / heightnumber40 / 9Chart area in characters
color / fillstring"#7dcfff" / "#1a1b26"Bar color and gradient end
maxnumberautoFixed scale top (defaults to max value)
showValues / showLabelsbooleantrueValue captions and category labels
gridlinesbooleantrueNice-tick horizontal gridlines

##Keymap

~/keymap
Display only

##Notes

  • Gridlines only draw on empty cells — bars stay solid.
  • Label glyphs are clipped to their column group, so long names degrade gracefully.

##Source

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

tsxbar-chart.tsx
1import { createElement as h, useMemo } from "react";
2import { Canvas } from "./canvas";
3import { renderBars, type BarDatum } from "./chart";
4
5export interface BarChartProps {
6 data: BarDatum[];
7 width?: number;
8 height?: number;
9 color?: string;
10 fill?: string;
11 max?: number;
12 showValues?: boolean;
13 showLabels?: boolean;
14 gridlines?: boolean;
15}
16
17export function BarChart({
18 data,
19 width = 40,
20 height = 9,
21 color,
22 fill,
23 max,
24 showValues,
25 showLabels,
26 gridlines,
27}: Readonly<BarChartProps>) {
28 const rows = useMemo(
29 () =>
30 renderBars(data, width, height, {
31 color,
32 fill,
33 max,
34 showValues,
35 showLabels,
36 gridlines,
37 }),
38 [data, width, height, color, fill, max, showValues, showLabels, gridlines],
39 );
40 return h("box", { flexDirection: "column", gap: 0, width }, h(Canvas, { rows, width }));
41}
42