Chart
Beautiful charts. Built using Recharts. Copy and paste into your apps. Built with Tailwind CSS. Copy-paste ready.
"use client";
import { Bar, BarChart } from "recharts";
import { type ChartConfig, ChartContainer } from "@/components/ui/chart";
const chartData = [
{ desktop: 186, mobile: 80, month: "January" },
{ desktop: 305, mobile: 200, month: "February" },
{ desktop: 237, mobile: 120, month: "March" },
{ desktop: 73, mobile: 190, month: "April" },
{ desktop: 209, mobile: 130, month: "May" },
{ desktop: 214, mobile: 140, month: "June" },
];
const chartConfig = {
desktop: {
color: "#2563eb",
label: "Desktop",
},
mobile: {
color: "#60a5fa",
label: "Mobile",
},
} satisfies ChartConfig;
export function ChartExample() {
return (
<ChartContainer className="min-h-50 w-full" config={chartConfig}>
<BarChart accessibilityLayer data={chartData}>
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
);
}
Installation
pnpm dlx shadcn@latest add @cnippet/chart
Usage
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
import type { ChartConfig } from "@/components/ui/chart"const chartConfig = {
desktop: {
color: "var(--chart-1)",
label: "Desktop",
},
} satisfies ChartConfig
export function MyChart() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
{/* Recharts component here */}
</ChartContainer>
)
}Examples
Multi-Series Bar Chart
Two data series displayed side-by-side as grouped bars. Colors are defined directly in chartConfig and resolved via CSS variables through ChartContainer.
"use client";
import { Bar, BarChart } from "recharts";
import { type ChartConfig, ChartContainer } from "@/components/ui/chart";
const chartData = [
{ desktop: 186, mobile: 80, month: "January" },
{ desktop: 305, mobile: 200, month: "February" },
{ desktop: 237, mobile: 120, month: "March" },
{ desktop: 73, mobile: 190, month: "April" },
{ desktop: 209, mobile: 130, month: "May" },
{ desktop: 214, mobile: 140, month: "June" },
];
const chartConfig = {
desktop: {
color: "#2563eb",
label: "Desktop",
},
mobile: {
color: "#60a5fa",
label: "Mobile",
},
} satisfies ChartConfig;
export function ChartExample() {
return (
<ChartContainer className="min-h-50 w-full" config={chartConfig}>
<BarChart accessibilityLayer data={chartData}>
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
);
}
Area Chart
A single-series area chart with a grid, X-axis labels, and a tooltip. Uses type="natural" for smooth curved lines and fillOpacity for the semi-transparent fill.
"use client";
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
export const description = "A simple area chart";
const chartData = [
{ desktop: 186, month: "January" },
{ desktop: 305, month: "February" },
{ desktop: 237, month: "March" },
{ desktop: 73, month: "April" },
{ desktop: 209, month: "May" },
{ desktop: 214, month: "June" },
];
const chartConfig = {
desktop: {
color: "var(--chart-1)",
label: "Desktop",
},
} satisfies ChartConfig;
export function ChartAreaDefault() {
return (
<ChartContainer className="min-h-50 w-full" config={chartConfig}>
<AreaChart
accessibilityLayer
data={chartData}
margin={{
left: 12,
right: 12,
}}
>
<CartesianGrid vertical={false} />
<XAxis
axisLine={false}
dataKey="month"
tickFormatter={(value) => value.slice(0, 3)}
tickLine={false}
tickMargin={8}
/>
<ChartTooltip
content={<ChartTooltipContent indicator="line" />}
cursor={false}
/>
<Area
dataKey="desktop"
fill="var(--color-desktop)"
fillOpacity={0.4}
stroke="var(--color-desktop)"
type="natural"
/>
</AreaChart>
</ChartContainer>
);
}
Bar Chart
A single-series bar chart with rounded corners, a Cartesian grid, abbreviated month labels on the X-axis, and a tooltip that hides the series label.
"use client";
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
export const description = "A bar chart";
const chartData = [
{ desktop: 186, month: "January" },
{ desktop: 305, month: "February" },
{ desktop: 237, month: "March" },
{ desktop: 73, month: "April" },
{ desktop: 209, month: "May" },
{ desktop: 214, month: "June" },
];
const chartConfig = {
desktop: {
color: "var(--chart-1)",
label: "Desktop",
},
} satisfies ChartConfig;
export function ChartBarDefault() {
return (
<ChartContainer className="min-h-50 w-full" config={chartConfig}>
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
axisLine={false}
dataKey="month"
tickFormatter={(value) => value.slice(0, 3)}
tickLine={false}
tickMargin={10}
/>
<ChartTooltip
content={<ChartTooltipContent hideLabel />}
cursor={false}
/>
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={8} />
</BarChart>
</ChartContainer>
);
}
Line Chart
A single-series line chart without dots, using natural curve interpolation. The tooltip shows the value on hover without repeating the axis label.
"use client";
import { CartesianGrid, Line, LineChart, XAxis } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
export const description = "A line chart";
const chartData = [
{ desktop: 186, month: "January" },
{ desktop: 305, month: "February" },
{ desktop: 237, month: "March" },
{ desktop: 73, month: "April" },
{ desktop: 209, month: "May" },
{ desktop: 214, month: "June" },
];
const chartConfig = {
desktop: {
color: "var(--chart-1)",
label: "Desktop",
},
} satisfies ChartConfig;
export function ChartLineDefault() {
return (
<ChartContainer className="min-h-50 w-full" config={chartConfig}>
<LineChart
accessibilityLayer
data={chartData}
margin={{
left: 12,
right: 12,
}}
>
<CartesianGrid vertical={false} />
<XAxis
axisLine={false}
dataKey="month"
tickFormatter={(value) => value.slice(0, 3)}
tickLine={false}
tickMargin={8}
/>
<ChartTooltip
content={<ChartTooltipContent hideLabel />}
cursor={false}
/>
<Line
dataKey="desktop"
dot={false}
stroke="var(--color-desktop)"
strokeWidth={2}
type="natural"
/>
</LineChart>
</ChartContainer>
);
}
Pie Chart
A proportional pie chart showing browser share across five segments. Each segment maps to a --chart-N CSS variable so colors stay in sync with the active theme.
"use client";
import { Pie, PieChart } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
export const description = "A simple pie chart";
const chartData = [
{ browser: "chrome", fill: "var(--color-chrome)", visitors: 275 },
{ browser: "safari", fill: "var(--color-safari)", visitors: 200 },
{ browser: "firefox", fill: "var(--color-firefox)", visitors: 187 },
{ browser: "edge", fill: "var(--color-edge)", visitors: 173 },
{ browser: "other", fill: "var(--color-other)", visitors: 90 },
];
const chartConfig = {
chrome: {
color: "var(--chart-1)",
label: "Chrome",
},
edge: {
color: "var(--chart-4)",
label: "Edge",
},
firefox: {
color: "var(--chart-3)",
label: "Firefox",
},
other: {
color: "var(--chart-5)",
label: "Other",
},
safari: {
color: "var(--chart-2)",
label: "Safari",
},
visitors: {
label: "Visitors",
},
} satisfies ChartConfig;
export function ChartPieSimple() {
return (
<ChartContainer
className="mx-auto aspect-square max-h-62.5 w-full"
config={chartConfig}
>
<PieChart>
<ChartTooltip
content={<ChartTooltipContent hideLabel />}
cursor={false}
/>
<Pie data={chartData} dataKey="visitors" nameKey="browser" />
</PieChart>
</ChartContainer>
);
}
Radar Chart
A spider/radar chart with a polar grid and angle axis labels. Useful for comparing a single metric across multiple categories — here, monthly desktop traffic.
"use client";
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
export const description = "A radar chart";
const chartData = [
{ desktop: 186, month: "January" },
{ desktop: 305, month: "February" },
{ desktop: 237, month: "March" },
{ desktop: 273, month: "April" },
{ desktop: 209, month: "May" },
{ desktop: 214, month: "June" },
];
const chartConfig = {
desktop: {
color: "var(--chart-1)",
label: "Desktop",
},
} satisfies ChartConfig;
export function ChartRadarDefault() {
return (
<ChartContainer
className="mx-auto aspect-square max-h-62.5 w-full"
config={chartConfig}
>
<RadarChart data={chartData}>
<ChartTooltip content={<ChartTooltipContent />} cursor={false} />
<PolarAngleAxis dataKey="month" />
<PolarGrid />
<Radar
dataKey="desktop"
fill="var(--color-desktop)"
fillOpacity={0.6}
/>
</RadarChart>
</ChartContainer>
);
}
Radial Bar Chart
A radial bar chart with a background track. Each segment corresponds to a browser, with inner and outer radii controlling the ring thickness.
"use client";
import { RadialBar, RadialBarChart } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
export const description = "A radial chart";
const chartData = [
{ browser: "chrome", fill: "var(--color-chrome)", visitors: 275 },
{ browser: "safari", fill: "var(--color-safari)", visitors: 200 },
{ browser: "firefox", fill: "var(--color-firefox)", visitors: 187 },
{ browser: "edge", fill: "var(--color-edge)", visitors: 173 },
{ browser: "other", fill: "var(--color-other)", visitors: 90 },
];
const chartConfig = {
chrome: {
color: "var(--chart-1)",
label: "Chrome",
},
edge: {
color: "var(--chart-4)",
label: "Edge",
},
firefox: {
color: "var(--chart-3)",
label: "Firefox",
},
other: {
color: "var(--chart-5)",
label: "Other",
},
safari: {
color: "var(--chart-2)",
label: "Safari",
},
visitors: {
label: "Visitors",
},
} satisfies ChartConfig;
export function ChartRadialSimple() {
return (
<ChartContainer
className="mx-auto aspect-square max-h-62.5 w-full"
config={chartConfig}
>
<RadialBarChart data={chartData} innerRadius={30} outerRadius={110}>
<ChartTooltip
content={<ChartTooltipContent hideLabel nameKey="browser" />}
cursor={false}
/>
<RadialBar background dataKey="visitors" />
</RadialBarChart>
</ChartContainer>
);
}
Stacked Area Chart
Two revenue streams (recurring and one-time) stacked in a single area chart with a Y-axis in dollar thousands and a legend for series identification.
"use client";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
const chartData = [
{ month: "Jan", oneTime: 1800, recurring: 4200 },
{ month: "Feb", oneTime: 2100, recurring: 5100 },
{ month: "Mar", oneTime: 3200, recurring: 4800 },
{ month: "Apr", oneTime: 2600, recurring: 6200 },
{ month: "May", oneTime: 3100, recurring: 7100 },
{ month: "Jun", oneTime: 2900, recurring: 8400 },
];
const chartConfig = {
oneTime: { color: "var(--chart-2)", label: "One-time" },
recurring: { color: "var(--chart-1)", label: "Recurring" },
} satisfies ChartConfig;
export function Pattern() {
return (
<ChartContainer className="min-h-52 w-full" config={chartConfig}>
<AreaChart
accessibilityLayer
data={chartData}
margin={{ left: 8, right: 8 }}
>
<CartesianGrid vertical={false} />
<XAxis
axisLine={false}
dataKey="month"
tickLine={false}
tickMargin={8}
/>
<YAxis
axisLine={false}
tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`}
tickLine={false}
width={40}
/>
<ChartTooltip content={<ChartTooltipContent />} cursor={false} />
<ChartLegend content={<ChartLegendContent />} />
<Area
dataKey="oneTime"
fill="var(--color-oneTime)"
fillOpacity={0.3}
stackId="a"
stroke="var(--color-oneTime)"
type="natural"
/>
<Area
dataKey="recurring"
fill="var(--color-recurring)"
fillOpacity={0.5}
stackId="a"
stroke="var(--color-recurring)"
type="natural"
/>
</AreaChart>
</ChartContainer>
);
}
Horizontal Bar Chart
A horizontal bar chart ranking traffic acquisition channels by session count — layout is set to "vertical" with a category Y-axis and a value X-axis.
"use client";
import { Bar, BarChart, XAxis, YAxis } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
const chartData = [
{ channel: "Organic", sessions: 4820 },
{ channel: "Direct", sessions: 3210 },
{ channel: "Referral", sessions: 2760 },
{ channel: "Social", sessions: 1940 },
{ channel: "Email", sessions: 1380 },
{ channel: "Paid", sessions: 920 },
];
const chartConfig = {
sessions: { color: "var(--chart-1)", label: "Sessions" },
} satisfies ChartConfig;
export function Pattern() {
return (
<ChartContainer className="min-h-52 w-full" config={chartConfig}>
<BarChart
accessibilityLayer
data={chartData}
layout="vertical"
margin={{ left: 0, right: 12 }}
>
<XAxis hide type="number" />
<YAxis
axisLine={false}
dataKey="channel"
tickLine={false}
tickMargin={4}
type="category"
width={60}
/>
<ChartTooltip
content={<ChartTooltipContent hideLabel />}
cursor={false}
/>
<Bar dataKey="sessions" fill="var(--color-sessions)" radius={4} />
</BarChart>
</ChartContainer>
);
}
Donut Chart With Center Label
A donut-style pie chart with padding between segments and a centered SVG label showing total headcount, broken down by department with a legend.
"use client";
import { Cell, Pie, PieChart } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
const chartData = [
{ fill: "var(--color-design)", label: "Design", value: 35 },
{ fill: "var(--color-engineering)", label: "Engineering", value: 42 },
{ fill: "var(--color-marketing)", label: "Marketing", value: 15 },
{ fill: "var(--color-ops)", label: "Operations", value: 8 },
];
const chartConfig = {
design: { color: "var(--chart-2)", label: "Design" },
engineering: { color: "var(--chart-1)", label: "Engineering" },
marketing: { color: "var(--chart-3)", label: "Marketing" },
ops: { color: "var(--chart-4)", label: "Operations" },
} satisfies ChartConfig;
const total = chartData.reduce((sum, d) => sum + d.value, 0);
export function Pattern() {
return (
<ChartContainer
className="mx-auto aspect-square max-h-64 w-full"
config={chartConfig}
>
<PieChart>
<ChartTooltip
content={<ChartTooltipContent hideLabel />}
cursor={false}
/>
<Pie
cx="50%"
cy="42%"
data={chartData}
dataKey="value"
innerRadius="55%"
outerRadius="75%"
paddingAngle={3}
strokeWidth={0}
>
{chartData.map((entry) => (
<Cell fill={entry.fill} key={entry.label} />
))}
</Pie>
<text dominantBaseline="central" textAnchor="middle" x="50%" y="42%">
<tspan
className="fill-foreground font-bold text-2xl"
dy="-0.5em"
x="50%"
>
{total}
</tspan>
<tspan className="fill-muted-foreground text-xs" dy="1.4em" x="50%">
headcount
</tspan>
</text>
<ChartLegend content={<ChartLegendContent nameKey="label" />} />
</PieChart>
</ChartContainer>
);
}
Multi-Series Line Chart
Three API latency percentiles (p50, p90, p99) plotted as lines with distinct dash patterns. Each series uses a var(--chart-N) color resolved through ChartContainer.
"use client";
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
const chartData = [
{ month: "Jan", p50: 120, p90: 340, p99: 780 },
{ month: "Feb", p50: 135, p90: 310, p99: 820 },
{ month: "Mar", p50: 110, p90: 290, p99: 640 },
{ month: "Apr", p50: 145, p90: 380, p99: 910 },
{ month: "May", p50: 128, p90: 355, p99: 760 },
{ month: "Jun", p50: 118, p90: 320, p99: 700 },
];
const chartConfig = {
p50: { color: "var(--chart-1)", label: "p50 (ms)" },
p90: { color: "var(--chart-2)", label: "p90 (ms)" },
p99: { color: "var(--chart-3)", label: "p99 (ms)" },
} satisfies ChartConfig;
export function Pattern() {
return (
<ChartContainer className="min-h-52 w-full" config={chartConfig}>
<LineChart
accessibilityLayer
data={chartData}
margin={{ left: 8, right: 8 }}
>
<CartesianGrid vertical={false} />
<XAxis
axisLine={false}
dataKey="month"
tickLine={false}
tickMargin={8}
/>
<YAxis
axisLine={false}
tickFormatter={(v) => `${v}ms`}
tickLine={false}
width={48}
/>
<ChartTooltip content={<ChartTooltipContent />} cursor={false} />
<ChartLegend content={<ChartLegendContent />} />
<Line
dataKey="p50"
dot={false}
stroke="var(--color-p50)"
strokeWidth={2}
type="monotone"
/>
<Line
dataKey="p90"
dot={false}
stroke="var(--color-p90)"
strokeDasharray="4 2"
strokeWidth={2}
type="monotone"
/>
<Line
dataKey="p99"
dot={false}
stroke="var(--color-p99)"
strokeDasharray="2 2"
strokeWidth={2}
type="monotone"
/>
</LineChart>
</ChartContainer>
);
}
Composed Chart
Revenue bars and a month-over-month growth percentage line share the same chart on dual Y-axes — left for dollar values and right for percentage values.
"use client";
import {
Bar,
CartesianGrid,
ComposedChart,
Line,
XAxis,
YAxis,
} from "recharts";
import {
type ChartConfig,
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
const chartData = [
{ growth: 8.2, month: "Jan", revenue: 12400 },
{ growth: 21.8, month: "Feb", revenue: 15100 },
{ growth: -8.6, month: "Mar", revenue: 13800 },
{ growth: 24.6, month: "Apr", revenue: 17200 },
{ growth: 14.0, month: "May", revenue: 19600 },
{ growth: 12.8, month: "Jun", revenue: 22100 },
];
const chartConfig = {
growth: { color: "var(--chart-2)", label: "Growth %" },
revenue: { color: "var(--chart-1)", label: "Revenue ($)" },
} satisfies ChartConfig;
export function Pattern() {
return (
<ChartContainer className="min-h-52 w-full" config={chartConfig}>
<ComposedChart
accessibilityLayer
data={chartData}
margin={{ left: 8, right: 16 }}
>
<CartesianGrid vertical={false} />
<XAxis
axisLine={false}
dataKey="month"
tickLine={false}
tickMargin={8}
/>
<YAxis
axisLine={false}
tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`}
tickLine={false}
width={44}
yAxisId="left"
/>
<YAxis
axisLine={false}
orientation="right"
tickFormatter={(v) => `${v}%`}
tickLine={false}
width={36}
yAxisId="right"
/>
<ChartTooltip content={<ChartTooltipContent />} cursor={false} />
<ChartLegend content={<ChartLegendContent />} />
<Bar
dataKey="revenue"
fill="var(--color-revenue)"
radius={4}
yAxisId="left"
/>
<Line
dataKey="growth"
dot={{ fill: "var(--color-growth)", r: 3 }}
stroke="var(--color-growth)"
strokeWidth={2}
type="monotone"
yAxisId="right"
/>
</ComposedChart>
</ChartContainer>
);
}

