Skip to content
SevenUI
Esc
navigateopen⌘Jpreview
Sign in
On this page

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.json

Usage

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.

  • ChartContainer takes a config: ChartConfig and renders recharts’ ResponsiveContainer inside a data-chart-scoped div, plus an injected <style> tag (ChartStyle) that defines the series’ CSS variables.
  • ChartConfig maps each series key to a label/icon and either a single color or a per-theme theme: { light, dark } pair.
  • Series colors resolve as var(--color-<key>) inside the container, scoped to that chart’s data-chart id. Dark values apply under the .dark [data-chart=…] selector (the shadcn consumer convention).
  • ChartTooltip / ChartLegend are direct re-exports of recharts’ Tooltip / Legend; ChartTooltipContent and ChartLegendContent are our styled content renderers, wired up as content={<ChartTooltipContent />}.
  • ChartTooltipContent accepts hideLabel, hideIndicator, indicator="line" | "dot" | "dashed", nameKey, and labelKey, on top of recharts’ own tooltip content props.
  • ChartLegendContent accepts hideIcon and nameKey, 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 TooltipContentPropsnot React.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} on Legend to preserve series order.
  • accessibilityLayer defaults to true in v3 — you no longer need to pass it yourself.

Was this page helpful?