Compare buckets with a vertical bar chart
By the end of this recipe you'll have a clean column chart with categorical x-axis, value labels on demand, and one bar quietly highlighted for the day's takeaway.
Overview
One bar per bucket. Heights compare directly because they share a baseline. The reader's eye does the maths for you.
Vertical bars answer "how big is each?" — pours per shift, orders per weekday, signups per product. They beat lines whenever the x-axis is discrete and unordered, or when you want the reader to compare individual values rather than read a trend.
Skip vertical bars if your category labels are long ("Premium plan with priority support" wraps and looks terrible vertical) — go horizontal instead. Skip if your bars are showing a continuous time series — that's a line chart's job.
Default opinion: sort by value, not by label. The reader's eye reads ranking before it reads names.
The chart
Daily pours at the gold mine clerk's window. Thursday gets the highlight because that's the day worth talking about.
Required pieces
From @corelithzw/react.
Intended exports used here: Chart.Bar.
Chart.Bar ships in @corelithzw/react v0.2.
The React snippet
Same shape as Chart.Line. Highlight one bar by returning a colour from a per-datum function.
Customising
Three forks.
Recolour per tone
Use a tone function when each bucket has a qualitative sense — success/danger/neutral — and the colour repeats that sense.
<Chart.Bar
data={data}
color={(d) =>
d.pours > 30 ? 'success' :
d.pours < 15 ? 'danger' : 'brand'}
height={260}
/>
Sort + flip
Sort by value descending so the eye reads ranking. Flip the y-domain (or the bar direction) for a "lower is better" metric.
<Chart.Bar
data={data.sort((a, b) => b.pours - a.pours)}
xAccessor="day"
yAccessor="pours"
height={260}
/>
Animate from baseline
Grow each bar from the x-axis on first mount. Keep the stagger short (40–80ms) — long stagger reads as a loading state.
<Chart.Bar
data={data}
animate="grow"
animateStaggerMs={60}
height={260}
/>
In context
Inside a report layout — pours-per-shift with the totals on the left.
Accessibility
Bars are forgiving — labels do most of the work, you just have to attach them.
- Role and label. Root
<svg>usesrole="img"+aria-labelledbyon inline<title>+<desc>. - Per-bar labels. Wrap each
<rect>in a<g aria-label="Thursday: 47 pours">so the screen reader names the value. - Screen-reader summary. A visually-hidden paragraph (
.ck-sr-only) names the highest, the lowest, the total and any obvious pattern. - Highlight repeats the message. The highlighted bar is full opacity, but the value above it is also bold and brand-coloured — colour is never the only signal.
- Keyboard. Each bar is
tabindex="0"; Arrow keys walk the buckets, Home/End jump to the extremes.