Manual UI Templates BarChart

BarChart

elements man ui/templates/chart-bar

Vertical, horizontal, stacked and grouped bars with tooltip, legend and labels.

Example
import { BarChart } from "@elements/ui/chart-bar"; import type { ChartConfig } from "@elements/ui/chart"; const config: ChartConfig = { desktop: { label: "Desktop", color: "var(--chart-1)" }, mobile: { label: "Mobile", color: "var(--chart-2)" }, }; <BarChart data={rows} {config} x="month" /> <BarChart data={rows} {config} x="month" stack="normal" legend /> <BarChart data={rows} {config} x="month" orientation="horizontal" labels />

Parts

Part What it is
BarChart The template. One bar per category and series, drawn as server-rendered SVG.
.chart-bar-mark One bar (an SVG path). --series is its color; .is-active with activeBar.
.chart-bar-cursor The band behind the hovered category.
.chart-bar-background The track behind a bar, with background.
.chart The figure. Declares --color-<key> for each config entry; keeps a 16:9 box unless sized by class.
.chart-plot The focusable plot area holding the SVG; one tab stop.
.chart-tooltip The tooltip: heading, one row per item with swatch, name and value, optional footer.
.chart-legend The legend row; .chart-legend-item per series, a button with legend toggle.
.chart-table The data as a table, visually hidden unless showTable.

Attributes

Attribute Type Default Description
data Row[] (required) The rows: one per category.
config ChartConfig (required) The chart config: per data key a label, a color (any CSS color, usually var(--chart-N)) or a theme { light, dark }, and an optional icon; legendType and tooltipType; strokeDasharray and strokeOpacity dash and fade a line or an area's edge. Each key becomes --color-<key> on the chart.
x string (required) The category field.
series string[] [] The value fields to draw. Empty draws every config key that has numbers in the data, in config order.
orientation "vertical" | "horizontal" "vertical" Columns, or bars that run along the value axis with the categories down the side.
stack "none" | "normal" | "expand" | "sign" | "silhouette" | "wiggle" "none" Stack the series in one bar per category; expand fills each to 100%; sign stacks negatives below zero; silhouette centers each stack on zero, wiggle as a streamgraph.
reverseStackOrder boolean false Stack the last series first, so the first sits on top; the legend and tooltip keep series order.
radius number -1 Corner radius in px. -1 follows the theme (--chart-radius). A stack rounds only its outer ends.
barSize number 0 Fixed bar thickness in px; 0 computes it from the gaps.
maxBarSize number 0 Cap on the computed thickness; 0 is no cap.
barGap number 4 px between the bars of one category.
barCategoryGap number | string "10%" Space on each side of a category's bars: px, or a percent of the band.
categoryAxis boolean | { tickFormatter?: (value, index) => string; tickLine?: boolean; axisLine?: boolean; tickMargin?: number; tickCount?: number; domain?: [number | "auto" | "dataMin" | "dataMax", ...]; size?: number; showAll?: boolean; minTickGap?: number; orientation?: "left" | "right" | "top" | "bottom"; series?: string[]; key?: string; hide?: boolean; reversed?: boolean; angle?: number; label?: string | { value, offset? }; unit?: string; ticks?: (number | string)[]; allowDecimals?: boolean; allowDataOverflow?: boolean; niceTicks?: "auto" | "none"; interval?: number | "preserveEnd" | "preserveStart" | "preserveStartEnd" | "equidistantPreserveStart"; padding?: { left?, right?, top?, bottom? }; scale?: "linear" | "log" | "sqrt"; type?: "category" | "number"; mirror?: boolean; tickSize?: number; tick?: boolean; includeHidden?: boolean; allowDuplicatedCategory?: boolean } | AxisOptions[] true The axis that names the categories (x for columns, y for horizontal bars). A list draws several, such as a second on the other side showing another field (key, orientation). Options: reversed, angle, label, interval, padding, type number, tickSize, tick, allowDuplicatedCategory.
valueAxis boolean | { tickFormatter?: (value, index) => string; tickLine?: boolean; axisLine?: boolean; tickMargin?: number; tickCount?: number; domain?: [number | "auto" | "dataMin" | "dataMax", ...]; size?: number; showAll?: boolean; minTickGap?: number; orientation?: "left" | "right" | "top" | "bottom"; series?: string[]; key?: string; hide?: boolean; reversed?: boolean; angle?: number; label?: string | { value, offset? }; unit?: string; ticks?: (number | string)[]; allowDecimals?: boolean; allowDataOverflow?: boolean; niceTicks?: "auto" | "none"; interval?: number | "preserveEnd" | "preserveStart" | "preserveStartEnd" | "equidistantPreserveStart"; padding?: { left?, right?, top?, bottom? }; scale?: "linear" | "log" | "sqrt"; type?: "category" | "number"; mirror?: boolean; tickSize?: number; tick?: boolean; includeHidden?: boolean; allowDuplicatedCategory?: boolean } | AxisOptions[] false The numeric axis. domain and tickCount shape its scale. A list adds axes, each scaling the series it names, on the other side with orientation. Options: reversed, unit, ticks, allowDecimals, allowDataOverflow, niceTicks, scale (linear, log, sqrt), mirror, label, includeHidden.
grid boolean | { horizontal?: boolean; vertical?: boolean; strokeDasharray?: string; fill?: string; fillOpacity?: number; horizontalFill?: string[]; verticalFill?: string[]; horizontalValues?: (number | string)[]; verticalValues?: (number | string)[]; horizontalPoints?: number[]; verticalPoints?: number[]; horizontalCoordinatesGenerator?: (plot) => number[]; verticalCoordinatesGenerator?: (plot) => number[]; syncWithTicks?: boolean } true The grid: horizontal lines at the value ticks by default, vertical on request; dashed lines, a background fill and stripes between the lines; lines at given values or pixels; syncWithTicks keeps the category lines to the ticks that show.
labels boolean | LabelOptions | LabelOptions[] (LabelOptions: { position?, key?, series?, formatter?: (value, row) => string, offset?, color?, class? }) false Value labels: a value or another field at top, bottom, left, right, center, or inside (insideLeft, insideRight, insideTop, insideBottom). Pass an array for several lists; each list takes its own color and class.
tooltip boolean | { indicator?: "dot" | "line" | "dashed"; hideLabel?: boolean; hideIndicator?: boolean; color?: string; labelKey?: string; nameKey?: string; labelFormatter?: (label, row) => string; formatter?: (value, key, row) => string; footer?: (row) => string; footerLabel?: string; unit?: string; defaultIndex?: number; cursor?: boolean; filterNull?: boolean; trigger?: "hover" | "click"; active?: boolean; position?: { x?, y? }; reverseDirection?: { x?, y? }; itemSorter?: "name" | "value" | "key" | (item) => number | string; includeHidden?: boolean; animationDuration?: number; animationEasing?: string | (t) => number; isAnimationActive?: boolean } true The tooltip: false turns it off; an object sets the indicator, hides the heading or swatches, takes names and headings from other keys, formats them, adds a footer line, or turns off the hover cursor. More options: trigger click (a click shows it and it stays), active (always or never shown), position (a fixed spot), reverseDirection, itemSorter and includeHidden.
legend boolean | { position?: "top" | "bottom" | "left" | "right" | "center" | "insideTop" | "insideBottom" | "insideLeft" | "insideRight" | "insideTopLeft" | "insideTopRight" | "insideBottomLeft" | "insideBottomRight" | { x, y }; offset?: number; iconSize?: number; verticalAlign?: "top" | "middle" | "bottom"; align?: "left" | "center" | "right"; layout?: "horizontal" | "vertical"; iconType?: "square" | "rect" | "circle" | "line" | "plainline" | "diamond" | "triangle" | "cross" | "star" | "wye" | "none"; formatter?: (name, key) => string; itemSorter?: "name" | "key" | (item) => number | string; hideIcon?: boolean; nameKey?: string; toggle?: boolean } false The legend: above or below the plot, or beside it with verticalAlign middle; position puts it beside the plot, over it at an inside spot or the center, or at a point, offset moves it, iconSize sizes the swatch; align, a vertical layout, the swatch shape (iconType), a name formatter and an itemSorter; names from another key; toggle makes each item a button that hides its series.
margin { top?, right?, bottom?, left? } {} Space around the plot in px; each side defaults to 5.
active number (two-way) -1 The active item index. Hover and the arrow keys move it; when the pointer leaves it returns to the value it had.
activeBar boolean false Outline the active bar: dashed stroke, lighter fill.
background boolean false A track behind each bar the full length of the plot.
minPointSize number 0 Least length in px of a bar that has a value, so tiny values stay visible.
hidden string[] (two-way) [] Series keys not drawn. They stay in the legend, where a toggle legend shows them again.
label string "Bar chart" The chart's accessible name and its table's caption.
animate boolean true Marks enter with motion and move to new values. Off under prefers-reduced-motion.
animation { begin?: number; duration?: number; easing?: string | (t) => number; matchBy?: "index" | "append" | (item, index) => key; interpolate?: (items, t) => items; newValues?: boolean } {} Times the entry and the move to new data. matchBy pairs old and new items by position or by a key, matchByDataKey(field) from the chart package; interpolate draws every frame of a change from the paired items and the eased time; newValues false shows an unpaired new point at once.
showTable boolean false Show the chart's data table under the plot. The table is always in the accessibility tree.
class string "" Classes on the figure. Size the chart here: it keeps a 16:9 box unless given a height or aspect-ratio.
attrs Record<string, string | number | boolean | undefined> {} Any other attributes for the figure: id, data-testid, aria-*.
syncId string "" Charts with the same syncId share the active item and its tooltip.
syncMethod "index" | "value" "index" Match the shared item by position, or by its category or name.
onActiveChange (index: number) => void () => {} The user moved the active item (hover, leave or keys).
onItemClick (index: number) => void () => {} A click or tap on an item, with its index.
onHiddenChange (hidden: string[]) => void () => {} A legend toggle changed hidden.

Keyboard

Keys Action
Tab Focuses the chart (one tab stop) and shows the tooltip for the item the keys last reached, else the active item, else the first.
ArrowRight / ArrowDown Next item. The same under dir=rtl: the plot is not mirrored, so keys follow the screen.
ArrowLeft / ArrowUp Previous item.
Home / End First and last item.
Escape Hides the tooltip. In a dialog, the dialog stays open until the next Escape.

Data attributes

Attribute Values On Description
data-chart "bar" | "line" | "area" | "pie" | "radar" | "radial" figure
data-state "open" | "closed" .chart-tooltip
data-index the item index .chart-hit and pie, radial marks
data-series the series key marks
data-resizing present while the chart redraws for a new size figure
data-entered present once the entry motion is over figure
aria-pressed true | false .chart-legend-item (toggle)
.is-horizontal class figure orientation horizontal

Accessibility

  • The plot is one tab stop: role=group, aria-roledescription=chart, named by label, described by the data table.
  • The SVG is aria-hidden; a screen reader gets the data from the table, which every chart renders.
  • Arrow keys move through the items and each move is announced in a polite live region, for example "February: Desktop 305, Mobile 200".
  • Identity is never color alone: a legend for two or more series and labels on the tooltip rows.
  • Legend toggles are buttons with aria-pressed.

See also