Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new

Chart

Beautiful charts. Built using Recharts. Copy and paste into your apps.

Interactive preview

Rendered from the shared Frontfriend stories with React Base, the same preview Studio shows. Styling comes from your Design System; the code below is native to Radix UI.

Installation

Complete project setup first. Your configuration must select react/radix and include your Design System ID.

pnpm exec frontfriend download chart -f react --primitive radix

Review dependencies reported by the downloader and keep your source changes in version control.

Usage

import {
  ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  ChartLegendContent,
} from "@/components/ui/chart";
import { BarChart, CartesianGrid, XAxis, Legend, Bar } from "recharts";
const chartConfig = {
  desktop: {
    label: "Desktop",
    color: "var(--bg-brand-mid)",
  },
  mobile: {
    label: "Mobile",
    color: "var(--bg-info-mid)",
  },
} satisfies ChartConfig;
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 },
];
function ChartPlayground({
  height = 280,
  showLegend = true,
  config = chartConfig,
}: {
  height?: number;
  showLegend?: boolean;
  config?: ChartConfig;
}) {
  return (
    <ChartContainer
      config={config}
      style={{
        width: 500,
        maxWidth: "100%",
        height: Math.max(160, Math.min(500, height)),
      }}
    >
      <BarChart accessibilityLayer data={chartData}>
        <CartesianGrid vertical={false} />
        <XAxis
          dataKey="month"
          tickLine={false}
          axisLine={false}
          tickFormatter={(value: string) => value.slice(0, 3)}
        />
        <ChartTooltip content={<ChartTooltipContent />} />
        {showLegend && <Legend content={<ChartLegendContent />} />}
        <Bar
          dataKey="desktop"
          fill="var(--color-desktop)"
          radius={4}
          isAnimationActive={false}
        />
        <Bar
          dataKey="mobile"
          fill="var(--color-mobile)"
          radius={4}
          isAnimationActive={false}
        />
      </BarChart>
    </ChartContainer>
  );
}
<ChartPlayground height={280} showLegend config={chartConfig} />;

Examples

Default

import { Card } from "@/components/ui/card";
import {
  ChartContainer,
  ChartConfig,
  ChartTooltip,
  ChartTooltipContent,
  ChartLegendContent,
} from "@/components/ui/chart";
import { AreaChart, CartesianGrid, XAxis, Area, Legend } from "recharts";
const chartConfig = {
  desktop: {
    label: "Desktop",
    color: "var(--bg-brand-mid)",
  },
  mobile: {
    label: "Mobile",
    color: "var(--bg-info-mid)",
  },
} satisfies ChartConfig;
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 },
];
<Card className="w-[500px] max-w-full h-[500px]">
  <ChartContainer config={chartConfig} className="w-full h-[304px] relative">
    <AreaChart
      accessibilityLayer
      data={chartData}
      margin={{
        left: 12,
        right: 12,
      }}
    >
      <CartesianGrid vertical={false} />
      <XAxis
        dataKey="month"
        tickLine={false}
        axisLine={false}
        tickMargin={8}
        tickFormatter={(value) => value.slice(0, 3)}
      />
      <ChartTooltip
        cursor={false}
        content={<ChartTooltipContent indicator="dot" />}
      />
      <Area
        dataKey="mobile"
        type="natural"
        fill="var(--color-desktop)"
        fillOpacity={0.4}
        stroke="var(--color-desktop)"
        stackId="a"
      />
      <Area
        dataKey="desktop"
        type="natural"
        fill="var(--color-mobile)"
        fillOpacity={0.4}
        stroke="var(--color-mobile)"
        stackId="a"
      />
      <Legend content={<ChartLegendContent />} />
    </AreaChart>
  </ChartContainer>
</Card>;

Bar Chart Example

