Skip to content

Bar Chart

ChartsSince 0.3.0
import { BarChart } from '@absoluteui/components/bar-chart';
import '@absoluteui/components/bar-chart/style.css';

Using Angular? See Bar Chart for Angular.

An accessible SVG bar chart for comparing values across categories. It provides:

  • vertical bars (columns) or horizontal bars;
  • grouped (side by side) or stacked series; negative values grow down (or leftward) from zero, and stacked positives and negatives diverge from the zero baseline;
  • gaps for missing values and optional printed value labels;
  • a legend of toggle buttons; keyboard-reachable bars (one tab stop, arrow keys) with a tooltip on focus and hover (hover shows every series of the category and, when stacked, the total);
  • a generated summary and a data table fallback (with a Total column when stacked);
  • per-series textures (with patterns) so series never differ by color alone (WCAG 1.4.1).
  • Comparing values across discrete categories.
  • Stacked: showing totals and their composition.
  • Horizontal: long category labels or many categories.
  • Trends over continuous time: use Line Chart.
  • A single part-to-whole breakdown with few parts: Pie Chart may read faster.
  • Exact lookup of many values: use Data Table.
import { BarChart } from '@absoluteui/components/bar-chart';
const host = document.createElement('div');
document.body.append(host);
BarChart.create(host, {
label: 'Support tickets by region',
categories: ['North America', 'Europe', 'Asia Pacific'],
series: [
{ id: 'open', label: 'Open', values: [34, 28, 19] },
{ id: 'closed', label: 'Closed', values: [120, 96, 88] },
],
valueAxis: { label: 'Tickets' },
valueLabels: true,
});

Horizontal stacked bars with negative values

Section titled “Horizontal stacked bars with negative values”
import { BarChart } from '@absoluteui/components/bar-chart';
const host = document.querySelector<HTMLElement>('#variance');
if (host) {
const chart = BarChart.create(host, {
label: 'Budget variance by department',
categories: ['Engineering', 'Marketing', 'Finance'],
series: [
{ id: 'capex', label: 'Capital', values: [40, 22, -8] },
{ id: 'opex', label: 'Operating', values: [25, -18, 12] },
],
orientation: 'horizontal',
layout: 'stacked',
valueFormat: { style: 'currency', currency: 'EUR', notation: 'compact' },
});
chart.setSeriesVisible('opex', false);
}
import { BarChart } from '@absoluteui/components/bar-chart';
import '@absoluteui/components/bar-chart/style.css';
const host = document.querySelector<HTMLElement>('#budget');
if (host) {
BarChart.create(host, {
label: 'Budget variance',
categories: ['Engineering', 'Marketing'],
series: [
{ id: 'capex', label: 'Capital', values: [40, -12] },
{ id: 'opex', label: 'Operating', values: [25, 18] },
],
orientation: 'horizontal',
layout: 'stacked',
});
}
import { BarChart } from '@absoluteui/components/bar-chart';
const host = document.createElement('div');
document.body.append(host);
BarChart.create(host, {
label: 'Orders by channel',
categories: ['Web', 'Store', 'Phone'],
series: [{ id: 'orders', label: 'Orders', values: [420, 310, 95] }],
valueLabels: true,
});
<div class="aui-chart aui-bar-chart [aui-bar-chart--horizontal] [aui-bar-chart--stacked] [aui-chart--patterns]">
<div class="aui-chart__header">title, description</div>
<ul class="aui-chart__legend" aria-label="Legend">toggle buttons with texture swatches</ul>
<div class="aui-chart__body">
<svg class="aui-chart__svg" role="group" aria-roledescription="column chart" aria-labelledby="T" aria-describedby="S">
<defs><pattern .../></defs>
<g class="aui-chart__grid" aria-hidden="true"/> <g class="aui-chart__axis …" aria-hidden="true"/>
<g class="aui-bar-chart__bars">
<g class="aui-bar-chart__series aui-chart__series--c2">
<rect class="aui-chart__mark aui-bar-chart__bar" role="img" aria-label="Europe, Closed: 96"/>
<rect class="aui-chart__pattern" fill="url(#pattern)" aria-hidden="true"/>
</g>
</g>
<g class="aui-bar-chart__labels" aria-hidden="true">value labels</g>
</svg>
<div class="aui-chart__tooltip" aria-hidden="true" hidden/>
</div>
<p class="aui-chart__summary" hidden/> <div class="aui-chart__data">Show data table, table</div>
</div>
BarChart.create(host: HTMLElement, options: BarChartOptions): BarChart

