Skip to content

Components · Charts

BarChart

Vertical and horizontal bar charts, grouped or stacked, with value labels, highlight, reference lines, keyboard tooltips, drill-in and a data table.

@rookcom/monarch-react/chartsComponent

Grouped columns

Posts

Drafted and posted per week

Use the arrow keys to inspect values.
Posts
WeekDraftedPosted
Week 1128
Week 299
Week 31511
Week 41110
Week 51413
Week 61812

Usage examples

Stacked with totals

Highlighted month with a target

Horizontal, with drill-in

Purpose

Compares amounts across categories or discrete periods, one or more series per category, with exact values on hover, tap or arrow keys and the full data as a table.

Use when

  • Comparing categories: requests per topic, revenue per month, posts per week.
  • Showing parts of a total per category (layout="stacked").
  • Long category names or rankings (orientation="horizontal").

Avoid when

  • A continuous trend with many points: use LineChart.
  • A simple ranked list with values and links: use BarList.
  • Shares of one whole: use StackedProportionBar or DonutChart.

Design principles

  • Bars always start at zero; the value axis can only fix its far end.
  • Only the far end of a bar is rounded (4px), stacked segments are separated by a surface gap, and only the outer segment is rounded.
  • Colour encodes the series, never the category; one series is one colour, and highlightIndex emphasises by dimming the rest.
  • Value labels are optional and compact (1.2K); exact values live in the tooltip and table.

API reference

import { BarChart } from '@rookcom/monarch-react/charts';
ExportKindRenderingRoot class
BarChartcomponentclient.mn-chart

Renders ChartFrame (ref to its <figure>); ChartFrame props pass through except children, legend and table, which BarChart builds.

data is one object per category; categoryKey names the category field and each series key a numeric field.

height defaults to 240 for vertical charts; horizontal charts grow by 32px per category.

Generated from the TypeScript declarations of packages/react/src/components/charts/bar-chart.

Properties

BarChart

Bar and column chart: one or more series per category, grouped or stacked, vertical or horizontal, with value labels, a highlighted category, reference lines, tooltips on hover, touch and keyboard, legend toggles, drill-in and an accessible data table.