import { Card } from "@/components/ui/card";
import {
  ChartContainer,
  ChartConfig,
  ChartTooltip,
  ChartTooltipContent,
  ChartLegendContent,
} from "@/components/ui/chart";
import { BarChart, CartesianGrid, XAxis, Bar, Legend } from "recharts";
const chartConfig = {
  desktop: {
    label: "Desktop",
    color: "var(--bg-brand-mid)",
  },
  mobile: {
    label: "Mobile",
    color: "var(--bg-info-mid)",
  },
} satisfies ChartConfig;
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 },
];
<Card className="w-[500px] max-w-full h-[500px]">
  <ChartContainer
    config={chartConfig}
    className="mx-auto aspect-square h-[400px] w-full "
  >
    <BarChart accessibilityLayer data={chartData}>
      <CartesianGrid vertical={false} />
      <XAxis
        dataKey="month"
        tickLine={false}
        tickMargin={10}
        axisLine={false}
        tickFormatter={(value) => value.slice(0, 3)}
      />
      <ChartTooltip
        cursor={false}
        content={<ChartTooltipContent indicator="dashed" />}
      />
      <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
      <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
      <Legend content={<ChartLegendContent />} />
    </BarChart>
  </ChartContainer>
</Card>;

Pie Chart Example

import { Card } from "@/components/ui/card";
import {
  ChartContainer,
  ChartConfig,
  ChartTooltip,
  ChartTooltipContent,
  ChartLegendContent,
} from "@/components/ui/chart";
import { PieChart, Pie, Label, Legend } from "recharts";
const pieChartConfig = {
  visitors: {
    label: "Visitors",
  },
  chrome: {
    label: "Chrome",
    color: "var(--bg-brand-mid)",
  },
  safari: {
    label: "Safari",
    color: "var(--bg-info-mid)",
  },
  firefox: {
    label: "Firefox",
    color: "var(--bg-positive-mid)",
  },
  edge: {
    label: "Edge",
    color: "var(--bg-warning-mid)",
  },
  other: {
    label: "Other",
    color: "var(--bg-neutral-strong)",
  },
} satisfies ChartConfig;
const pieChartData = [
  { browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
  { browser: "safari", visitors: 200, fill: "var(--color-safari)" },
  { browser: "firefox", visitors: 287, fill: "var(--color-firefox)" },
  { browser: "edge", visitors: 173, fill: "var(--color-edge)" },
  { browser: "other", visitors: 190, fill: "var(--color-other)" },
];
const total = pieChartData.reduce((acc, curr) => acc + curr.visitors, 0);
<Card className="w-[500px] max-w-full h-[500px]">
  <ChartContainer
    config={pieChartConfig}
    className="mx-auto aspect-square h-[400px] w-full relative"
  >
    <PieChart>
      <ChartTooltip
        cursor={false}
        content={<ChartTooltipContent hideLabel />}
      />
      <Pie
        data={pieChartData}
        dataKey="visitors"
        nameKey="browser"
        innerRadius={60}
        strokeWidth={5}
      >
        <Label
          content={({ viewBox }) => {
            if (viewBox && "cx" in viewBox && "cy" in viewBox) {
              return (
                <text
                  x={viewBox.cx}
                  y={viewBox.cy}
                  textAnchor="middle"
                  dominantBaseline="middle"
                >
                  <tspan
                    x={viewBox.cx}
                    y={viewBox.cy}
                    className="fill-current text-neutral-strong text-3xl font-bold"
                  >
                    {total.toLocaleString()}
                  </tspan>
                  <tspan
                    x={viewBox.cx}
                    y={(viewBox.cy || 0) + 24}
                    className="fill-current text-neutral-mid"
                  >
                    Visitors
                  </tspan>
                </text>
              );
            }
          }}
        />
      </Pie>
      <Legend content={<ChartLegendContent />} />
    </PieChart>
  </ChartContainer>
</Card>;

Line Chart Example

import { Card } from "@/components/ui/card";
import {
  ChartContainer,
  ChartConfig,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart";
import { LineChart, CartesianGrid, XAxis, Line } from "recharts";
const lineChartConfig = {
  desktop: {
    label: "Desktop",
    color: "var(--bg-brand-mid)",
  },
} satisfies ChartConfig;
const lineChartData = [
  { month: "January", desktop: 186 },
  { month: "February", desktop: 305 },
  { month: "March", desktop: 237 },
  { month: "April", desktop: 73 },
  { month: "May", desktop: 209 },
  { month: "June", desktop: 214 },
];
<Card className="w-[500px] max-w-full h-[500px]">
  <ChartContainer
    config={lineChartConfig}
    className="mx-auto aspect-square h-[400px] w-full "
  >
    <LineChart
      accessibilityLayer
      data={lineChartData}
      margin={{
        left: 12,
        right: 12,
      }}
    >
      <CartesianGrid vertical={false} />
      <XAxis
        dataKey="month"
        tickLine={false}
        axisLine={false}
        tickMargin={8}
        tickFormatter={(value) => value.slice(0, 3)}
      />
      <ChartTooltip
        cursor={false}
        content={<ChartTooltipContent hideLabel />}
      />
      <Line
        dataKey="desktop"
        type="natural"
        stroke="var(--color-desktop)"
        strokeWidth={2}
        dot={false}
      />
    </LineChart>
  </ChartContainer>
</Card>;

Radar Chart Example

import { Card } from "@/components/ui/card";
import {
  ChartContainer,
  ChartConfig,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart";
import { RadarChart, PolarAngleAxis, PolarGrid, Radar } from "recharts";
const radarChartConfig = {
  desktop: {
    label: "Desktop",
    color: "var(--bg-brand-mid)",
  },
} satisfies ChartConfig;
const radarChartData = [
  { month: "January", desktop: 186 },
  { month: "February", desktop: 305 },
  { month: "March", desktop: 237 },
  { month: "April", desktop: 273 },
  { month: "May", desktop: 209 },
  { month: "June", desktop: 214 },
];
<Card className="w-[500px] max-w-full h-[500px]">
  <ChartContainer
    config={radarChartConfig}
    className="mx-auto aspect-square h-[400px] w-full "
  >
    <RadarChart data={radarChartData}>
      <ChartTooltip cursor={false} content={<ChartTooltipContent />} />
      <PolarAngleAxis dataKey="month" />
      <PolarGrid />
      <Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.6} />
    </RadarChart>
  </ChartContainer>
</Card>;

Radial Chart Example

import { Card } from "@/components/ui/card";
import {
  ChartContainer,
  ChartConfig,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart";
import { RadialBarChart, RadialBar } from "recharts";
const radialChartConfig = {
  visitors: {
    label: "Visitors",
  },
  chrome: {
    label: "Chrome",
    color: "var(--bg-brand-mid)",
  },
  safari: {
    label: "Safari",
    color: "var(--bg-info-mid)",
  },
  firefox: {
    label: "Firefox",
    color: "var(--bg-positive-mid)",
  },
  edge: {
    label: "Edge",
    color: "var(--bg-warning-mid)",
  },
  other: {
    label: "Other",
    color: "var(--bg-neutral-strong)",
  },
} satisfies ChartConfig;
const radialChartData = [
  { browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
  { browser: "safari", visitors: 200, fill: "var(--color-safari)" },
  { browser: "firefox", visitors: 287, fill: "var(--color-firefox)" },
  { browser: "edge", visitors: 173, fill: "var(--color-edge)" },
  { browser: "other", visitors: 190, fill: "var(--color-other)" },
];
<Card className="w-[500px] max-w-full h-[500px]">
  <ChartContainer
    config={radialChartConfig}
    className="mx-auto aspect-square h-[400px] w-full "
  >
    <RadialBarChart data={radialChartData} innerRadius={30} outerRadius={110}>
      <ChartTooltip
        cursor={false}
        content={<ChartTooltipContent hideLabel nameKey="browser" />}
      />
      <RadialBar dataKey="visitors" background />
    </RadialBarChart>
  </ChartContainer>
</Card>;

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Radix UI.

ChartContainer

Prop Type Default Description
config ChartConfig —
initialDimension { width: number; height: number; } INITIAL_DIMENSION

ChartLegendContent

Prop Type Default Description
hideIcon boolean false
nameKey string —

ChartStyle

Prop Type Default Description
config ChartConfig —

ChartTooltipContent

Prop Type Default Description
hideIndicator boolean false
hideLabel boolean false
indicator "line" | "dot" | "dashed" "dot"
labelKey string —
nameKey string —

Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.