Global configuration key: barChart (see Configuration).

Option Type Default Description
label string Chart title: visible text and the accessible name of the plot (aria-labelledby). Required.
hideLabel boolean false Visually hide the title; it stays the accessible name.
description string Visible description below the title, also referenced by aria-describedby (text only).
summary string Replaces the generated accessible summary (aria-describedby).
valueFormat Intl.NumberFormatOptions Number format for values in tooltips, labels, the data table, the summary, and axis ticks (ticks use fixed fraction digits).
formatValue (value: number) => string Custom value text; overrides valueFormat everywhere except axis ticks.
hiddenSeries readonly string[] Ids of series (or slices) hidden initially; update() replaces the hidden set.
categories readonly string[] Category labels, one per bar group (text only). Required.
series readonly ChartSeries[] Series: { id, label, values: (number | null)[], color?: 1-8 }, one value per category; null, NaN, and infinities leave a gap. Required.
orientation 'vertical' | 'horizontal' "vertical" vertical: columns; horizontal: bars along the inline axis with category labels beside the plot.
layout 'grouped' | 'stacked' "grouped" grouped: side by side; stacked: summed per category (positives up from zero, negatives down).
categoryAxis { label?: string } Category axis title.
valueAxis { label?: string; min?: number; max?: number; tickCount?: number } Value axis title, fixed domain (bars are clipped to it), and approximate tick count (2-20). The automatic domain always includes zero.
legend 'auto' | 'show' | 'hide' "auto" auto: legend when there is more than one series (pie charts: always). Globally configurable.
dataTable 'toggle' | 'visible' | 'hidden' | 'none' "toggle" Data table fallback with the exact data: behind a Show data table button (built on first open), always visible, visually hidden (screen readers only), or none. Globally configurable.
tooltip boolean true Tooltip on pointer hover and keyboard focus. Globally configurable.
patterns boolean false Dash patterns and texture fills so series never differ by color alone. Off by default (plain colors); always on in forced colors. Turn it on when series are told apart by color alone (grouped or stacked series, multi-slice pies) and no labels carry the distinction (WCAG 1.4.1). Globally configurable.
height number 300 Plot height in CSS px (integer 120-2000); the width follows the container. Globally configurable.
valueLabels boolean false Print values at the bar ends (grouped) or inside segments that fit (stacked). Globally configurable.
locale string "en-US" Number, date, and message locale. Globally configurable. Inherited from common configuration.
direction 'ltr' | 'rtl' "ltr" rtl mirrors the category/x axis, the value axis side, and Left/Right arrow keys. Globally configurable. Inherited from common configuration.
Property Type Description
host HTMLElement The host element.
element SVGSVGElement The plot (svg role=“group”), named by the title and described by the summary.
summary string The generated (or custom) accessible summary.
hiddenSeries string[] Ids of hidden series (slices for Pie Chart).
Method Description
update(options: Partial<BarChartOptions>): void Merge, validate, and re-render. Invalid options throw and keep the previous state. Keyboard focus stays on the same data point.
setSeriesVisible(id: string, visible: boolean): void Show or hide a series (slice) programmatically; emits no event.
destroy(): void Remove rendering, host classes, listeners, the resize observer, and the configuration subscription.
Event Detail Bubbles Cancelable Description
aui-series-toggle { id: string; visible: boolean; hidden: string[] } Yes No The user toggled a legend entry (pointer or keyboard). Not emitted for update() or setSeriesVisible().

All rules live in the aui.components cascade layer, so application styles override them without specificity battles.

