Stacked area chart
FreeParts of a whole over time, stacked from the baseline. Switching between values and share morphs the same layers, so growth and share read as one picture.
pnpm dlx shadcn@latest add https://caliperui.site/r/stacked-area-chart.json| Period | Starter | Team | Enterprise | Total |
|---|---|---|---|---|
| Jan | 18 | 24 | 30 | 72 |
| Feb | 20.2 | 27.1 | 30.55 | 77.85 |
| Mar | 22.4 | 30.2 | 32.2 | 84.8 |
| Apr | 21.6 | 33.3 | 34.95 | 89.85 |
| May | 23.8 | 36.4 | 38.8 | 99 |
| Jun | 26 | 39.5 | 43.75 | 109.25 |
| Jul | 25.2 | 42.6 | 49.8 | 117.6 |
| Aug | 27.4 | 45.7 | 56.95 | 130.05 |
| Sep | 29.6 | 48.8 | 65.2 | 143.60000000000002 |
| Oct | 28.799999999999997 | 51.900000000000006 | 74.55000000000001 | 155.25 |
| Nov | 31 | 55 | 85 | 171 |
| Dec | 33.2 | 58.1 | 96.55000000000001 | 187.85000000000002 |
When to use #
Use it for
- Revenue by plan, traffic by source or spend by team across months.
- Questions about both size and mix.
Skip it when
- Series that do not add up to a total; use the line chart.
- More than five or six layers; the middle ones become unreadable.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/stacked-area-chart.json
Adds its 7 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
import { StackedAreaChart } from "@/components/ui/stacked-area-chart" const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; const planMix = months.map((label, i) => ({ id: label, label, values: { starter: 18 + i * 1.2 + (i % 3), team: 24 + i * 3.1, enterprise: 30 + i * i * 0.55 }, })); const plans = [ { id: "starter", label: "Starter" }, { id: "team", label: "Team" }, { id: "enterprise", label: "Enterprise" }, ]; export function StackedAreaChartDemo() { return <StackedAreaChart label="MRR by plan, 2026 ($k)" data={planMix} series={plans} formatValue={(v) => `$${Math.round(v)}k`} className="w-full" />; }
API reference #
StackedAreaChart
component
Accessibility #
It exposes group and status semantics, with aria-label, aria-busy and aria-hidden kept in step with state. Changes that matter are announced through a live region.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.