2 BarChart
L4stIdi0t edited this page 2026-10-09 22:01:06 +02:00

BarChart

Magnitude across a handful of named things.

Bars grow out of the baseline when the chart mounts, one category after the next. Two series or more render side by side; stacked puts them end to end instead, for a total that is worth reading as well as its parts. A 2px gap in the card colour separates every touching mark — that, not an outline, is what keeps two adjacent segments apart. Hover or arrow onto a category to compare its series in one tooltip; the numbers are also in a visually-hidden table, which is what a screen reader actually reads. The table sits inside a clipped box: a table grows to fit its content whatever width it is given, so on its own it would widen a phone page.

Charts · keyboard contract

<script lang="ts">
	import { BarChart } from '@l4st/driftwood';
</script>
Light Dark
bar-chart bar-chart in dark mode

Props

Prop Type Default What it does
series required ChartSeries[] — One entry per bar colour. Each data array is read in categories order.
categories required string[] — The named things being compared.
stacked boolean false Stack the series into one bar per category instead of grouping them.
horizontal boolean false Lay the bars along the x axis — the right choice once labels are long.
height number 220 Plot height in pixels; the width follows the container.
max number — Force the value ceiling. Defaults to a rounded value at or above the data.
format (value: number) => string compact Formats every value: axis, tooltip and table. Defaults to compact (1.2k).
ticks number 4 Roughly how many gridlines to aim for.
legend boolean true Hide the legend even with several series. The table view still names them.
thickness number 24 Cap on bar thickness. Leftover band space is left as air, never filled.
categoriesLabel string 'Category' Heads the category column of the screen-reader table — what the categories are ('Region', 'File type').
aria-label required string — Names the chart, and captions the table. Required.
class string — Merged with the component's own classes, last — so yours win.

Keyboard

Key Does
← / → (↑ / ↓ when horizontal) move between categories
Home / End first / last category
Escape clear the highlight

Example

The markup behind the screenshot above, lifted from src/routes/shots/ — so it compiles, and it is exactly what produced the image.

<BarChart
	series={[
		{ label: 'Media', data: [5240, 4100, 3020, 1800] },
		{ label: 'Backups', data: [3180, 2600, 2100, 1500] },
		{ label: 'Code', data: [980, 760, 610, 420] }
	]}
	categories={['volume1', 'volume2', 'volume3', 'volume4']}
	stacked
	categoriesLabel="Volume"
	aria-label="Gigabytes stored per volume, by category"
/>

Notes

ChartSeries

type ChartSeries = {
	/** Names the series in the legend, the tooltip and the table view. */
	label: string;
	/** One value per category, in `categories` order. `null` is a gap, not a zero. */
	data: (number | null)[];
	/** Overrides the palette slot, e.g. `'var(--chart-3)'` or `'var(--success)'`. */
	color?: string;
};

Colour

A series takes the --chart-N slot at its own index and keeps it, so a filter that removes one series never repaints the others. The five slots are validated as an ordered set — each neighbouring pair stays apart under simulated protanopia and deuteranopia — which is why a sixth series does not get a generated hue: group the tail into an "Other" instead, or facet the chart.

Pass color only for a series whose meaning is fixed, such as an error count that should always be var(--destructive).

Two things it will not do

  • No second y axis. Two measures of different scale are two charts, small multiples, or both indexed to a common base — never two scales in one frame.
  • No number on every point. The axis, the legend and the tooltip carry the values; the visually-hidden table carries all of them exactly.

Charts · LineChart · DonutChart · ShareBar · Heatmap · Gauge · Sparkline · ChartLegend


← All components · Getting started · Theming · source