import { AreaChart, AreaChartSeries } from "@/components/ui/area-chart";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
ChartGrid,
ChartLegend,
ChartTooltip,
ChartXAxis,
type ChartConfig,
} from "@/components/ui/chart";
const data = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 273, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 314, mobile: 140 },
{ month: "July", desktop: 268, mobile: 175 },
{ month: "August", desktop: 342, mobile: 210 },
{ month: "September", desktop: 296, mobile: 184 },
{ month: "October", desktop: 358, mobile: 226 },
{ month: "November", desktop: 331, mobile: 203 },
{ month: "December", desktop: 389, mobile: 248 },
];
const config = {
desktop: { label: "Desktop" },
mobile: { label: "Mobile" },
} satisfies ChartConfig;
export default function AreaChartStacked() {
return (
<Card className="w-full">
<CardHeader>
<CardTitle>Visitors</CardTitle>
<CardDescription>January to December 2025</CardDescription>
</CardHeader>
<CardContent>
<AreaChart
data={data}
config={config}
stack="stacked"
className="aspect-[4/3] sm:aspect-[2/1]"
>
<ChartGrid />
<ChartXAxis dataKey="month" tickFormatter={(month: string) => month.slice(0, 3)} />
<ChartTooltip />
<ChartLegend />
<AreaChartSeries dataKey="mobile" />
<AreaChartSeries dataKey="desktop" />
</AreaChart>
</CardContent>
</Card>
);
}- Add the registryOnce per project
pnpm dlx shadcn@latest registry add @jarvis=https://ui.jarv.is/r/{name}.json - Add area-chart
pnpm dlx shadcn@latest add @jarvis/area-chart
Usage
import { AreaChart, AreaChartSeries } from "@/components/ui/area-chart";
import { ChartTooltip, ChartXAxis, type ChartConfig } from "@/components/ui/chart";
const data = [
{ month: "January", visitors: 186 },
{ month: "February", visitors: 305 },
{ month: "March", visitors: 237 },
];
const config = {
visitors: { label: "Visitors" },
} satisfies ChartConfig;
export function VisitorsChart() {
return (
<AreaChart data={data} config={config}>
<ChartXAxis dataKey="month" />
<ChartTooltip />
<AreaChartSeries dataKey="visitors" />
</AreaChart>
);
}AreaChartSeries draws one series. The axes, tooltip, legend and config come from
Chart. Stacked series stack in the order they're written, first at the bottom.
Composition
Examples
Fills
variant fills the area with a gradient, a flat tint or hatching.
import { AreaChart, AreaChartSeries } from "@/components/ui/area-chart";
import { ChartLegend, ChartTooltip, ChartXAxis, type ChartConfig } from "@/components/ui/chart";
const data = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 273, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 314, mobile: 140 },
];
const config = {
desktop: { label: "Desktop" },
mobile: { label: "Mobile" },
} satisfies ChartConfig;
export default function AreaChartFills() {
return (
<AreaChart data={data} config={config} stack="stacked" className="max-w-lg">
<ChartXAxis dataKey="month" tickFormatter={(month: string) => month.slice(0, 3)} />
<ChartTooltip />
<ChartLegend />
<AreaChartSeries dataKey="mobile" variant="hatched" />
<AreaChartSeries dataKey="desktop" variant="solid" />
</AreaChart>
);
}Expanded
stack="expanded" stretches each stack to full height to show shares.
import { AreaChart, AreaChartSeries } from "@/components/ui/area-chart";
import {
ChartGrid,
ChartLegend,
ChartTooltip,
ChartXAxis,
ChartYAxis,
type ChartConfig,
} from "@/components/ui/chart";
const data = [
{ month: "January", desktop: 186, mobile: 80, tablet: 42 },
{ month: "February", desktop: 305, mobile: 200, tablet: 61 },
{ month: "March", desktop: 237, mobile: 120, tablet: 58 },
{ month: "April", desktop: 273, mobile: 190, tablet: 70 },
{ month: "May", desktop: 209, mobile: 130, tablet: 49 },
{ month: "June", desktop: 314, mobile: 140, tablet: 66 },
];
const config = {
desktop: { label: "Desktop" },
mobile: { label: "Mobile" },
tablet: { label: "Tablet" },
} satisfies ChartConfig;
export default function AreaChartExpanded() {
return (
<AreaChart data={data} config={config} stack="expanded" className="max-w-lg">
<ChartGrid />
<ChartXAxis dataKey="month" tickFormatter={(month: string) => month.slice(0, 3)} />
<ChartYAxis tickFormatter={(share: number) => `${Math.round(share * 100)}%`} />
<ChartTooltip />
<ChartLegend />
<AreaChartSeries dataKey="tablet" />
<AreaChartSeries dataKey="mobile" />
<AreaChartSeries dataKey="desktop" />
</AreaChart>
);
}Forecast
A dashed, hatched series reads as an estimate. Leave a value out of a row to break the line.
import { AreaChart, AreaChartSeries } from "@/components/ui/area-chart";
import {
ChartGrid,
ChartLegend,
ChartTooltip,
ChartXAxis,
ChartYAxis,
type ChartConfig,
} from "@/components/ui/chart";
const data = [
{ month: "January", actual: 1240 },
{ month: "February", actual: 1380 },
{ month: "March", actual: 1310 },
{ month: "April", actual: 1520 },
{ month: "May", actual: 1610 },
{ month: "June", actual: 1740, forecast: 1740 },
{ month: "July", forecast: 1830 },
{ month: "August", forecast: 1960 },
{ month: "September", forecast: 2080 },
];
const config = {
actual: { label: "Actual" },
forecast: { label: "Forecast", color: "var(--chart-5)" },
} satisfies ChartConfig;
export default function AreaChartForecast() {
return (
<AreaChart data={data} config={config} className="max-w-lg">
<ChartGrid />
<ChartXAxis dataKey="month" tickFormatter={(month: string) => month.slice(0, 3)} />
<ChartYAxis tickFormatter={(signups: number) => signups.toLocaleString("en-US")} />
<ChartTooltip />
<ChartLegend />
<AreaChartSeries dataKey="actual" dots />
<AreaChartSeries dataKey="forecast" variant="hatched" dashed />
</AreaChart>
);
}Props
| Part | Extends |
|---|---|
| AreaChart | Chart |
| AreaChartSeries | Area |
AreaChart
| Prop | Type | Default |
|---|---|---|
configEach series' label, icon and color, keyed by its data key. | ChartConfig | — |
dataThe rows to plot, one object per point along the x-axis. | Record<string, unknown>[] | — |
stackHow the series combine: drawn over each other, stacked, or stacked and scaled to fill the height, so each shows its share. | "expanded" | "none" | "stacked" | "none" |
curveHow lines between points are drawn. A series can set its own. | CurveType | "monotone" |
children | React.ReactNode | — |
AreaChartSeries
| Prop | Type | Default |
|---|---|---|
dataKeyThe key of the series' values in each row, which also names it in the config. | string | — |
variantHow the area under the line is filled. | "gradient" | "hatched" | "solid" | "gradient" |
curveHow lines between points are drawn. Defaults to the chart's | CurveType | — |
dashedDraws the line dashed, as for a forecast. | boolean | false |
dotsMarks every point, not just the hovered one. | boolean | false |
AreaChartSeries takes the props of Recharts'
Area too, such as connectNulls.