Show a revenue mix with a stacked area chart
By the end of this recipe you'll have two-to-three components summing to a total over time — the silhouette gives you the total, the bands give you the mix.
Overview
Bands stacked on top of one another. The top edge is the total; each band is one component.
Stacked areas answer two questions at once: "how is the total trending?" and "what's the mix made of?". Reach for them when the components naturally add up — revenue by channel, costs by category, gold weight by purity. The total reads off the silhouette; the mix reads off the bands.
Skip stacked area if the components are independent (use a multi-line — stacking falsely implies they sum), or if there are more than four bands (the lower ones become unreadable). For two-to-three components with a clear total story, it's the cleanest chart in the kit.
Default opinion: the bottom band is the one your eye reads most accurately. Put your most important component there.
The chart
Revenue by channel — POS, online, and wholesale — summed to the silhouette across thirty days.
Required pieces
Everything this recipe pulls from @corelithzw/react.
Intended exports used here: Chart.Area, Chart.Legend.
Chart.Area with stack ships in @corelithzw/react v0.2.
The React snippet
Set stack to add the series together rather than overlaying them.
Customising
Three forks.
Switch to percent-stacked
If the question is "what's the share?" rather than "what's the total?", normalise each column to 100%.
<Chart.Area
data={data}
stack="percent"
series={mySeries}
yFormat={(v) => `${Math.round(v * 100)}%`}
height={280}
/>
Show the total line
Overlay a stronger stroke along the top edge so the reader sees the silhouette as a real line, not just an edge.
<Chart.Area
data={data}
stack
series={mySeries}
totalLine {/* draws the silhouette */}
height={280}
/>
Reduce visual noise
Drop the gridlines and y-axis labels when the chart lives inside a dense dashboard — the silhouette alone tells the story.
<Chart.Area
data={data}
stack
axes="x"
grid="none"
height={220}
/>
In context
Inside a revenue-mix card. The legend doubles as a "click to isolate" filter.
Accessibility
Bands are harder to read than lines — the labels do the heavy lifting.
- Role and label. Root
<svg>usesrole="img"+aria-labelledbypointing to inline<title>+<desc>. - Each band has a name. Wrap each
<path>in a<g aria-label="POS">so the screen reader can announce it. - Screen-reader summary. A visually-hidden paragraph (
.ck-sr-only) restates the start/end totals and per-channel share. - Pattern fills, not only colour. If you need accessible-by-default, add a low-opacity stripe pattern to one band so colour-blind readers see structure.
- Keyboard. Each band is
tabindex="0"; Arrow keys walk between data columns inside one band.