Charts
Line, bar, area and donut charts on the chart palette with thin strokes.
Playground
Recharts on the chart palette: thin strokes, horizontal gridlines only, 11px muted axis text and a tooltip that looks like every other popover. Controls that do not apply to the chosen type are hidden.
- New business
- Expansion
Props
1import { Area, AreaChart, CartesianGrid, Tooltip, XAxis, YAxis } from "recharts"2import { ChartContainer, type ChartConfig } from "@/components/ui/chart"3import { ChartTip, Legend } from "./chart-kit"45const config = {6 newBusiness: { label: "New business", color: "var(--chart-1)" },7 expansion: { label: "Expansion", color: "var(--chart-2)" },8} satisfies ChartConfig910<Legend items={series} />11<ChartContainer config={config} className="aspect-auto h-64 w-full">12 <AreaChart data={revenue} margin={{ top: 8, right: 8, left: 0 }}>13 <defs>{/* one vertical linearGradient per series, 24% → 2% opacity */}</defs>14 <CartesianGrid vertical={false} stroke="var(--border)" />15 <XAxis dataKey="month" tickLine={false} axisLine={false} tick={{ fontSize: 11 }} />16 <YAxis tickLine={false} axisLine={false} width={44} tick={{ fontSize: 11 }} />17 <Tooltip content={<ChartTip />} />18 <Area dataKey="newBusiness" type="monotone" stroke="var(--color-newBusiness)" fill="url(#fill-newBusiness)" strokeWidth={1.5} />19 <Area dataKey="expansion" type="monotone" stroke="var(--color-expansion)" fill="url(#fill-expansion)" strokeWidth={1.5} />20 </AreaChart>21</ChartContainer>States
Charts are data views, so their states are about the data: fetching, paused, failed and fresh. Every state keeps the panel's footprint so the layout never jumps.
- Revenue$2.21MDefault
rest - Revenue$2.21MJun $177kHover
tooltip + cursor - Revenue$2.21MFocus
surface :focus-visible - Loading
aria-busy - RevenuePausedDisabled
paused source - Couldn't load revenueError
role=alert - Revenue$2.21MUpdated just nowSuccess
just refreshed
New business
Monthly, in thousands of dollars
Examples
A revenue overview composed from the same parts: KPI stat cards with sparklines, bars that switch between grouped and stacked, a donut with its total in the centre and a line against a dashed target.
Revenue
Up+12%$2.21M
vs Oct 2024 – Sep 2025
New deals
Up+8%184
closed won this year
Win rate
Down−2.1 pts31%
of qualified deals
Avg. deal size
Up+4%$12,020
closed won, trailing 90 days
Deals won by region
Last seven weeks
- Americas
- EMEA
- APAC
Open pipeline
By stage, in thousands of dollars
- Qualified$420k38%
- Proposal$310k28%
- Negotiation$240k22%
- Verbal yes$130k12%
New business vs target
Monthly, Oct 2025 to Sep 2026
- New business
- Target $80k
Keyboard
- Focus the chart surface
- Tab
- Move the tooltip between data points
- ←or→
- Leave the chart
- Tab
Semantics and ARIA
- Each chart sits in a
<figure>with anaria-labeland a visually hidden<figcaption>that states the takeaway, not just the chart type. - Recharts' accessibility layer makes the surface focusable and lets arrow keys walk the tooltip through the points.
- Colour is never the only cue: series are labelled in the legend and the tooltip, deltas carry an arrow and a hidden "Up" or "Down", and targets are dashed.
- Loading sets
aria-busyon the panel, the empty state offers a next step, and a failed load is announced withrole="alert"and a retry button. - Entry animations are turned off when the user prefers reduced motion.