āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/components/chart.md ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
**Note:**We're working on upgrading to Recharts v3. In the meantime, if you'd like to start testing v3, see the code in the commenthere. We'll have an official release soon.
Bar Chart - InteractiveShowing total visitors for the last 3 monthsDesktop24,828Mobile25,010[data-chart=chart-R_141qanpfknqbplb] { --color-desktop: var(--chart-2); --color-mobile: var(--chart-1); } .dark [data-chart=chart-R_141qanpfknqbplb] { --color-desktop: var(--chart-2); --color-mobile: var(--chart-1); }Apr 2Apr 12Apr 23May 4May 15May 27Jun 7Jun 17Jun 29
IntroducingCharts. A collection of chart components that you can copy and paste into your apps.
Charts are designed to look great out of the box. They work well with the other components and are fully customizable to fit your project.
We useRechartsunder the hood.
We designed thechartcomponent with composition in mind.You build your charts using Recharts components and only bring in custom components, such asChartTooltip, when and where you need it.
import { Bar, BarChart } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/charts"
export function MyChart() {
return (
<ChartContainer>
<BarChart data={data}>
<Bar dataKey="value" />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>
)
}
We do not wrap Recharts. This means you're not locked into an abstraction. When a new Recharts version is released, you can follow the official upgrade path to upgrade your charts.
The components are yours.
Note:If you are using charts withReact 19or theNext.js 15, see the notehere. CLIManual
chart.tsxpnpm dlx shadcn@latest add chart
app/globals.css
@layer base {
:root {
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
}
}
Let's build your first chart. We'll build a bar chart, add a grid, axis, tooltip and legend.
The following data represents the number of desktop and mobile users for each month.
**Note:**Your data can be in any shape. You are not limited to the shape of the data below. Use thedataKeyprop to map your data to the chart.
components/example-chart.tsx
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
The chart config holds configuration for the chart. This is where you place human-readable strings, such as labels, icons and color tokens for theming. components/example-chart.tsx
import { type ChartConfig } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
You can now build your chart using Recharts components.
**Important:**Remember to set amin-h-[VALUE]on theChartContainercomponent. This is required for the chart be responsive.
Expandcomponents/example-chart.tsxCopy
"use client"
import { Bar, BarChart } from "recharts"
import { ChartConfig, ChartContainer } from "@/components/ui/chart"
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
export function Component() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
)
}
Expand [data-chart=chart-R_3ggqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; } .dark [data-chart=chart-R_3ggqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; }Copy
"use client"
import { Bar, BarChart } from "recharts"
import { ChartConfig, ChartContainer } from "@/components/ui/chart"
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
export function Component() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
)
}
Let's add a grid to the chart.
CartesianGridcomponent.import { Bar, BarChart, CartesianGrid } from "recharts"
CartesianGridcomponent to your chart.<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
[data-chart=chart-R_1kjqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; } .dark [data-chart=chart-R_1kjqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; }Copy
"use client"
import { Bar, BarChart, CartesianGrid } from "recharts"
import { ChartConfig, ChartContainer } from "@/components/ui/chart"
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
export function Component() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
)
}
To add an x-axis to the chart, we'll use theXAxiscomponent.
XAxiscomponent.import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
XAxiscomponent to your chart.<ChartContainer config={chartConfig} className="h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value) => value.slice(0, 3)}
/>
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
[data-chart=chart-R_1kmqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; } .dark [data-chart=chart-R_1kmqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; }JanFebMarAprMayJunCopy
"use client"
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
import { ChartConfig, ChartContainer } from "@/components/ui/chart"
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
export function Component() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value) => value.slice(0, 3)}
/>
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
)
}
So far we've only used components from Recharts. They look great out of the box thanks to some customization in thechartcomponent.
To add a tooltip, we'll use the customChartTooltipandChartTooltipContentcomponents fromchart.
ChartTooltipandChartTooltipContentcomponents.import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
<ChartContainer config={chartConfig} className="h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value) => value.slice(0, 3)}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
[data-chart=chart-R_1kqqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; } .dark [data-chart=chart-R_1kqqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; }JanFebMarAprMayJunCopy
"use client"
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
import {
ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
export function Component() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value) => value.slice(0, 3)}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
)
}
Hover to see the tooltips. Easy, right? Two components, and we've got a beautiful tooltip.
We'll do the same for the legend. We'll use theChartLegendandChartLegendContentcomponents fromchart.
ChartLegendandChartLegendContentcomponents.import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"
<ChartContainer config={chartConfig} className="h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value) => value.slice(0, 3)}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
[data-chart=chart-R_1ktqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; } .dark [data-chart=chart-R_1ktqanpfknqbplb] { --color-desktop: #2563eb; --color-mobile: #60a5fa; }JanFebMarAprMayJunDesktopMobileCopy
"use client"
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
import {
ChartConfig,
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
export function Component() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value) => value.slice(0, 3)}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
)
}
Done. You've built your first chart! What's next?
The chart config is where you define the labels, icons and colors for a chart.
It is intentionally decoupled from chart data.
This allows you to share config and color tokens between charts. It can also works independently for cases where your data or color tokens live remotely or in a different format.
import { Monitor } from "lucide-react"
import { type ChartConfig } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
icon: Monitor,
// A color like 'hsl(220, 98%, 61%)' or 'var(--color-name)'
color: "#2563eb",
// OR a theme object with 'light' and 'dark' keys
theme: {
light: "#2563eb",
dark: "#dc2626",
},
},
} satisfies ChartConfig
Charts has built-in support for theming. You can use css variables (recommended) or color values in any color format, such as hex, hsl or oklch.
app/globals.css
@layer base {
:root {
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
}
.dark: {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
}
}
chartConfigconst chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig
You can also define your colors directly in the chart config. Use the color format you prefer.
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
} satisfies ChartConfig
To use the theme colors in your chart, reference the colors using the formatvar(--color-KEY).
<Bar dataKey="desktop" fill="var(--color-desktop)" />
const chartData = [
{ browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
<LabelList className="fill-[--color-desktop]" />
A chart tooltip contains a label, name, indicator and value. You can use a combination of these to customize your tooltip.
LabelPage ViewsDesktop186Mobile****80NameChrome1,286Firefox****1,000Page ViewsDesktop****12,486IndicatorChrome****1,286
You can turn on/off any of these using thehideLabel,hideIndicatorprops and customize the indicator style using theindicatorprop.
UselabelKeyandnameKeyto use a custom key for the tooltip label and name.
Chart comes with the<ChartTooltip>and<ChartTooltipContent>components. You can use these two components to add custom tooltips to your chart.
import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
<ChartTooltip content={<ChartTooltipContent />} />
Use the following props to customize the tooltip.
TABLE:
| Prop | Type | Description | |
| labelKey | string | The config or data key to use for the label. | |
| nameKey | string | The config or data key to use for the name. | |
| indicator | dot``lineordashed | The indicator style for the tooltip. | |
| hideLabel | boolean | Whether to hide the label. | |
| hideIndicator | boolean | Whether to hide the indicator. | |
/TABLE
Colors are automatically referenced from the chart config.
To use a custom key for tooltip label and names, use thelabelKeyandnameKeyprops.
const chartData = [
{ browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
const chartConfig = {
visitors: {
label: "Total Visitors",
},
chrome: {
label: "Chrome",
color: "hsl(var(--chart-1))",
},
safari: {
label: "Safari",
color: "hsl(var(--chart-2))",
},
} satisfies ChartConfig
<ChartTooltip
content={<ChartTooltipContent labelKey="visitors" nameKey="browser" />}
/>
This will useTotal Visitorsfor label andChromeandSafarifor the tooltip names.
You can use the custom<ChartLegend>and<ChartLegendContent>components to add a legend to your chart.
import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"
<ChartLegend content={<ChartLegendContent />} />
Colors are automatically referenced from the chart config.
To use a custom key for legend names, use thenameKeyprop.
const chartData = [
{ browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
const chartConfig = {
chrome: {
label: "Chrome",
color: "hsl(var(--chart-1))",
},
safari: {
label: "Safari",
color: "hsl(var(--chart-2))",
},
} satisfies ChartConfig
<ChartLegend content={<ChartLegendContent nameKey="browser" />} />
This will useChromeandSafarifor the legend names.
You can turn on theaccessibilityLayerprop to add an accessible layer to your chart.
This prop adds keyboard access and screen reader support to your charts.
<LineChart accessibilityLayer />
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā