TanStack Charts

TanStack Charts draws from a chart definition: marks, scales and a tooltip. The kit's Chart paints it with your theme's chart colors, grid, axes and tooltip, in light and dark mode, compact mode and inside a ThemeScope.

LLMs

Code

Every chart in this section is 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.

Setup

Wrap your app in AntuikitProvider once. The charts read the theme from it, so they follow light and dark mode, compact mode and any ThemeScope around them without props of their own. Get started covers the rest of the setup.
import { AntuikitProvider } from "@/components/antuikit-provider"
export function Root() {
return (
<AntuikitProvider>
<App />
</AntuikitProvider>
)
}

Your first chart

A chart is a definition built with defineChart and passed to Chart. Build it outside the component, or in a useMemo when it depends on state, so it is not rebuilt on every render.
import { defineChart, lineY } from "@tanstack/charts"
import { scaleLinear } from "@tanstack/charts/scales/linear"
import { scalePoint } from "@tanstack/charts/scales/point"
import { tooltip } from "@tanstack/charts/tooltip"
import { Chart, seriesTooltip } from "@/components/ui/tanstack-chart"
const revenue = [
{ month: "January", revenue: 34 },
{ month: "February", revenue: 52 },
{ month: "March", revenue: 44 },
]
const definition = defineChart(
{
marks: [lineY(revenue, { x: "month", y: "revenue" })],
scales: {
x: { scale: scalePoint },
y: { scale: scaleLinear, grid: true },
},
},
{ focus: "group-x", tooltip: { use: tooltip, content: seriesTooltip } },
)
export function RevenueChart() {
return (
<Chart
definition={definition}
ariaLabel="Revenue by month, in thousands of dollars"
height={240}
/>
)
}
The chart fills its container's width, so give it a height. ariaLabel is required.

The definition

defineChart takes two arguments. The first says what to draw: the marks, the scales and the chart-wide settings such as color and margin. The second says how the chart behaves: focus, tooltip and keyboard.
defineChart(
{
marks: [/* what to draw */],
scales: {/* how values map to pixels */},
color: { domain: ["Desktop", "Mobile"] },
margin: { top: 8, right: 12, bottom: 28, left: 12 },
},
{
focus: "group-x",
tooltip: { use: tooltip, content: seriesTooltip },
keyboard: true,
},
)

Marks

A mark draws one shape per row, or one path per series. A chart is a list of marks drawn in order, so a later mark sits on top. Combine them for the chart you need: a line with dots, bars with value labels, an area with a rule at zero.
  • barY and barX: bars, grouped or stacked.
  • lineY and areaY: lines and filled areas.
  • dot: points, for scatter plots and markers.
  • text: labels placed in data space.
  • ruleX and ruleY: reference lines, such as a target or zero.

Channels

A mark's options map your rows to what it draws. Pass a field name, or a function of the row for a value you compute. TanStack checks field names against your row type.
lineY(rows, {
x: "month", // position along the axis
y: (row) => row.revenue / 1000,
z: "region", // one line per region
color: "region", // the color scale's input
key: (row) => `${row.month}:${row.region}`, // a stable id per point
})
  • x and y are positions, read by the scales of the same name.
  • z splits the rows into series. color picks the color, and splits the rows too when z is not set.
  • key gives each mark an identity, so it animates and keeps focus when the data changes.

Scales

A scale turns values into pixels. Pass a factory, and TanStack fits the domain to the data, or an instance with a fixed domain. Each scale also carries its axis and grid.
import { scaleBand } from "@tanstack/charts/scales/band"
import { scaleLinear } from "@tanstack/charts/scales/linear"
import { scaleUtc } from "d3-scale"
scales: {
x: { scale: () => scaleBand<string>().paddingInner(0.2) },
y: { scale: scaleLinear().domain([0, 80]), grid: true, axis: { label: "Revenue" } },
}
// Dates, spaced by elapsed time.
x: { scale: scaleUtc }
  • scaleLinear for numbers, scaleBand for bars and scalePoint for evenly spaced categories. Import each from its own @tanstack/charts/scales/* path.
  • For time, log and other scales, add d3-scale to your project. TanStack takes its scales as they are.
  • The Axes and labels guideline covers baselines, ticks and number formats.

Which component

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

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" />
Palette props
Taken by Chart, RendererChart and CanvasChart. Rows marked antuikit in the Version column are added by the kit.

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="..." />

Where to go next