AreaChart
Filled areas, stacked or expanded, solid or gradient, with a crosshair tooltip.
Default
A natural curve over a wash of the series color.
Showing total visitors for the last 6 months
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | 237 |
| April | 73 |
| May | 209 |
| June | 214 |
Code
<AreaChart data={rows} config={{ desktop: { label: "Desktop", color: "var(--chart-1)" } }}
x="month" curve="natural" margin={{ left: 12, right: 12 }}
categoryAxis={{ tickFormatter: (v) => String(v).slice(0, 3) }}
tooltip={{ indicator: "line", cursor: false }} />Usage
import { AreaChart } from "@elements/ui/chart-area";
import type { ChartConfig } from "@elements/ui/chart";
<AreaChart data={rows} {config} x="month" curve="natural" />
<AreaChart data={rows} {config} x="month" series={["mobile", "desktop"]}
stack="normal" fill="gradient" legend />Examples
Linear
curve=linear: straight edges.
Showing total visitors for the last 6 months
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | 237 |
| April | 73 |
| May | 209 |
| June | 214 |
Code
<AreaChart data={rows} {config} x="month" series={["desktop"]} curve="linear"
tooltip={{ indicator: "dot", hideLabel: true, cursor: false }} />Step
curve=step: a held value between categories.
Showing total visitors for the last 6 months
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | 237 |
| April | 73 |
| May | 209 |
| June | 214 |
Code
<AreaChart data={rows} {config} x="month" series={["desktop"]} curve="step"
tooltip={{ hideLabel: true, cursor: false }} />Legend
Stacked areas with a legend under the plot.
Showing total visitors for the last 6 months
- Mobile
- Desktop
| Month | Mobile | Desktop |
|---|---|---|
| January | 80 | 186 |
| February | 200 | 305 |
| March | 120 | 237 |
| April | 190 | 73 |
| May | 130 | 209 |
| June | 140 | 214 |
Code
<AreaChart data={rows} {config} x="month" series={["mobile", "desktop"]}
curve="natural" stack="normal" legend tooltip={{ indicator: "line", cursor: false }} />Stacked
stack=normal: each area sits on the one below.
Showing total visitors for the last 6 months
| Month | Mobile | Desktop |
|---|---|---|
| January | 80 | 186 |
| February | 200 | 305 |
| March | 120 | 237 |
| April | 190 | 73 |
| May | 130 | 209 |
| June | 140 | 214 |
Code
<AreaChart data={rows} {config} x="month" series={["mobile", "desktop"]}
curve="natural" stack="normal" tooltip={{ indicator: "dot", cursor: false }} />Stacked expanded
stack=expand: the stack fills the plot, each area is its share.
Showing total visitors for the last 6 months
| Month | Other | Mobile | Desktop |
|---|---|---|---|
| January | 45 | 80 | 186 |
| February | 100 | 200 | 305 |
| March | 150 | 120 | 237 |
| April | 50 | 190 | 73 |
| May | 100 | 130 | 209 |
| June | 160 | 140 | 214 |
Code
<AreaChart data={rows} config={{ desktop, mobile, other }} x="month"
series={["other", "mobile", "desktop"]} curve="natural" stack="expand"
margin={{ left: 12, right: 12, top: 12 }} tooltip={{ indicator: "line", cursor: false }} />Icons
A config icon replaces the swatch in the legend and tooltip.
Showing total visitors for the last 6 months
- Mobile
- Desktop
| Month | Mobile | Desktop |
|---|---|---|
| January | 80 | 186 |
| February | 200 | 305 |
| March | 120 | 237 |
| April | 190 | 73 |
| May | 130 | 209 |
| June | 140 | 214 |
Code
const config = {
desktop: { label: "Desktop", color: "var(--chart-1)", icon: "monitor" },
mobile: { label: "Mobile", color: "var(--chart-2)", icon: "smartphone" },
};
<AreaChart data={rows} {config} x="month" series={["mobile", "desktop"]}
curve="natural" stack="normal" legend tooltip={{ indicator: "line", cursor: false }} />Gradient
fill=gradient fades each area from the line down.
Showing total visitors for the last 6 months
| Month | Mobile | Desktop |
|---|---|---|
| January | 80 | 186 |
| February | 200 | 305 |
| March | 120 | 237 |
| April | 190 | 73 |
| May | 130 | 209 |
| June | 140 | 214 |
Code
<AreaChart data={rows} {config} x="month" series={["mobile", "desktop"]}
curve="natural" stack="normal" fill="gradient" tooltip={{ cursor: false }} />Axes
A value axis with three ticks; a negative left margin pulls the plot to the card edge.
Showing total visitors for the last 6 months
| Month | Mobile | Desktop |
|---|---|---|
| January | 80 | 186 |
| February | 200 | 305 |
| March | 120 | 237 |
| April | 190 | 73 |
| May | 130 | 209 |
| June | 140 | 214 |
Code
<AreaChart data={rows} {config} x="month" series={["mobile", "desktop"]}
curve="natural" stack="normal" margin={{ left: -20, right: 12 }}
valueAxis={{ tickCount: 3 }} tooltip={{ cursor: false }} />Interactive
A time range picks the rows; stacked gradient areas with a legend.
Showing total visitors for the last 3 months
- Mobile
- Desktop
| Date | Mobile | Desktop |
|---|---|---|
| 2024-04-01 | 356 | 286 |
| 2024-04-02 | 222 | 136 |
| 2024-04-03 | 333 | 267 |
| 2024-04-04 | 489 | 121 |
| 2024-04-05 | 293 | 326 |
| 2024-04-06 | 448 | 204 |
| 2024-04-07 | 152 | 353 |
| 2024-04-08 | 219 | 289 |
| 2024-04-09 | 186 | 359 |
| 2024-04-10 | 325 | 314 |
| 2024-04-11 | 141 | 160 |
| 2024-04-12 | 527 | 466 |
| 2024-04-13 | 307 | 138 |
| 2024-04-14 | 199 | 472 |
| 2024-04-15 | 351 | 258 |
| 2024-04-16 | 238 | 359 |
| 2024-04-17 | 534 | 158 |
| 2024-04-18 | 218 | 268 |
| 2024-04-19 | 259 | 309 |
| 2024-04-20 | 445 | 151 |
| 2024-04-21 | 267 | 231 |
| 2024-04-22 | 509 | 122 |
| 2024-04-23 | 491 | 185 |
| 2024-04-24 | 219 | 278 |
| 2024-04-25 | 289 | 331 |
| 2024-04-26 | 394 | 394 |
| 2024-04-27 | 214 | 144 |
| 2024-04-28 | 158 | 270 |
| 2024-04-29 | 293 | 109 |
| 2024-04-30 | 392 | 362 |
| 2024-05-01 | 256 | 472 |
| 2024-05-02 | 328 | 265 |
| 2024-05-03 | 472 | 266 |
| 2024-05-04 | 305 | 270 |
| 2024-05-05 | 219 | 196 |
| 2024-05-06 | 175 | 387 |
| 2024-05-07 | 442 | 198 |
| 2024-05-08 | 527 | 433 |
| 2024-05-09 | 481 | 461 |
| 2024-05-10 | 389 | 389 |
| 2024-05-11 | 130 | 312 |
| 2024-05-12 | 270 | 219 |
| 2024-05-13 | 285 | 176 |
| 2024-05-14 | 430 | 364 |
| 2024-05-15 | 522 | 197 |
| 2024-05-16 | 271 | 93 |
| 2024-05-17 | 305 | 324 |
| 2024-05-18 | 536 | 126 |
| 2024-05-19 | 486 | 273 |
| 2024-05-20 | 317 | 325 |
| 2024-05-21 | 453 | 140 |
| 2024-05-22 | 231 | 449 |
| 2024-05-23 | 185 | 100 |
| 2024-05-24 | 413 | 373 |
| 2024-05-25 | 485 | 354 |
| 2024-05-26 | 469 | 182 |
| 2024-05-27 | 136 | 157 |
| 2024-05-28 | 129 | 123 |
| 2024-05-29 | 469 | 305 |
| 2024-05-30 | 181 | 427 |
| 2024-05-31 | 142 | 288 |
| 2024-06-01 | 325 | 202 |
| 2024-06-02 | 269 | 116 |
| 2024-06-03 | 244 | 182 |
| 2024-06-04 | 177 | 406 |
| 2024-06-05 | 120 | 156 |
| 2024-06-06 | 156 | 340 |
| 2024-06-07 | 166 | 251 |
| 2024-06-08 | 294 | 281 |
| 2024-06-09 | 438 | 93 |
| 2024-06-10 | 430 | 271 |
| 2024-06-11 | 511 | 225 |
| 2024-06-12 | 388 | 377 |
| 2024-06-13 | 271 | 197 |
| 2024-06-14 | 490 | 121 |
| 2024-06-15 | 149 | 123 |
| 2024-06-16 | 248 | 165 |
| 2024-06-17 | 372 | 102 |
| 2024-06-18 | 278 | 266 |
| 2024-06-19 | 501 | 306 |
| 2024-06-20 | 297 | 301 |
| 2024-06-21 | 498 | 138 |
| 2024-06-22 | 330 | 355 |
| 2024-06-23 | 405 | 453 |
| 2024-06-24 | 526 | 273 |
| 2024-06-25 | 295 | 444 |
| 2024-06-26 | 415 | 289 |
| 2024-06-27 | 504 | 405 |
| 2024-06-28 | 536 | 308 |
| 2024-06-29 | 468 | 344 |
| 2024-06-30 | 152 | 266 |
Code
<select value={state.range}>...</select>
<AreaChart data={inRange(state.range)} config={dailyConfig} x="date"
series={["mobile", "desktop"]} curve="natural" stack="normal" fill="gradient"
legend class="chart-demo-wide"
categoryAxis={{ tickFormatter: shortDate, minTickGap: 32 }}
tooltip={{ indicator: "dot", cursor: false, labelFormatter: (_, row) => shortDate(row.date) }} />Missing values
A null breaks the area; connectNulls fills across it.
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | |
| April | 73 |
| May | 209 |
| June | 214 |
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | |
| April | 73 |
| May | 209 |
| June | 214 |
Code
<!-- a null breaks the area unless connectNulls -->
<AreaChart data={rowsWithNulls} {config} x="month" series={["desktop"]} />
<AreaChart data={rowsWithNulls} {config} x="month" series={["desktop"]} connectNulls />Labels
Each point's value above the area.
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | 237 |
| April | 73 |
| May | 209 |
| June | 214 |
Code
<AreaChart data={rows} {config} x="month" series={["desktop"]} curve="natural"
margin={{ top: 20, left: 12, right: 12 }}
labels={{ position: "top", offset: 8 }} tooltip={{ cursor: false }} />Dots, opacity and toggles
Dots on every point, a lighter fill, a thicker line, and a legend that hides series.
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<AreaChart data={rows} {config} x="month" dots fillOpacity={0.15} strokeWidth={3}
legend={{ toggle: true, position: "top" }} hidden={state.hidden} />Controlled and keyboard
Areas with no stroke. Tab to the chart, then arrows, Home, End and Escape.
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<AreaChart data={rows} {config} x="month" stack="normal" stroke={false}
active={state.active} onActiveChange={() => state.changes++}
onItemClick={(i) => state.clicked = i} />Vertical layout
Months run down the chart and the stacked values across it.
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<!-- months down the chart, values across -->
<AreaChart data={rows} {config} x="month" layout="vertical" stack="normal" valueAxis />Two value axes
Desktop on the left axis, mobile on its own right axis, each scaled to its data.
- Desktop
- Mobile
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<!-- mobile on a second value axis on the right -->
<AreaChart data={rows} {config} x="month" valueAxis={[{}, { orientation: "right", series: ["mobile"] }]} />Base value
baseValue 200 fills between the line and a target of 200, above and below it.
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | 237 |
| April | 73 |
| May | 209 |
| June | 214 |
Code
<!-- fill toward a target of 200 rather than down to zero;
"dataMin" and "dataMax" fill to the bottom or the top of the axis -->
<AreaChart data={rows} {config} x="month" series={["desktop"]} baseValue={200} valueAxis />Streamgraph
stack wiggle and silhouette center the layers instead of stacking them on zero.
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<!-- a streamgraph: layers around a moving center line -->
<AreaChart data={rows} {config} x="month" stack="wiggle" curve="basis" valueAxis />
<AreaChart data={rows} {config} x="month" stack="silhouette" curve="monotone" valueAxis />Animation timing
animation sets when the marks start moving, how long they take and their easing: a CSS easing name, a cubic-bezier, spring, or a function of progress.
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<!-- wait 150ms, then take 900ms to enter or move to new data -->
<AreaChart data={rows} {config} x="month" stack="normal"
animation={{ begin: 150, duration: 900, easing: "linear" }} />Legend and tooltip types
legendType on a config entry sets that series' legend icon, and none leaves a drawn series out of the legend; tooltipType none leaves it out of the tooltip.
- Desktop
- Mobile
| Month | Desktop | Mobile | Other |
|---|---|---|---|
| January | 186 | 80 | 45 |
| February | 305 | 200 | 100 |
| March | 237 | 120 | 150 |
| April | 73 | 190 | 50 |
| May | 209 | 130 | 100 |
| June | 214 | 140 | 160 |
Code
<!-- desktop's legend icon is a line; mobile is left out of the tooltip, other out of the legend -->
<AreaChart data={rows} x="month" legend config={{
desktop: { label: "Desktop", color: "var(--chart-1)", legendType: "line" },
mobile: { label: "Mobile", color: "var(--chart-2)", tooltipType: "none" },
other: { label: "Other", color: "var(--chart-3)", legendType: "none" },
}} />Dashed edge
strokeDasharray and strokeOpacity on a config entry dash that area's edge and fade it; the other edges stay solid.
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<!-- strokeDasharray and strokeOpacity on a config entry style that area's edge -->
<AreaChart data={rows} x="month" config={{
desktop: { label: "Desktop", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)", strokeDasharray: "4 4", strokeOpacity: 0.5 },
}} />Reverse stack order
reverseStackOrder stacks the last series first, so the first sits on top; the legend and tooltip keep series order.
- Desktop
- Mobile
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<!-- desktop stacks on top; legend and tooltip keep series order -->
<AreaChart data={rows} {config} x="month" stack="normal" reverseStackOrder legend />Data table
The data as a table; showTable shows it.
| Month | Desktop | Mobile |
|---|---|---|
| January | 186 | 80 |
| February | 305 | 200 |
| March | 237 | 120 |
| April | 73 | 190 |
| May | 209 | 130 |
| June | 214 | 140 |
Code
<AreaChart data={rows} {config} x="month" showTable={state.table} />Moving to new data
animation matchBy pairs old and new items by a key, so each month slides to its new place; interpolate draws every frame with a function of your own, here one that starts each point after the one before.
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | 237 |
| April | 73 |
| May | 209 |
| June | 214 |
| Month | Desktop |
|---|---|
| January | 186 |
| February | 305 |
| March | 237 |
| April | 73 |
| May | 209 |
| June | 214 |
Code
<!-- each month keeps its point: the window slides instead of every point changing value -->
<AreaChart data={rows} {config} x="month" animation={{ matchBy: matchByDataKey("month") }} />
<!-- (items, t) => the items to draw: each matched item from prev to next, started one after another -->
<AreaChart data={rows} {config} x="month" animation={{ interpolate: stagger }} />