PropTypeDescription
categoryKey requiredstringField holding the category: a label, a number or a `Date` (formatted with `categoryFormat`).
data requiredreadonly ChartDatum[]One row per category, in display order, with one number per series. Missing values draw no bar.
series requiredreadonly ChartSeries[]The measures to draw. Colours follow the order unless pinned.
title requiredReactNodeThe chart's name. Labels the figure. Required.
actionsReactNodePeriod or metric controls in the header, such as a pill TabsFilter or a Select.
activeIndexnumber | nullControlled inspected category (`null` for none).
categoryFormatIntl.DateTimeFormatOptions`Intl.DateTimeFormat` options when categories are dates. Default `{ month: 'short', day: 'numeric' }`.
categoryLabelstringColumn header for the categories in the data table. Default: `categoryKey`.
classNamestring
defaultHiddenSeriesreadonly string[]Uncontrolled initial hidden series.
defaultShowTablebooleanUncontrolled initial table view. Default `false`.
descriptionReactNodeOne line under the title: the period, unit or what the chart answers. Describes the figure.
emptyActionsReactNodeActions in the empty state, such as a link to set up tracking.
emptyDescriptionReactNodeEmpty-state description, such as what will appear and when.
footerReactNodeNotes under the chart: source, last updated, a footnote.
formatCategory((value: XValue, index: number) => string)Formats categories everywhere. Wins over `categoryFormat`.
formatTickValueFormatterFormats value-axis ticks. Default: compact notation of `valueFormat`.
formatValueValueFormatterFormats values in the tooltip, table, labels and summary. Wins over `valueFormat`.
headingLevelChartFrameHeadingLevelRender the title as a heading (`h2`–`h6`) to match the page outline. Default: not a heading.
heightnumberHeight of the chart in px. Default 240 vertical; horizontal grows with the number of categories (32px each).
hiddenSeriesreadonly string[]Controlled list of hidden series keys.
highlightIndexnumberEmphasise one category (the current month, say); the others are dimmed.
idstring
labelsBarChartLabels
layoutBarChartLayoutWith several series: side by side (`grouped`, default) or one stacked bar per category. Exposed as `data-layout`.
legendTogglebooleanLegend entries toggle their series. Default `true` (legend shows for two or more series).
localestringBCP 47 locale for numbers and dates. Pass it when rendering on the server.
onActiveIndexChange((index: number | null) => void)
onBarSelect((datum: ChartDatum, index: number) => void)Click, Enter or Space on the inspected category, for drill-in (open the filtered list).
onHiddenSeriesChange((hidden: string[]) => void)
onRetry(() => unknown)Error-state retry. Return the refetch promise to keep the button busy until it settles.
onShowTableChange((showTable: boolean) => void)
orientationBarChartOrientation`vertical` (default) columns, or `horizontal` bars for long category names and rankings. Exposed as `data-orientation`.
referenceLinesreadonly ChartReferenceLine[]Dashed lines across the bars for targets or averages.
showTablebooleanControlled table view.
statusChartFrameStatus`ready` (default) shows the chart; `loading` a skeleton with `aria-busy`; `empty` an empty state; `error` an error with Try again when `onRetry` is set. Exposed as `data-status`.
summarystringReplaces the generated text summary (the plot's accessible name).
tableTogglebooleanShow the "View as table" toggle. Default `true` when `table` is set.
valueDomainreadonly [ChartDomainBound, ChartDomainBound]Fix the far end of the value axis (bars always start at zero).
valueFormatIntl.NumberFormatOptions`Intl.NumberFormat` options for values in the tooltip, table, labels and summary.
valueLabelsbooleanPrint each bar's value (the stack total when stacked) at its end.

Variants

PropValuesDescription
orientation'vertical''horizontal'Columns, or bars with category labels on the left (truncated with an ellipsis). data-orientation.
layout'grouped''stacked'Series side by side, or one bar per category with positive and negative parts stacked separately and a Total column in the table. data-layout.
valueLabels'true''false'Each bar’s value (the stack total when stacked) at its end.
series[].dashed'true''false'An outlined bar instead of a filled one, as a second encoding (a forecast, a target).

States

StateExposed asBehaviour
Inspecting–A muted band behind the category and a tooltip with every visible series (and the total when stacked).
Highlighteddata-dimmed on the other barsWith highlightIndex, every other category is dimmed.
Selectabledata-selectableWith onBarSelect the plot shows a pointer cursor and Enter selects.
Series hiddenaria-pressed="false"The series leaves the plot and the axis; it stays in the table.
Empty / loading / errordata-statusFrom ChartFrame.

Interaction behaviour

  • Hover or tap a category to inspect it; leaving with the mouse clears it.
  • onBarSelect(datum, index) runs on click, Enter or Space, for drill-in such as opening a filtered list.
  • Legend entries toggle series (controlled hiddenSeries or uncontrolled defaultHiddenSeries).
  • activeIndex + onActiveIndexChange sync the inspected category with other charts.

Keyboard support

KeysAction
TabFocuses the plot (one tab stop) and inspects the first category.
ArrowRight / ArrowDownNext category (either pair works in both orientations).
ArrowLeft / ArrowUpPrevious category.
Home / EndFirst or last category.
PageUp / PageDownMoves a tenth of the categories.
EscapeHides the tooltip.
Enter / SpaceCalls onBarSelect for the inspected category.

Accessibility

Role
figure (ChartFrame); the plot is a group with aria-roledescription "chart"
Accessible name
The figure by title; the plot by a generated summary (count, then total and highest category per series) or summary.
  • The SVG is aria-hidden; the summary, a polite live region during keyboard inspection and the data table carry the values.
  • The tooltip is visual only, so pointer use does not flood screen readers.
  • The data table has every series and, when stacked, a Total column.
  • Emphasis is not colour alone: the highlighted category keeps full opacity while others dim, and value labels can show the numbers.
  • All text, including summaries and "Total", is translatable through labels.

Responsive behaviour

  • Lays out at the measured container width (works at 320px); bar thickness is capped so few bars do not turn into slabs.
  • Vertical category labels thin out when they would collide; horizontal labels truncate to at most 40% of the width.
  • Server render and first paint use a 640px layout scaled to fit, matching on hydration.

Theme support

  • Series use --mn-color-data-1 … -5; stacked segments are separated by a --mn-color-bg-surface stroke.
  • Light, dark and high contrast follow the tokens; data colours meet 3:1 (4.5:1 in high contrast) on every chart background.
  • Dimming uses opacity with a fast, token-timed transition that is instant under reduced motion.

Do and don't

Do

  • Sort categories meaningfully: by time for periods, by value for rankings.
  • Use horizontal bars when labels are longer than a word or two.
  • Fill missing periods with zero in your data when zero is the truth; leave them out when it is not.

Don't

  • Colour bars by category or by value; one series is one colour.
  • Stack more than about four series; the inner segments become unreadable.
  • Start the value axis anywhere but zero (BarChart does not allow it).

Dependencies

KindDepends on
npm packagesreact
Monarch componentsChartFrame

Hand-written SVG from src/internal/charts; no charting library.

Testing coverage

  • Grouped bars per category, legend toggles and a generated summary; no axe violations.
  • Stacked: Total column and tooltip footer, only the outer segment rounded.
  • Keyboard inspection with live announcements; Enter and Space call onBarSelect; band highlight.
  • Tap and click select a category.
  • Horizontal layout: category labels, value labels, auto height, no legend for one series.
  • highlightIndex dims the other categories.
  • Negative values extend below zero.
  • Hiding a series keeps the other colour.
  • Locale-aware percent formatting.
  • Renders on the server.
CheckCovered
Axe in jsdomYes
Server renderingYes
Browser suitesVisual baselines: /__gallery/bar-chart; Cross-browser axe: /components/bar-chart

Tests: packages/react/src/components/charts/bar-chart