Bar chart
Bars over categories or time buckets, with several series drawn side by side within each band.
Bars for comparing discrete things: teams, plans, weekdays, buckets. Several series are drawn side by side
within each band, or stacked into one bar with stack, and bar-width and bar-gap decide how much of the
band the group takes and how much of the group is air between the bars. orientation="horizontal" turns the
chart on its side, and value-labels prints each bar’s value on the chart.
A bar chart reads its x as discrete slots rather than as a continuous scale, so the axis is padded by half a band at each end and the cursor snaps to the band instead of landing between two points.
On first display the plot reveals from the zero baseline upward, so grouped bars grow together. Later data
updates stay immediate; set animation="none" when even the initial entrance should be disabled.
Import
import '@c2n/components/chart/bar-chart'This chart draws with uPlot, a peer dependency it loads on first draw: npm install uplot.
Usage
The values come from one France 2015–2024 extract of the public Our World in Data Energy dataset, in terawatt-hours. Here the same yearly rows used by the other chart pages are interpreted as categorical groups.
Labelling the bands
label-field names the key that holds each band’s label, and x-type="category" reads the x as slots. The
tick shows the label rather than the slot index, and the tooltip follows the band. Without a label-field
the bars fall back to x-field (or the row index), which is what a time-bucketed histogram usually wants.
Stacking
stack="normal" draws a band’s series as one bar, each segment starting where the one before it ends. Positive
values stack upwards from zero and negative ones downwards, each on a running total of its own, so a mixed-sign
series never draws across the other stack. stack="percent" divides every band by its total, so each bar is
100 high and the axis reads in percent: use it when the share matters more than the size. Hiding a series from
the legend re-stacks the others. The tooltip and the value labels always show a series’ own value, never the
running total. bar-gap has no effect on a stacked chart, since there are no gaps between grouped bars.
Orientation
orientation="horizontal" puts the categories down the left edge, the first at the top, and the values along
the bottom. Use it for long category names and for rankings (sort the rows yourself: the chart keeps their
order). The left axis grows to fit the longest name. Everything else — grouping, stacking, bar-width, the
legend and the tooltip — works the same way.
Value labels
value-labels prints each bar’s value: past the end of a grouped bar, or centred inside a stacked segment,
where a segment too small to hold its text is left unlabelled. The labels use the series’ own format, then
the chart’s number format, and the formatLabel property replaces both. It is handed the series’ own value,
the series definition and the row index:
chart.formatLabel = (value) => `${value.toFixed(0)} TWh`Bar geometry
bar-width is the share of the band a group occupies and bar-gap the share of that group taken by the
gaps between grouped bars, both from 0 to 1. The defaults — 0.6 and 0.1 — give comfortable bars with a
small gutter between the series of a group. Narrow the width for a sparse, editorial look; widen it to 1
for a histogram with no air between bands.
<c2-bar-chart label-field="bucket" x-type="category" bar-width="1" bar-gap="0">
<c2-chart-series field="count"></c2-chart-series>
</c2-bar-chart>Theming
Bars use the shared palette, --c2-chart__series-1--color through --c2-chart__series-8--color, wired by
@c2n/theme to the --c2-theme--chart-series-* tokens; a single series can override its slot with
<c2-chart-series color="…">. Every other --c2-chart__* variable — the grid, the axis, the tooltip, the
card around the plot — is shared with the rest of the package, so setting them once themes every chart.
Round the value end of each bar with --c2-chart__bar--border-radius. It accepts a unitless value from 0
(square) to 0.5 (fully rounded) and keeps the end at the zero baseline square:
c2-bar-chart {
--c2-chart__bar--border-radius: 0.18;
}