Chart
A Chart shows users data that is plotted with Recharts, with Summit’s colors, tooltip, and legend.
When to Use
- as a line chart, for a trend over time, such as revenue by month against last year
- as a stacked area chart, for the parts of a total over time, such as billable and internal hours
- as a grouped bar chart, to compare two series category by category
- as a donut chart, for the shares of one total, such as revenue by client
When Not to Use
- for exact values that users look up or compare row by row (use a Table)
- for one figure, like “Outstanding” (use a Card with the figure as its title)
- for how far one task has come (use the Progress component)
- for more than five series (use a Table)
Anatomy
Recharts renders the chart type, the series, the axes, and the grid. Summit provides the container, the tooltip, and the legend.
Chart
| Element | Usage |
|---|---|
| Container | Required |
| Grid | Optional |
| Axis | Optional |
| Series | Required |
| Legend | Optional |
Tooltip
| Element | Usage |
|---|---|
| Label | Optional |
| Indicator | Optional |
| Value | Required |
| Series name | Required |
The tooltip appears next to the point that is under the pointer or that users reached with the arrow keys.
Behavior
ChartContainer wraps the chart in Recharts’ ResponsiveContainer and declares the color variables.
Size
By default, ChartContainer is as wide as its container and has a ratio of 16 to 9. To replace the ratio, pass a class. For example, aspect-auto h-64 w-full sets a fixed height, and the donut sets aspect-square. Recharts measures the container and redraws the chart when its size changes. Until Recharts has measured the container, as on the server, the chart is drawn at initialDimension, which is 320 by 200px by default.
Colors
ChartContainer declares a variable for each key of config that has a color: for example, current becomes --color-current. Use the variable in the fill or the stroke of a series. Use chart-1 for the first series, chart-2 for the second, and continue in order. See Color for the chart colors.
To set a light and a dark value, pass theme in place of color. The chart colors already change with the theme, so color: 'var(--chart-1)' doesn’t need theme.
Tooltip Content
The tooltip shows the category, and then one row for each series: an indicator, the label of the series from config, and the value. A number is formatted with toLocaleString(), so 11200 is shown as “11,200” in English.
To change the mark next to each series, set indicator.
| Indicator | Mark |
|---|---|
dot | A square |
line | A bar as tall as the row |
dashed | A dashed line, as tall as the row |
The previews set cursor={false}, which removes the line or the band that Recharts shows at the active point.
Legend
ChartLegendContent shows a swatch and the label of each series. If a series has no label, its swatch has no name.
label in config for every series.label is missing, the legend shows two swatches with no names, so users can’t tell which series is which year.By default, Recharts sorts the legend by the name of each series, which is its dataKey unless the series sets name. To keep the order in which the series are written, set itemSorter={null} on ChartLegend, as the previews do.
Content
| String | Rule | Example | Counterexample |
|---|---|---|---|
| Series label | Use the name that users know the series by, in sentence case | “Billable” | “billable_hours” |
| Axis tick | Shorten a large number and keep its unit | “$15k” | “15000” |
Accessibility
Recharts renders a chart as one svg. Its accessibilityLayer, which is on by default from Recharts 3, adds that svg to the tab order and allows users to move the tooltip with the arrow keys.
Keyboard
| Key | Result |
|---|---|
Tab | Moves focus to the chart and opens the tooltip on the first point |
ArrowRight | Moves the tooltip to the next point and stops at the last |
ArrowLeft | Moves the tooltip to the previous point |
Enter | Hides the tooltip or shows it again |
Escape | Hides the tooltip |
When users press Tab again, focus moves out of the chart, and the tooltip closes. In a donut chart, no key opens the tooltip.
According to the Recharts documentation, a screen reader has to pass these keys through to the chart: JAWS and NVDA do so for role="application", and VoiceOver does so when Quick Nav is off.
Requirements
A Chart needs a name and a text alternative for its data so that screen reader users can get the figures. To provide
the name, pass title to the Recharts chart, which renders a title element in the svg. To provide the
alternative, show the figures in a Table or a sentence next to the Chart, as WCAG 2.2 SC 1.1.1 Non-text Content requires.
Two series differ by color alone, so users who can’t tell the two colors apart can’t tell the series apart. If their lines cross, add a second sign to one of them, such as strokeDasharray="4 4" on last year’s line.
Installation
npx shadcn@latest add @summit/chartUsage
Recharts renders the chart, so import the chart type, the series, the axes, and the grid from recharts. In config, set the name and the color of each series.
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from '@/components/ui/chart';
import type { ChartConfig } from '@/components/ui/chart';
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from 'recharts';
const revenue = [
{ month: 'Sep', current: 16373, previous: 13100 },
{ month: 'Oct', current: 18420, previous: 14250 },
];
const config = {
current: { label: '2026', color: 'var(--chart-1)' },
previous: { label: '2025', color: 'var(--chart-2)' },
} satisfies ChartConfig;
<ChartContainer config={config}>
<BarChart data={revenue} title="Revenue by month, 2025 and 2026">
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
<YAxis tickLine={false} axisLine={false} tickMargin={8} width={48} />
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
<Bar dataKey="previous" fill="var(--color-previous)" radius={4} isAnimationActive={false} />
<Bar dataKey="current" fill="var(--color-current)" radius={4} isAnimationActive={false} />
<ChartLegend itemSorter={null} content={<ChartLegendContent />} />
</BarChart>
</ChartContainer>;Set the Size
To replace the 16 to 9 ratio, pass a className to ChartContainer.
<ChartContainer config={config} className="aspect-auto h-64 w-full">
<BarChart data={revenue} />
</ChartContainer>Format the Axis
To format the ticks of a Recharts axis, pass a function that returns the text of a tick to tickFormatter.
<YAxis tickFormatter={(value: number) => `$${value / 1000}k`} />Change the Tooltip
To change the tooltip, set indicator, hideLabel, or hideIndicator on ChartTooltipContent.
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" hideLabel />} />Color Each Slice of a Donut
Add a key to config for each slice, set the fill of each row to its variable, and pass the field that contains the key as nameKey.
import { Pie, PieChart } from 'recharts';
const clients = [
{ client: 'brume', revenue: 7703, fill: 'var(--color-brume)' },
{ client: 'kite', revenue: 5400, fill: 'var(--color-kite)' },
];
const config = {
brume: { label: 'Atelier Brume', color: 'var(--chart-1)' },
kite: { label: 'Paper Kite Films', color: 'var(--chart-2)' },
} satisfies ChartConfig;
<ChartContainer config={config} className="mx-auto aspect-square max-w-sm">
<PieChart>
<ChartTooltip cursor={false} content={<ChartTooltipContent nameKey="client" />} />
<Pie data={clients} dataKey="revenue" nameKey="client" innerRadius="58%" outerRadius="80%" />
<ChartLegend itemSorter={null} content={<ChartLegendContent nameKey="client" />} />
</PieChart>
</ChartContainer>;API Reference
ChartContainer renders ChartStyle, so you don’t need to add ChartStyle to a chart.
ChartContainer
| Prop | Type | Default | Description |
|---|---|---|---|
config | ChartConfig | Required | The label, the icon, and the color of each series |
children | A Recharts chart | Required | The chart to size |
initialDimension | { width: number; height: number } | { width: 320, height: 200 } | The size of the chart before Recharts has measured its container |
id | string | A generated id | The suffix of data-chart, which scopes the color variables |
Other props are passed to the div.
ChartConfig
A key of config is the dataKey of a series, or the value of the field that nameKey names.
| Field | Type | Description |
|---|---|---|
label | ReactNode | The name in the tooltip and the legend |
icon | A component | Replaces the indicator in the tooltip and the swatch in the legend |
color | string | The value of --color-<key> |
theme | { light: string; dark: string } | The value of --color-<key> in each theme, in place of color |
ChartTooltipContent
| Prop | Type | Default | Description |
|---|---|---|---|
indicator | 'dot' | 'line' | 'dashed' | 'dot' | The mark next to each series |
hideLabel | boolean | false | Removes the category at the top |
hideIndicator | boolean | false | Removes the mark next to each series |
nameKey | string | None | The field whose value selects a row’s entry in config |
labelKey | string | None | The key in config whose label is shown at the top |
labelFormatter | A function | None | Returns the content of the label |
formatter | A function | None | Returns the content of a row, in place of the indicator, name, and value |
color | string | None | One color for every indicator |
labelClassName | string | None | Classes for the label |
See the Recharts Tooltip documentation for cursor, defaultIndex, and trigger on ChartTooltip.
ChartLegendContent
| Prop | Type | Default | Description |
|---|---|---|---|
hideIcon | boolean | false | Shows the swatch when config sets an icon for the series |
nameKey | string | None | The field whose value selects an entry in config |
verticalAlign | 'top' | 'bottom' | 'bottom' | Adds padding under the legend at 'top', or over it at 'bottom' |
See the Recharts Legend documentation for itemSorter on ChartLegend.