Composable chart components for data visualization using Recharts
"use client";
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts";
import {
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart/chart";
import styles from "./chart-line-demo.module.css";
const chartData = [
  { date: 1990, canada: 27.7, uk: 57.2 },
  { date: 1991, canada: 28.0, uk: 57.4 },
  { date: 1992, canada: 28.4, uk: 57.6 },
  { date: 1993, canada: 28.7, uk: 57.7 },
  { date: 1994, canada: 29.0, uk: 57.9 },
  { date: 1995, canada: 29.3, uk: 58.0 },
  { date: 1996, canada: 29.6, uk: 58.2 },
  { date: 1997, canada: 29.9, uk: 58.3 },
  { date: 1998, canada: 30.2, uk: 58.5 },
  { date: 1999, canada: 30.4, uk: 58.7 },
  { date: 2000, canada: 30.7, uk: 59.0 },
  { date: 2001, canada: 31.0, uk: 59.1 },
  { date: 2002, canada: 31.4, uk: 59.3 },
  { date: 2003, canada: 31.6, uk: 59.6 },
  { date: 2004, canada: 31.9, uk: 60.0 },
  { date: 2005, canada: 32.2, uk: 60.4 },
  { date: 2006, canada: 32.6, uk: 60.8 },
  { date: 2007, canada: 32.9, uk: 61.3 },
  { date: 2008, canada: 33.2, uk: 61.8 },
  { date: 2009, canada: 33.6, uk: 62.3 },
  { date: 2010, canada: 34.0, uk: 62.8 },
  { date: 2011, canada: 34.3, uk: 63.3 },
  { date: 2012, canada: 34.7, uk: 63.7 },
  { date: 2013, canada: 35.1, uk: 64.1 },
  { date: 2014, canada: 35.4, uk: 64.6 },
  { date: 2015, canada: 35.7, uk: 65.1 },
  { date: 2016, canada: 36.1, uk: 65.6 },
  { date: 2017, canada: 36.5, uk: 66.0 },
  { date: 2018, canada: 37.0, uk: 66.4 },
  { date: 2019, canada: 37.6, uk: 66.8 },
  { date: 2020, canada: 38.0, uk: 67.9 },
  { date: 2021, canada: 38.2, uk: 67.0 },
  { date: 2022, canada: 38.9, uk: 67.5 },
  { date: 2023, canada: 39.6, uk: 68.3 },
  { date: 2024, canada: 40.0, uk: 69.0 },
  { date: 2025, canada: 40.1, uk: 69.8 },
];
const chartConfig = {
  canada: {
    label: "Canada",
    color: "var(--chart-1)",
  },
  uk: {
    label: "United Kingdom",
    color: "var(--chart-2)",
  },
} satisfies ChartConfig;
// biome-ignore lint/style/noMagicNumbers: X-axis tick values for 5-year intervals
const X_AXIS_TICKS = [1990, 1995, 2000, 2005, 2010, 2015, 2020, 2025];
export default function ChartLineDemo() {
  return (
    <div className={styles.container}>
      <ChartContainer className={styles.chartContainer} config={chartConfig}>
        <LineChart
          data={chartData}
          margin={{ top: 5, right: 5, left: 0, bottom: 0 }}
        >
          <CartesianGrid strokeDasharray="3 3" vertical={false} />
          <XAxis
            axisLine={false}
            dataKey="date"
            tickFormatter={(value) => value.toString()}
            tickLine={false}
            tickMargin={8}
            ticks={X_AXIS_TICKS}
          />
          <YAxis
            axisLine={false}
            domain={[0, "auto"]}
            tickLine={false}
            tickMargin={8}
            width={40}
          />
          <ChartTooltip content={<ChartTooltipContent labelKey="date" />} />
          <Line
            animationDuration={800}
            dataKey="canada"
            dot={false}
            stroke="var(--color-canada)"
            strokeWidth={2}
            type="monotone"
          />
          <Line
            animationBegin={200}
            animationDuration={800}
            dataKey="uk"
            dot={false}
            stroke="var(--color-uk)"
            strokeWidth={2}
            type="monotone"
          />
        </LineChart>
      </ChartContainer>
    </div>
  );
}
npx shadcn@latest add https://roiui.com/r/chart.json"use client";
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts";
import {
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart/chart";
import styles from "./chart-bar-demo.module.css";
const chartData = [
  { month: "Jan", sales: 45.2 },
  { month: "Feb", sales: 52.8 },
  { month: "Mar", sales: 48.9 },
  { month: "Apr", sales: 67.3 },
  { month: "May", sales: 72.1 },
  { month: "Jun", sales: 89.4 },
  { month: "Jul", sales: 95.7 },
  { month: "Aug", sales: 103.2 },
];
const chartConfig = {
  sales: {
    label: "Sales",
    color: "var(--chart-1)",
  },
} satisfies ChartConfig;
// biome-ignore lint/style/noMagicNumbers: Animation duration in milliseconds
const ANIMATION_DURATION = 500;
// biome-ignore lint/style/noMagicNumbers: Border radius for top corners of bars
const BAR_RADIUS: [number, number, number, number] = [4, 4, 0, 0];
export default function ChartBarDemo() {
  return (
    <div className={styles.container}>
      <ChartContainer className={styles.chartContainer} config={chartConfig}>
        <BarChart
          data={chartData}
          margin={{ top: 5, right: 5, left: 0, bottom: 0 }}
        >
          <CartesianGrid strokeDasharray="3 3" vertical={false} />
          <XAxis
            axisLine={false}
            dataKey="month"
            tickLine={false}
            tickMargin={8}
          />
          <YAxis
            axisLine={false}
            domain={[0, "auto"]}
            tickLine={false}
            tickMargin={8}
            width={40}
          />
          <ChartTooltip
            content={
              <ChartTooltipContent
                formatter={(value) => {
                  const numValue =
                    typeof value === "number"
                      ? value
                      : Number.parseFloat(String(value));
                  return `$${numValue.toLocaleString()}k`;
                }}
              />
            }
          />
          <Bar
            animationDuration={ANIMATION_DURATION}
            dataKey="sales"
            fill="var(--color-sales)"
            radius={BAR_RADIUS}
          />
        </BarChart>
      </ChartContainer>
    </div>
  );
}
"use client";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
import {
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart/chart";
import styles from "./chart-area-demo.module.css";
const chartData = [
  { year: 2020, revenue: 45.2 },
  { year: 2021, revenue: 52.8 },
  { year: 2022, revenue: 48.9 },
  { year: 2023, revenue: 67.3 },
  { year: 2024, revenue: 72.1 },
  { year: 2025, revenue: 89.4 },
  { year: 2026, revenue: 95.7 },
  { year: 2027, revenue: 103.2 },
  { year: 2028, revenue: 118.6 },
  { year: 2029, revenue: 127.9 },
  { year: 2030, revenue: 142.3 },
];
const chartConfig = {
  revenue: {
    label: "Revenue",
    color: "var(--chart-1)",
  },
} satisfies ChartConfig;
export default function ChartAreaDemo() {
  return (
    <div className={styles.container}>
      <ChartContainer className={styles.chartContainer} config={chartConfig}>
        <AreaChart
          data={chartData}
          margin={{ top: 5, right: 5, left: 0, bottom: 0 }}
        >
          <defs>
            <linearGradient id="fillRevenue" x1="0" x2="0" y1="0" y2="1">
              <stop
                offset="0%"
                stopColor="var(--color-revenue)"
                stopOpacity={0.3}
              />
              <stop
                offset="100%"
                stopColor="var(--color-revenue)"
                stopOpacity={0.1}
              />
            </linearGradient>
          </defs>
          <CartesianGrid strokeDasharray="3 3" vertical={false} />
          <XAxis
            axisLine={false}
            dataKey="year"
            tickFormatter={(value) => value.toString()}
            tickLine={false}
            tickMargin={8}
          />
          <YAxis
            axisLine={false}
            domain={[0, "auto"]}
            tickLine={false}
            tickMargin={8}
            width={40}
          />
          <ChartTooltip content={<ChartTooltipContent labelKey="year" />} />
          <Area
            animationDuration={800}
            dataKey="revenue"
            dot={false}
            fill="url(#fillRevenue)"
            stroke="var(--color-revenue)"
            strokeWidth={2}
            type="monotone"
          />
        </AreaChart>
      </ChartContainer>
    </div>
  );
}
"use client";
import { Pie, PieChart } from "recharts";
import {
  type ChartConfig,
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart/chart";
import styles from "./chart-pie-demo.module.css";
const chartData = [
  { platform: "mobile", visitors: 45.2, fill: "var(--color-mobile)" },
  { platform: "desktop", visitors: 32.8, fill: "var(--color-desktop)" },
  { platform: "tablet", visitors: 15.9, fill: "var(--color-tablet)" },
  { platform: "smarttv", visitors: 6.1, fill: "var(--color-smarttv)" },
];
const chartConfig = {
  visitors: {
    label: "Visitors",
  },
  mobile: {
    label: "Mobile",
    color: "var(--chart-1)",
  },
  desktop: {
    label: "Desktop",
    color: "var(--chart-2)",
  },
  tablet: {
    label: "Tablet",
    color: "var(--chart-3)",
  },
  smarttv: {
    label: "Smart TV",
    color: "var(--chart-4)",
  },
} satisfies ChartConfig;
export default function ChartPieDemo() {
  return (
    <div className={styles.container}>
      <ChartContainer className={styles.chartContainer} config={chartConfig}>
        <PieChart>
          <ChartTooltip
            content={
              <ChartTooltipContent
                formatter={(value) => {
                  const numValue =
                    typeof value === "number"
                      ? value
                      : Number.parseFloat(String(value));
                  return `${numValue.toFixed(1)}%`;
                }}
                nameKey="platform"
              />
            }
          />
          <ChartLegend content={<ChartLegendContent nameKey="platform" />} />
          <Pie
            animationDuration={800}
            data={chartData}
            dataKey="visitors"
            innerRadius={60}
            nameKey="platform"
            outerRadius={100}
            stroke="transparent"
            strokeWidth={0}
          />
        </PieChart>
      </ChartContainer>
    </div>
  );
}
The main container component for all charts. Provides configuration and responsive sizing.
configChartConfigchildrenReactNodeidstringclassNamestringCustom tooltip content component for displaying data on hover.
indicator"line" | "dot" | "dashed""dot"hideLabelbooleanfalsehideIndicatorbooleanfalselabelFormatterfunctionformatterfunctionlabelClassNamestringclassNamestringcolorstringnameKeystringlabelKeystringCustom legend component for displaying chart data series.
hideIconbooleanfalseverticalAlign"top" | "bottom""bottom"nameKeystringclassNamestringFor individual chart components (LineChart, BarChart, AreaChart, PieChart, etc.), refer to the Recharts API documentation.