Area
Magnitude and composition over an ordered dimension, with stacked layers, streamgraphs and direct labels.
import { area } from 'visdelta/area';area() shows magnitude over an ordered dimension and supports stacked detail.
import { area } from 'visdelta/area';
import { transition } from 'visdelta/transition';
import 'visdelta/style.css';
const listeners = [
{ month: '2026-01-01', genre: 'Jazz', hours: 12 },
{ month: '2026-02-01', genre: 'Jazz', hours: 15 },
{ month: '2026-03-01', genre: 'Jazz', hours: 14 },
{ month: '2026-04-01', genre: 'Jazz', hours: 18 },
{ month: '2026-05-01', genre: 'Jazz', hours: 16 },
{ month: '2026-01-01', genre: 'Folk', hours: 8 },
{ month: '2026-02-01', genre: 'Folk', hours: 11 },
{ month: '2026-03-01', genre: 'Folk', hours: 16 },
{ month: '2026-04-01', genre: 'Folk', hours: 13 },
{ month: '2026-05-01', genre: 'Folk', hours: 10 },
{ month: '2026-01-01', genre: 'Ambient', hours: 5 },
{ month: '2026-02-01', genre: 'Ambient', hours: 7 },
{ month: '2026-03-01', genre: 'Ambient', hours: 6 },
{ month: '2026-04-01', genre: 'Ambient', hours: 9 },
{ month: '2026-05-01', genre: 'Ambient', hours: 12 },
];
const from = area(listeners)
.x('month', { type: 'temporal', label: 'Month' })
.y('hours', { label: 'Listening hours' })
.key(['month', 'genre'])
.breakdown('genre')
.color('genre');
const to = from.layout('stream', { offset: 'wiggle', order: 'insideOut' });
const change = await transition(from, to, { target: '#chart' });
change.play({ duration: 800 }); // or change.progress(0.5)
Methods
| Method | Meaning |
|---|---|
.baseline(number) | Set the ordinary area baseline |
.curve(d3AreaCurveName) | Use an exact D3 curve export supported by d3.area() |
.connect('adjacent' | 'across') | Preserve gaps, or connect across filtered observations |
.breakdown(field, options?) | Split a total into stacked layers |
.rollup(options?) | Combine stacked layers into a total |
.layout('stacked' | 'stream', { offset?, order? }) | Use a fixed stack, or configure D3 stream offsets and orders |
.labels('inside' | 'none') | Label stacked layers inside their area |
The supported curve names are exported as D3_AREA_CURVE_NAMES. Unlike Line,
Area does not accept curveBundle.
Stacking and streams
Ordinary stacked areas place series with larger whole-domain totals nearer the baseline. Ties keep first-appearance order, and one fixed order applies across all x positions. When colour maps the stacked series with no explicit domain or palette, the legend and default colours follow the same ranking.
Stream layouts default to the wiggle offset and insideOut order. The
diverging offset supports signed values. To keep input layer order with a
fixed baseline, use:
detailed.layout('stream', { offset: 'none', order: 'none' });Direct labels
.labels('inside') identifies stacked and stream layers by their series value.
The renderer measures text, searches observation centres for a position where a
padded label fits inside the layer and picks black or white text for contrast.
Labels that cannot fit are omitted, and the colour legend still identifies those
layers. Custom label text, outside placement and callouts are not supported.
area(rows).x('year').y('revenue')
.breakdown('businessLine')
.color('businessLine')
.labels('inside');Transition behaviour
Area owns y0/y1 geometry. A divider line appears only during a detail
transition; endpoints have no default border.
Try it
Edit unemployment layers that settle into a stream in the playground.