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
Prop | Type | Default | Description |
---|---|---|---|
config | ChartConfig | - | Configuration object for chart colors and labels. |
children | React.ReactNode | - | The chart components to render. |
className | string | - | Additional CSS classes for styling. |
ChartConfig
Property | Type | Description |
---|---|---|
label | React.ReactNode | Display label for the data key. |
color | string | Color value using CSS custom properties (--chart-1 to --chart-5). |
icon | React.ComponentType | Optional icon component for the data series. |