Class Purpose
aui-chart Host (shared chart chrome).
aui-bar-chart Host modifier for this chart type.
aui-chart--patterns patterns option on: dash patterns and textures shown.
aui-chart__header / __title / __title--hidden / __description Title and description.
aui-chart__legend / __legend-entry / __legend-item / __legend-item--hidden / __legend-label / __legend-detail Legend list and toggle buttons.
aui-chart__swatch aria-hidden legend and tooltip key (marker, dash, texture).
aui-chart__body / __svg / __layer Plot container (height from –aui-chart-height), SVG, and drawing layer.
aui-chart__grid / __gridline / __zero-line / __axis / __axis-line / __tick-label / __axis-title Axes (aria-hidden).
aui-chart__series--c1 ... --c8 Palette slot classes; set –aui-chart-color from color-chart-<n>.
aui-chart__dash--1 ... --4 / aui-chart__pattern / aui-chart__pattern-tile Dash patterns and texture overlays.
aui-chart__mark / __mark--active / __mark--hover Focusable data mark and its states.
aui-chart__value-label Printed values with a surface-colored halo.
aui-chart__tooltip / __tooltip-title / __tooltip-rows / __tooltip-row / __tooltip-label / __tooltip-value Tooltip (aria-hidden; the focused mark carries the same text).
aui-chart__empty Empty state text (No data, All series are hidden).
aui-chart__summary Hidden summary referenced by aria-describedby.
aui-chart__data / __data--hidden / __table-toggle / __table-scroll / __table / __cell--numeric Data table fallback.
aui-bar-chart--horizontal / --stacked Orientation and layout modifiers.
aui-bar-chart__bars / __series / __bar / __labels Bar groups, bar marks, and value labels.

Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.

--aui-border-width | --aui-color-border | --aui-color-border-strong | --aui-color-chart-1 | --aui-color-chart-2 | --aui-color-chart-3 | --aui-color-chart-4 | --aui-color-chart-5 | --aui-color-chart-6 | --aui-color-chart-7 | --aui-color-chart-8 | --aui-color-chart-axis | --aui-color-chart-grid | --aui-color-focus-ring | --aui-color-hover | --aui-color-link | --aui-color-surface | --aui-color-surface-sunken | --aui-color-text | --aui-color-text-muted | --aui-duration-fast | --aui-easing-standard | --aui-focus-ring-offset | --aui-focus-ring-width | --aui-font-family-sans | --aui-font-size-md | --aui-font-size-sm | --aui-font-size-xs | --aui-font-weight-medium | --aui-font-weight-regular | --aui-font-weight-semibold | --aui-line-height-normal | --aui-line-height-tight | --aui-radius-md | --aui-radius-sm | --aui-shadow-md | --aui-space-1 | --aui-space-2 | --aui-space-3 | --aui-tooltip-max-width | --aui-touch-target-min

interface BarChartConfig extends ChartBaseConfig { valueLabels: boolean }
interface BarChartOptions extends ChartCommonOptions, Partial<BarChartConfig> {
categories: readonly string[];
series: readonly ChartSeries[];
orientation?: 'vertical' | 'horizontal';
layout?: 'grouped' | 'stacked';
categoryAxis?: { label?: string };
valueAxis?: { label?: string; min?: number; max?: number; tickCount?: number };
}
interface BarChartSeriesToggleDetail { id: string; visible: boolean; hidden: string[] }

Pattern: SVG bar chart as a named, described group (role=“group” with aria-roledescription “column chart” or “bar chart”) of role=“img” bars with roving focus; data table fallback (native table, with a Total column when stacked).

Key Context Action
ArrowLeft / ArrowRight (vertical); ArrowUp / ArrowDown (horizontal) Mark focused Previous / next data point (category) in the same series; Left/Right are mirrored in RTL.
ArrowUp / ArrowDown (vertical); ArrowLeft / ArrowRight (horizontal) Mark focused, more than one visible series Same category in the previous / next visible series (nearest point when missing).
Home / End Mark focused First / last point of the series.
PageUp / PageDown Mark focused Ten points back / forward.
Escape Tooltip visible Hides the tooltip without moving focus (WCAG 1.4.13); it returns on the next move.
Tab / Shift+Tab Any Legend buttons, then one tab stop for the plot (the active mark), then the Show data table button and table region.
Enter / Space Legend button Shows or hides the series (native button).
Element Role
svg.aui-chart__svg group with aria-roledescription (localized chart type), named by the title
data marks (points, bars, slices) img with an aria-label: category/x, series, formatted value
legend list (ul) named “Legend”; entries are toggle buttons (aria-pressed)
data table table (native) with caption, column headers, and row headers; wide tables scroll in a focusable region
axes, lines, textures, value labels, tooltip aria-hidden (decorative duplicates of the accessible data)
Attribute Element Value
aria-labelledby svg id of the visible (or visually hidden) title
aria-describedby svg description id (when provided) and the generated summary id
aria-roledescription svg Localized chart type, for example “line chart”
aria-label each mark Localized “{x}, {series}: {value}” (pie: “{label}: {value} ({percent})”)
tabindex active mark 0 on exactly one mark (roving); other marks have none
aria-pressed legend button true while the series is visible
aria-expanded / aria-controls Show data table button Table open state and the table region id

