Chart

Beautiful charts and graphs built with Recharts. From basic charts to rich data displays.

Installation

CLI

bash
npx fivui add chart

This will install the chart component and automatically add the chart color variables to your globals.css. You can customize these colors by editing the CSS variables.

Manual

Install the following dependencies:

bash
npm install recharts

Copy and paste the following code into your project:

tsx
"use client"
import * as React from "react"
import { ResponsiveContainer } from "recharts"
import { cn } from "@/lib/utils"
const ChartContainer = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> & {
config: Record<string, any>
children: React.ComponentProps<typeof ResponsiveContainer>["children"]
}
>(({ id, className, children, config, ...props }, ref) => {
const uniqueId = React.useId()
const chartId = `chart-${uniqueId.replace(/:/g, "")}`
return (
<div
data-chart={chartId}
ref={ref}
className={cn(
"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
className
)}
{...props}
>
<ChartStyle id={chartId} config={config} />
<ResponsiveContainer>{children}</ResponsiveContainer>
</div>
)
})
ChartContainer.displayName = "ChartContainer"
const ChartTooltip = ({ active, payload, label }: any) => {
if (active && payload && payload.length) {
return (
<div className="rounded-lg border bg-background p-2 shadow-sm">
<div className="grid grid-cols-2 gap-2">
<div className="flex flex-col">
<span className="text-[0.70rem] uppercase text-muted-foreground">
{label}
</span>
<span className="font-bold text-muted-foreground">
{payload[0].value}
</span>
</div>
</div>
</div>
)
}
return null
}
const ChartTooltipContent = ({ active, payload, label }: any) => {
if (active && payload && payload.length) {
return (
<div className="rounded-lg border bg-background p-2 shadow-sm">
<div className="grid grid-cols-2 gap-2">
<div className="flex flex-col">
<span className="text-[0.70rem] uppercase text-muted-foreground">
{label}
</span>
<span className="font-bold text-muted-foreground">
{payload[0].value}
</span>
</div>
</div>
</div>
)
}
return null
}
export { ChartContainer, ChartTooltip, ChartTooltipContent }

Add the chart color variables to your globals.css:

css
@layer base {
:root {
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
}
}

Usage

tsx
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
ChartLegend,
ChartLegendContent,
type ChartConfig,
} from "@/components/ui/chart"

Chart Types

Area Charts

Perfect for showing data trends over time with filled areas.

Basic Area Chart

Area Chart - Basic
Desktop vs Mobile visitors
tsx
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts"
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/components/ui/chart"
const chartData = [
{ month: "Jan", desktop: 186, mobile: 80 },
{ month: "Feb", desktop: 305, mobile: 200 },
{ month: "Mar", desktop: 237, mobile: 120 },
{ month: "Apr", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "Jun", desktop: 214, mobile: 140 },
]
const chartConfig = {
desktop: {
label: "Desktop",
color: "hsl(var(--chart-1))",
},
mobile: {
label: "Mobile",
color: "hsl(var(--chart-2))",
},
} satisfies ChartConfig
export function AreaChartDemo() {
return (
<ChartContainer config={chartConfig}>
<AreaChart 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 />} />
<Area
dataKey="desktop"
type="natural"
fill="var(--color-desktop)"
fillOpacity={0.4}
stroke="var(--color-desktop)"
/>
<Area
dataKey="mobile"
type="natural"
fill="var(--color-mobile)"
fillOpacity={0.4}
stroke="var(--color-mobile)"
/>
</AreaChart>
</ChartContainer>
)
}

Stacked Area Chart

Area Chart - Stacked
Multi-device visitor breakdown
tsx
export function AreaStackedDemo() {
return (
<ChartContainer config={chartConfig}>
<AreaChart data={areaStackedData} 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 />} />
<Area
dataKey="tablet"
type="natural"
fill="var(--color-tablet)"
fillOpacity={0.4}
stroke="var(--color-tablet)"
stackId="a"
/>
<Area
dataKey="mobile"
type="natural"
fill="var(--color-mobile)"
fillOpacity={0.4}
stroke="var(--color-mobile)"
stackId="a"
/>
<Area
dataKey="desktop"
type="natural"
fill="var(--color-desktop)"
fillOpacity={0.4}
stroke="var(--color-desktop)"
stackId="a"
/>
</AreaChart>
</ChartContainer>
)
}

Gradient Area Chart

Area Chart - Gradient Fill
Beautiful gradient fills for enhanced visuals
tsx
export function AreaGradientDemo() {
return (
<ChartContainer config={chartConfig}>
<AreaChart data={areaGradientData} 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 />} />
<defs>
<linearGradient id="fillDesktopGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="var(--color-desktop)" stopOpacity={0.8} />
<stop offset="95%" stopColor="var(--color-desktop)" stopOpacity={0.1} />
</linearGradient>
<linearGradient id="fillMobileGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="var(--color-mobile)" stopOpacity={0.8} />
<stop offset="95%" stopColor="var(--color-mobile)" stopOpacity={0.1} />
</linearGradient>
</defs>
<Area
dataKey="desktop"
type="natural"
fill="url(#fillDesktopGradient)"
fillOpacity={1}
stroke="var(--color-desktop)"
strokeWidth={2}
/>
<Area
dataKey="mobile"
type="natural"
fill="url(#fillMobileGradient)"
fillOpacity={1}
stroke="var(--color-mobile)"
strokeWidth={2}
/>
</AreaChart>
</ChartContainer>
)
}

Step Area Chart

Area Chart - Step Type
Step-based area chart for discrete data
tsx
export function AreaStepDemo() {
return (
<ChartContainer config={chartConfig}>
<AreaChart data={areaStepData} 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 />} />
<Area
dataKey="desktop"
type="step"
fill="var(--color-desktop)"
fillOpacity={0.4}
stroke="var(--color-desktop)"
strokeWidth={2}
/>
<Area
dataKey="mobile"
type="step"
fill="var(--color-mobile)"
fillOpacity={0.4}
stroke="var(--color-mobile)"
strokeWidth={2}
/>
<Area
dataKey="tablet"
type="step"
fill="var(--color-tablet)"
fillOpacity={0.4}
stroke="var(--color-tablet)"
strokeWidth={2}
/>
</AreaChart>
</ChartContainer>
)
}

Area Chart with Dots

Area Chart - With Data Points
Area chart with visible data points and active dots
tsx
export function AreaDotsDemo() {
return (
<ChartContainer config={chartConfig}>
<AreaChart data={areaDotsData} 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 />} />
<Area
dataKey="desktop"
type="monotone"
fill="var(--color-desktop)"
fillOpacity={0.4}
stroke="var(--color-desktop)"
strokeWidth={2}
dot={{
fill: "var(--color-desktop)",
strokeWidth: 2,
r: 4,
}}
activeDot={{
r: 6,
}}
/>
</AreaChart>
</ChartContainer>
)
}

API Reference

ChartContainer

PropTypeDefaultDescription
configChartConfig-Configuration object for chart colors and labels.
childrenReact.ReactNode-The chart components to render.
classNamestring-Additional CSS classes for styling.

ChartConfig

PropertyTypeDescription
labelReact.ReactNodeDisplay label for the data key.
colorstringColor value using CSS custom properties (--chart-1 to --chart-5).
iconReact.ComponentTypeOptional icon component for the data series.

External Documentation