pnpm dlx shadcn@latest add https://herocn.dev/r/chart.jsonWe use Recharts under the hood.
We designed the chart component with composition in mind. You build your charts using Recharts components and only bring in custom components, such as ChartTooltip, when and where you need it.
import { Bar, BarChart } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
function MyChart() {
return (
<ChartContainer config={chartConfig}>
<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.
Use the following composition to build a Chart:
ChartContainer
├── ChartStyle (injects CSS custom properties)
├── ChartTooltip
│ └── ChartTooltipContent
└── ChartLegend
└── ChartLegendContentLet's build your first chart. We'll build a bar chart, add a grid, axis, tooltip and legend.
Start by defining your chart data and config, then build the chart.
"use client";
import { Bar, BarChart } from "recharts";
import {
type 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: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig;
export function ChartBarDemo() {
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>
);
}
Import the CartesianGrid component from recharts and add it to your chart.
"use client";
import { Bar, BarChart, CartesianGrid } from "recharts";
import {
type 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: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig;
export function ChartBarDemoGrid() {
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>
);
}
Use the XAxis component to add an x-axis to your chart.
"use client";
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
import {
type 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: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig;
export function ChartBarDemoAxis() {
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>
);
}
Use the custom ChartTooltip and ChartTooltipContent components to add a tooltip.
"use client";
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
import {
type 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: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig;
export function ChartBarDemoTooltip() {
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>
);
}
Use the ChartLegend and ChartLegendContent components to add a legend.
"use client";
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
import {
type 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: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig;
export function ChartBarDemoLegend() {
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>
);
}
The chart config is where you define the labels, icons and colors for a chart.
import { Monitor } from "lucide-react"
import { type ChartConfig } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
icon: Monitor,
color: "var(--chart-1)",
theme: {
light: "var(--chart-1)",
dark: "var(--chart-3)",
},
},
} satisfies ChartConfigCharts have built-in support for theming. You can use CSS variables (recommended) or color values in any color format, such as hex, hsl or oklch.
Define your colors in your CSS file and reference them in the chart config:
@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);
}
}const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfigTo use the theme colors in your chart, reference the colors using the format var(--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.
You can turn on/off any of these using the hideLabel, hideIndicator props and customize the indicator style using the indicator prop.
Use labelKey and nameKey to use a custom key for the tooltip label and name.
Colors are automatically referenced from the chart config.
To use custom keys for the tooltip label and names, use labelKey and nameKey:
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: "var(--chart-1)",
},
safari: {
label: "Safari",
color: "var(--chart-2)",
},
} satisfies ChartConfig<ChartTooltip
content={<ChartTooltipContent labelKey="visitors" nameKey="browser" />}
/>You can use the custom <ChartLegend> and <ChartLegendContent> components to add a legend to your chart.
Colors are automatically referenced from the chart config.
To use custom keys for legend names, use the nameKey prop:
<ChartLegend content={<ChartLegendContent nameKey="browser" />} />You can turn on the accessibilityLayer prop on your Recharts chart to add keyboard access and screen reader support.
<BarChart accessibilityLayer />To enable RTL support, set dir="rtl" on the chart container and reverse the axis accordingly.
"use client";
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
import {
type Translations,
useTranslation,
} from "@/components/language-selector";
import {
type ChartConfig,
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
const translations: Translations = {
en: {
dir: "ltr",
values: {
january: "January",
february: "February",
march: "March",
april: "April",
may: "May",
june: "June",
desktop: "Desktop",
mobile: "Mobile",
},
},
ar: {
dir: "rtl",
values: {
january: "يناير",
february: "فبراير",
march: "مارس",
april: "أبريل",
may: "مايو",
june: "يونيو",
desktop: "سطح المكتب",
mobile: "الجوال",
},
},
he: {
dir: "rtl",
values: {
january: "ינואר",
february: "פברואר",
march: "מרץ",
april: "אפריל",
may: "מאי",
june: "יוני",
desktop: "מחשב",
mobile: "נייד",
},
},
};
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 },
];
export function ChartRtl() {
const { t, dir } = useTranslation(translations, "ar");
const chartConfig = {
desktop: {
label: t.desktop,
color: "var(--chart-2)",
},
mobile: {
label: t.mobile,
color: "var(--chart-1)",
},
} satisfies ChartConfig;
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid
vertical={false}
orientation={dir === "rtl" ? "right" : "left"}
/>
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value) =>
(t[value as keyof typeof t] as string).slice(0, 3)
}
reversed={dir === "rtl"}
/>
<ChartTooltip
content={
<ChartTooltipContent
labelFormatter={(value) => t[value as keyof typeof t] as string}
/>
}
labelClassName="w-32"
/>
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
);
}
The ChartContainer component wraps a Recharts chart and provides the chart config context.
| Prop | Type | Default |
|---|---|---|
| config* | ChartConfig | — |
| className | string | — |
| id | string | — |
| initialDimension | { width: number; height: number } | { width: 320, height: 200 } |
The ChartTooltip component is a wrapper around the Recharts Tooltip component.
| Prop | Type | Default |
|---|---|---|
| content | ReactElement | — |
The ChartTooltipContent component renders the tooltip with labels, indicators, and values.
| Prop | Type | Default |
|---|---|---|
| indicator | "dot" | "line" | "dashed" | "dot" |
| hideLabel | boolean | false |
| hideIndicator | boolean | false |
| labelKey | string | — |
| nameKey | string | — |
| labelFormatter | (value: unknown, payload: unknown[]) => ReactNode | — |
| formatter | (value: unknown, name: unknown, item: unknown, index: number, payload: unknown) => ReactNode | — |
| className | string | — |
The ChartLegend component is a wrapper around the Recharts Legend component.
| Prop | Type | Default |
|---|---|---|
| content | ReactElement | — |
The ChartLegendContent component renders the legend with color indicators and labels.
| Prop | Type | Default |
|---|---|---|
| nameKey | string | — |
| hideIcon | boolean | false |
| className | string | — |
| verticalAlign | "top" | "bottom" | "bottom" |
The ChartConfig type defines the configuration object for the chart.
| Prop | Type | Default |
|---|---|---|
| [key] | { label?: ReactNode; icon?: ComponentType; color?: string } | { label?: ReactNode; icon?: ComponentType; theme: { light: string; dark: string } } | — |
On This Page
InstallationUsageCompositionYour First ChartBasic bar chartAdd a GridAdd an AxisAdd a TooltipAdd a LegendChart ConfigThemingCSS VariablesUsing ColorsComponentsChart DataTailwindTooltipTooltip ColorsCustom KeysLegendCustom KeysAccessibilityRTLAPI ReferenceChartContainerChartTooltipChartTooltipContentChartLegendChartLegendContentChartConfig