Bar

Bar charts compare values across categories, with one bar per item or several side by side or stacked.

LLMs

Code

Bar charts are drawn with TanStack Charts, through the kit's Chart components. They paint the chart with the theme's colors, grid and type, and add three palette props. The chart itself is a TanStack definition, written the way TanStack documents it.

Install

npx antuikit@latest init
npx antuikit@latest add tanstack-chart
The first command installs AntuikitProvider and the theme tokens. The second adds the chart components and TanStack Charts itself.

Your first bar chart

Describe the chart with defineChart, outside the component, and pass it to Chart. A bar is a barY mark: x names the category field and y the value field.
import { barY, defineChart } from "@tanstack/charts"
import { scaleBand } from "@tanstack/charts/scales/band"
import { scaleLinear } from "@tanstack/charts/scales/linear"
import { tooltip } from "@tanstack/charts/tooltip"
import { Chart, seriesTooltip } from "@/components/ui/tanstack-chart"
const visits = [
{ page: "Pricing", visits: 1840 },
{ page: "Docs", visits: 1320 },
{ page: "Blog", visits: 760 },
]
const definition = defineChart(
{
marks: [barY(visits, { x: "page", y: "visits", radius: { end: 6 } })],
scales: {
x: { scale: () => scaleBand<string>().paddingInner(0.2) },
y: { scale: scaleLinear, grid: true },
},
},
{
focus: "group-x",
tooltip: { use: tooltip, content: seriesTooltip },
},
)
export function VisitsChart() {
return (
<Chart
definition={definition}
ariaLabel="Visits by page, last 30 days"
height={240}
/>
)
}
The chart fills its container's width, so give it a height. ariaLabel is required.

Which component

All three take the same definition and the same palette props.
Chart components

Vertical and horizontal

barY draws vertical bars and barX horizontal ones. For barX, swap the channels: x is the value, y the category, and the band scale moves to y.
barX(visits, { x: "visits", y: "page" })

Several series

Put every series in one array and name the series field with z. Bars that share a category stack by default. To put them side by side, pass layout: group().
import { barY, group } from "@tanstack/charts"
barY(tickets, {
x: "month",
y: "tickets",
z: "status",
color: "status",
key: (row) => `${row.month}:${row.status}`,
layout: group({
scale: scaleBand<string>().domain(["Opened", "Closed"]),
}),
})
  • Give each bar a key that is unique across series, or bars in the same month share an identity and animate into each other.
  • Set color: { domain: [...] } on the definition to fix which series gets which color, so the colors stay put when a series is missing.
  • stack({ order }) sets which series sits at the bottom of a stack.

Sorting

Sort the band scale's domain, not only the rows. The domain decides the order on the axis, and several marks can share it.
const ranked = [...visits].sort((a, b) => b.visits - a.visits)
scales: {
x: { scale: () => scaleBand<string>().domain(ranked.map((row) => row.page)) },
}

Zero baseline

Keep zero in the value scale. If you set a domain yourself, start it at 0, or the bars lose the shared baseline the reader compares them against. For bars that float, such as a waterfall, pass explicit ends with y1 and y2 instead.

Colors

The chart takes the theme's chart colors without any setup. Change the palette on the chart itself, or paint one mark with fill and chartColors. The Color guideline covers which palette fits which data.
<Chart definition={definition} ariaLabel="..." palette="multi" />
// With palette="accent", series[0] is the accent and the next ones are grays.
barY(visits, {
x: "page",
y: "visits",
fill: (row) =>
row.page === "Pricing" ? chartColors.series[0] : chartColors.series[1],
})
Palette props
Taken by Chart, RendererChart and CanvasChart. Rows marked antuikit in the Version column are added by the kit.

Tooltip and focus

focus: "group-x" makes one category the unit of focus, so the tooltip lists every series in it. seriesTooltip from the kit formats that tooltip: the category as the title, then one row per series with its color and value. The same focus drives the keyboard, so pointer and keyboard users see the same tooltip.

Animation

Use RendererChart with TanStack's motion() renderer to animate marks in and between data updates. It skips the animation when the reader has asked for reduced motion.
import { motion } from "@tanstack/charts/motion"
import { RendererChart } from "@/components/ui/tanstack-chart"
const renderer = motion({ initial: "always" })
<RendererChart definition={definition} renderer={renderer} ariaLabel="..." />

API

The options a bar chart uses most. TanStack Charts' documentation has the full reference.
barY and barX