Chart
Composable chart primitives built on Recharts.
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/registry/base/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 default function ChartDemo() {
return (
<ChartContainer config={chartConfig} className="w-full max-w-md">
<BarChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value: string) => value.slice(0, 3)}
/>
<ChartTooltip cursor={false} 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>
);
}
Installation
npx shadcn@latest add https://sevenui.dev/r/chart.jsonUsage
import { Bar, BarChart } from "recharts";
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/components/ui/chart";
const chartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" },
} satisfies ChartConfig;
const chartData = [{ month: "January", desktop: 186 }];
<ChartContainer config={chartConfig} className="w-full max-w-md">
<BarChart data={chartData}>
<Bar dataKey="desktop" fill="var(--color-desktop)" />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>;
Examples
Line chart
import { CartesianGrid, Line, LineChart, XAxis } from "recharts";
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/registry/base/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 default function ChartLine() {
return (
<ChartContainer config={chartConfig} className="w-full max-w-md">
<LineChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
tickMargin={10}
axisLine={false}
tickFormatter={(value: string) => value.slice(0, 3)}
/>
<ChartTooltip content={<ChartTooltipContent hideLabel />} />
<Line
dataKey="desktop"
type="natural"
stroke="var(--color-desktop)"
strokeWidth={2}
dot={false}
/>
<Line
dataKey="mobile"
type="natural"
stroke="var(--color-mobile)"
strokeWidth={2}
dot={false}
/>
</LineChart>
</ChartContainer>
);
}
API reference
A thin wrapper over Recharts v3 (pinned to
^3.10.1) — charts compose from recharts primitives (BarChart,
LineChart, CartesianGrid, XAxis, and the rest) inside a
ChartContainer. We wrap the container, tooltip, and legend — not every
chart type — so any recharts component works inside. v2 snippets you find
online need porting to the v3 API.
ChartContainertakes aconfig: ChartConfigand renders recharts’ResponsiveContainerinside adata-chart-scopeddiv, plus an injected<style>tag (ChartStyle) that defines the series’ CSS variables.ChartConfigmaps each series key to alabel/iconand either a singlecoloror a per-themetheme: { light, dark }pair.- Series colors resolve as
var(--color-<key>)inside the container, scoped to that chart’sdata-chartid. Dark values apply under the.dark [data-chart=…]selector (the shadcn consumer convention). ChartTooltip/ChartLegendare direct re-exports of recharts’Tooltip/Legend;ChartTooltipContentandChartLegendContentare our styledcontentrenderers, wired up ascontent={<ChartTooltipContent />}.ChartTooltipContentacceptshideLabel,hideIndicator,indicator="line" | "dot" | "dashed",nameKey, andlabelKey, on top of recharts’ own tooltip content props.ChartLegendContentacceptshideIconandnameKey, on top of recharts’payload/verticalAlign.
v3 gotchas you’ll hit if you’ve used recharts v2:
- Type custom tooltip content against the root-exported
TooltipContentProps— notReact.ComponentProps<typeof Tooltip>, which is the v2 idiom and does not describe the v3 content-renderer props. - Legend items sort alphabetically by default; pass
itemSorter={null}onLegendto preserve series order. accessibilityLayerdefaults totruein v3 — you no longer need to pass it yourself.