Bar Chart

BarChart is the bar primitive used inside Chart — use it directly when you need per-series color overrides, click handlers, or grouped-stacked layout. It supports the following:

  • Each series is defined by a BarSeriesConfig ({ key, label?, color, unit?, stackId? }) so series order, color, and tooltip labels are explicit.
  • layout controls how multiple series are arranged: single, grouped, stacked, or grouped-stacked (mix of stacking and grouping via stackId).
  • orientation="horizontal" flips the axes — use it for long category labels.
  • All click callbacks (onBarClick, onXAxisTickClick, onYAxisTickClick) receive the native mouse event as the last argument so you can call e.stopPropagation().
  • unit on a series adds a suffix to its tooltip value.

Import

import { BarChart } from "h2o-library/charts";

Usage

Single

One metric across categories.

Cases by specialty

Cases
const data = [
  { x: "Bariatrics", cases: 35 },
  { x: "Cardiology", cases: 78 },
  { x: "Dermatology", cases: 23 },
];

<BarChart
  data={data}
  bars={[{ key: "cases", label: "Cases", color: "#041957" }]}
  layout="single"
/>;

Grouped

Side-by-side bars per category for multi-metric comparison.

Appointments by month

Completed
Missed
Rescheduled
<BarChart
  data={data}
  bars={[
    { key: "completed", label: "Completed", color: "#041957" },
    { key: "missed", label: "Missed", color: "#3767F6" },
  ]}
  layout="grouped"
/>;

Stacked

Stack series into one bar per category for part-to-whole comparison.

Cases by specialty

Cardiology
Dermatology
Neurology
<BarChart
  data={data}
  bars={[
    { key: "cardiology", label: "Cardiology", color: "#041957" },
    { key: "dermatology", label: "Dermatology", color: "#3767F6" },
    { key: "neurology", label: "Neurology", color: "#9FB7FF" },
  ]}
  layout="stacked"
/>;

Grouped-Stacked

Stack some bars while keeping other groups side-by-side. Assign stackId to each bar — bars with the same stackId stack together; distinct stackId values are placed side-by-side.

Revenue by product line vs services

Product A
Product B
Service A
Service B
const bars = [
  {
    key: "productA",
    label: "Product A",
    color: "#041957",
    stackId: "products",
  },
  {
    key: "productB",
    label: "Product B",
    color: "#3767F6",
    stackId: "products",
  },
  {
    key: "serviceA",
    label: "Service A",
    color: "#e94040",
    stackId: "services",
  },
  {
    key: "serviceB",
    label: "Service B",
    color: "#f08080",
    stackId: "services",
  },
];

<BarChart data={data} bars={bars} layout="grouped-stacked" />;

Horizontal

orientation="horizontal" flips the axes — use it when category labels are long and would otherwise overlap on the X axis. Long labels truncate with ellipsis and surface their full text in the native tooltip on hover.

Quarterly KPI scorecard

Score
<BarChart
  data={data}
  bars={[{ key: "score", label: "Score", color: "#041957", unit: "%" }]}
  layout="single"
  orientation="horizontal"
/>;

Click Events

onBarClick, onXAxisTickClick, and onYAxisTickClick all expose the native mouse event so you can stop propagation when needed.

<BarChart
  data={data}
  bars={bars}
  onBarClick={(dataPoint, index, dataKey, e) => {
    e.stopPropagation();
    console.log(dataKey, dataPoint);
  }}
  onXAxisTickClick={(value, e) => {
    e.stopPropagation();
    console.log("tick:", value);
  }}
/>;

Units in Tooltips

Setting unit on a series appends it to the value in the hover tooltip — useful for %, kg, min, etc.

<BarChart
  data={data}
  bars={[
    { key: "utilization", label: "Utilization", color: "#041957", unit: "%" },
  ]}
/>;

Playground

Loading playground…

Keyboard

Interactive regions are only added when the matching click callback is passed (onBarClick, onXAxisTickClick, onYAxisTickClick). Those targets use role="button", tabIndex={0}, and activate with Enter or Space (same as click). Tab moves between focusable tick labels and bar segments that have handlers.

Props

BarChart

PropTypeDefaultDescription
data*BarChartDataPoint[]Array of data objects. Each must have an x field for the category axis and numeric fields matching bar keys.
bars*BarSeriesConfig[]Series definitions — each specifies the data key, color, and optional label, unit, and stackId.
layout"single" | "grouped" | "stacked" | "grouped-stacked""single"How multiple series are arranged.
orientation"vertical" | "horizontal""vertical"Vertical draws bars upward; horizontal draws bars rightward (X/Y axes swapped).
heightnumber400Height of the chart in pixels.
showGridbooleantrueRenders a background grid behind the bars.
showLegendbooleanfalseShows the built-in Recharts legend.
classNamestringundefinedAdditional CSS class for the container div.
onBarClick(dataPoint, index, dataKey, event) => voidundefinedFired when a bar segment is clicked. Receives the data point, its index, the series key, and the native mouse event.
onXAxisTickClick(value, event) => voidundefinedFired when an X-axis tick label is clicked.
onYAxisTickClick(value, event) => voidundefinedFired when a Y-axis tick label is clicked.

* Required

BarSeriesConfig

PropTypeDefaultDescription
key*stringKey in the data object this series reads from.
color*stringFill color (hex, hsl, or any CSS color).
labelstringkeyHuman-readable name shown in legend and tooltip.
unitstringundefinedUnit suffix appended in the tooltip (e.g. "%", "kg").
stackIdstringundefinedRequired when layout="grouped-stacked". Bars with the same stackId stack; different stackIds are grouped side-by-side.

* Required

BarChartDataPoint

PropTypeDefaultDescription
x*stringCategory label shown on the category axis.
[key]number | stringNumeric values for each bar series, keyed by the corresponding BarSeriesConfig.key.

* Required

Design Guidelines

  • Use single for one metric across categories.
  • Use grouped for side-by-side multi-metric comparison.
  • Use stacked for part-to-whole comparison; keep series count ≤ 5.
  • Use grouped-stacked when you need both stacking within a group and grouping between groups.
  • Use orientation="horizontal" when category names are long — it avoids tick-label overlap.
  • For headline pages with one or two charts, prefer the Chart wrapper — it adds the title, KPI strip, and legend out of the box.

Accessibility

  • Tooltips appear on mouse hover and are not keyboard-accessible by default.
  • For critical data, provide a companion data table.
  • onBarClick, onXAxisTickClick, and onYAxisTickClick make individual bars and axis ticks interactive — pair them with page-level keyboard handlers if you need keyboard parity.