Charts
BarChart
Discrete categories compared by length.
When to reach for it
The categories are buckets rather than a continuum. If the axis is time and the reader is following a trend, an AreaChart or LineChart reads it faster.
Examples
default
| month | Desktop | Mobile |
|---|---|---|
| Jan | 186 | 80 |
| Feb | 305 | 200 |
| Mar | 237 | 120 |
| Apr | 273 | 190 |
| May | 209 | 130 |
| Jun | 314 | 240 |
fill variants
| Desktop |
|---|
| 186 |
| 305 |
| 237 |
| 273 |
| 209 |
| 314 |
stacking and orientation
| Desktop | Mobile |
|---|---|
| 186 | 80 |
| 305 | 200 |
| 237 | 120 |
| 173 | 190 |
emphasis
| Desktop |
|---|
| 186 |
| 305 |
| 237 |
| 273 |
| 209 |
| 314 |
| Desktop |
|---|
| 186 |
| 305 |
| 237 |
| 273 |
| 209 |
| 314 |
| Desktop |
|---|
| 186 |
| 305 |
| 237 |
| 273 |
| 209 |
| 314 |
interaction
| Desktop | Mobile |
|---|---|
| 186 | 80 |
| 305 | 200 |
| 237 | 120 |
| 273 | 190 |
brush
| day | Desktop |
|---|---|
| D1 | 90 |
| D2 | 176 |
| D3 | 241 |
| D4 | 270 |
| D5 | 254 |
| D6 | 198 |
| D7 | 115 |
| D8 | 153 |
| D9 | 226 |
| D10 | 266 |
| D11 | 263 |
| D12 | 217 |
| D13 | 140 |
| D14 | 129 |
| D15 | 208 |
| D16 | 259 |
| D17 | 268 |
| D18 | 234 |
| D19 | 164 |
| D20 | 104 |
| D21 | 188 |
| D22 | 248 |
| D23 | 270 |
| D24 | 248 |
| D25 | 187 |
| D26 | 102 |
| D27 | 166 |
| D28 | 235 |
loading
value labels
| Desktop |
|---|
| 1,860 |
| 30,500 |
| 23,700 |
| 27,300 |
| 9,200 |
| 31,400 |
sonify
| month | Revenue | Refunds |
|---|---|---|
| Jan | 18,600 | 1,240 |
| Feb | 30,500 | 980 |
| Mar | 23,700 | 2,310 |
| Apr | 27,300 | 1,150 |
| May | 9,200 | 3,040 |
| Jun | 31,400 | 870 |
toolbar
Arrow keys pan by one point, Page Up and Page Down by a screenful, Home and End jump to the ends. Plus and minus zoom, zero resets. Ctrl and the wheel zoom around the pointer, and dragging across the plot zooms to that span.
Showing Jan 25 to Dec 26, 24 of 24 points
| month | Desktop |
|---|---|
| Jan 25 | 1,200 |
| Feb 25 | 1,534 |
| Mar 25 | 1,837 |
| Apr 25 | 2,077 |
| May 25 | 2,235 |
| Jun 25 | 2,296 |
| Jul 25 | 2,258 |
| Aug 25 | 2,131 |
| Sep 25 | 1,932 |
| Oct 25 | 1,687 |
| Nov 25 | 1,428 |
| Dec 25 | 1,189 |
| Jan 26 | 999 |
| Feb 26 | 884 |
| Mar 26 | 861 |
| Apr 26 | 937 |
| May 26 | 1,108 |
| Jun 26 | 1,360 |
| Jul 26 | 1,669 |
| Aug 26 | 2,005 |
| Sep 26 | 2,337 |
| Oct 26 | 2,631 |
| Nov 26 | 2,861 |
| Dec 26 | 3,004 |
Notes
Discrete categories compared by length — the shape for "how much, per thing".
Reach for <AreaChart> or <LineChart> when the axis is continuous and the reader is following a trend rather than comparing buckets.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| childrenrequired | ReactNode | The composed parts — axes, grid, tooltip, legend, and the marks themselves. | |
| configrequired | TConfig & ValidateKeys<TData, TConfig> | — | |
| datarequired | TData[] | The rows the chart draws. One entry per point, bar or category. | |
| titlerequired | string | What the chart shows, in a sentence a reader could act on. Required, and announced to a screen reader even when it is not printed. | |
| animationType | ChartRevealType | 'forward' | The grow-in order every `<BarChart.Bar>` inherits. |
| barCategoryGap | number | Gap between categories. | |
| barGap | number | Gap between bars inside one category. | |
| barRadius | number | BAR_RADIUS | The corner every `<BarChart.Bar>` inherits. |
| chartProps | ComponentProps<typeof RechartsBarChart> | Escape hatch onto the raw Recharts chart element. | |
| className | string | Merged onto the figure, last, so a call site can size or space it. | |
| defaultSelectedDataKey | string | null | null | The series lit on first render. Selection dims every other series. |
| description | ReactNode | A line under the title — the unit, the window, the caveat. | |
| empty | ChartEmptyProps | false | What the chart shows when it has nothing to draw. Rendered instead of the plot whenever `data` is empty and the chart is not loading — the state a real dashboard reaches within a week, and the one an empty pair of axes is indistinguishable from a failed load. `false` keeps the axes, for a chart whose emptiness is itself the reading. | |
| hideDataTable | boolean | false | Drops the hidden table view. Only correct when the page prints the data itself. |
| isLoading | boolean | false | Swaps the marks for an animated skeleton, keeping the measured height so the page does not jump when the data lands. |
| loadingBars | number | How many bars the skeleton draws. | |
| onSelectionChange | (selectedDataKey: string | null) => void | Fires when the selection changes, and with null when it is cleared. | |
| orientation | BarOrientation | 'vertical' | Which way the bars run. Reach for `horizontal` when the category names are long enough to need rotating under a column. |
| showTitle | boolean | Prints the title above the plot instead of hiding it from sight. | |
| stackType | BarStackType | 'default' | How several marks combine: side by side, stacked, or normalised to 100%. |
| xDataKey | keyof TData & string | The row field on the category axis. Needed by the brush and by the table view. |
Types
export type BarVariant = 'default' | 'hatched' | 'duotone' | 'duotone-reverse' | 'gradient' | 'stripped'
export type BarStackType = 'default' | 'stacked' | 'percent'
export type BarOrientation = 'vertical' | 'horizontal'Accessibility
- title is required; the rows are also rendered as a visually hidden table.
- Every bar carries an invisible full-height hit rectangle, so a 3px bar at the bottom of the scale is as easy to hit as a full-height one.
- A clickable legend entry is a real button with aria-pressed, not a div with a click handler.
- The staggered grow-in is anchored to the chart’s own start rather than to each bar’s mount, so a hover cannot replay it — and reduce-motion drops it entirely.