Roving focus: one mark is in the tab sequence and remembers the last visited data point, also across re-renders (resize, update). Toggling a legend entry keeps focus on its button; toggling the table keeps focus on the table button.

Criterion Level Note
1.1.1 Non-text Content A
1.3.1 Info and Relationships A
1.4.1 Use of Color A
1.4.3 Contrast (Minimum) AA
1.4.10 Reflow AA
1.4.11 Non-text Contrast AA
1.4.13 Content on Hover or Focus AA
2.1.1 Keyboard A
2.4.3 Focus Order A
2.4.7 Focus Visible AA
4.1.2 Name, Role, Value A

Automated test results: Accessibility and compliance.

  • The generated summary lists the chart type, series and point counts, axis ranges, per-series minimum and maximum with their positions, the overall trend, missing values, and hidden series.
  • Meaning never depends on color alone: marker shapes, dash patterns, and textures (patterns option), plus legend keys that repeat them.
  • Forced colors: series use CanvasText and keep shapes, dashes, and textures; focus uses Highlight.
  • No animation: nothing moves on render; hover and focus emphasis transitions are removed under prefers-reduced-motion and animation: none.
  • Bars are separated by a surface-colored stroke, so adjacent (stacked) segments never depend on the contrast between two series colors.
  • Hovering a category shows every visible series and, when stacked, the total.
  • Manual screen-reader verification (NVDA, JAWS, VoiceOver, TalkBack) is pending.
  • aria-roledescription support varies; screen readers without it announce “group”.

default, empty, all series hidden, series hidden, bar focused (tooltip), category hovered, table open; orientation vertical | horizontal; layout grouped | stacked.

From Trigger To
any legend button series hidden or shown; aui-series-toggle; domain rescales
plot not focused Tab active bar focused, tooltip shown
bar focused arrow keys, Home, End, PageUp, PageDown another bar focused
tooltip visible Escape tooltip hidden
table closed Show data table table shown
  • Bars are separated by a color-surface stroke, so stacked segments never depend on contrast between two series colors.
  • Textures are the non-color cue for series; keep patterns on for grouped or stacked series.
  • Forced colors: bars use CanvasText with Canvas textures; focus and hover use Highlight.
  • No animation. Manual screen-reader verification is pending.

Width follows the container; category labels are truncated or thinned; horizontal charts reserve at most 40% of the width for labels. Reflows at 320 CSS px.

Vertical charts mirror the category axis; horizontal bars grow leftward from a right-hand zero line; axis labels move to the right; ArrowLeft/ArrowRight swap.

Series use color-chart-1..8 (3:1 against surface, background, and sunken surfaces in all themes). Gridlines color-chart-grid, axes color-chart-axis, labels color-text-muted.

configureAbsoluteUI({ components: { barChart: { valueLabels: true, legend: 'show' } } });

Instance options override global and theme defaults. All options are dynamic.

Not applicable (categories are text).

All text uses textContent; SVG uses createElementNS; colors are classes; texture fills reference per-instance pattern ids through the fill attribute. No innerHTML or style attributes.

No persistence, network access, or telemetry.

Budget: create with 50 categories x 4 series under 30 ms including the first render (e2e performance test, median of 5).

Up to about 200 bars (each is one focusable node plus one texture overlay). Aggregate larger data first or use a Data Table.

  • Empty categories or series: “No data”; every series hidden: “All series are hidden”.
  • Missing values: no bar, “No value” in the table; stacked totals treat them as 0.
  • Negative values: grouped bars grow below zero; stacked positives and negatives stack separately.
  • A fixed valueAxis domain clips bars at its edges.
  • Long category labels are truncated with an ellipsis; the full text stays in bar labels, tooltip, and table.
Code Category Cause
BAR_CHART_OPTIONS configuration Missing label; categories not strings; duplicate series ids; values length differs from categories; invalid orientation, layout, or axis options.
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION configuration Invalid or unknown configuration.

A failed construction leaves the host untouched.

  • One value per category per series.
  • Stacked value labels are printed only inside segments that fit them.
  • Manual screen-reader verification is pending.
  • 100% stacked, waterfall, bullet, and combo charts.
  • Logarithmic or broken axes; zoom, selection, export.
  • HTML in labels.