Charts

Plots data as charts, built on 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;

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 @roiui/chart
npx shadcn@latest add @roiui/chart-tailwind

"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;

const ANIMATION_DURATION = 500;
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.

Prop
Type
Default

Custom tooltip content component for displaying data on hover.

Prop
Type
Default

Custom legend component for displaying chart data series.

Prop
Type
Default

For individual chart components (LineChart, BarChart, AreaChart, PieChart, etc.), refer to the Recharts API documentation.