English
Stacked area
D3PStack derives one series per input with the base (y0) of each layer; D3PAreaRenderer draws between the base and the top by itself. An auto domain linked to the layers covers them.
ts
import * as d3 from 'd3'
import {
D3PAreaRenderer, D3PAutoDomain, d3pAutoInteractionArea, D3PAxis, D3PAxisDomain, D3PChart,
D3PCursorIndicator, d3pDomLegend, d3pDomTooltip, D3PLegendBundle, D3PSeries, D3PStack, type D3PStackOffset,
type D3PStackOrder, D3PTooltip, getGlobalBus,
} from 'd3pict'
// your series data: replace these generators with your own values
import { walk } from './data'
const bus = getGlobalBus()
const container = document.getElementById('app')! // any element with a size: the chart fills it
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
const COLORS = d3.schemeTableau10
const month = (v: unknown) => MONTHS[Math.round(Number(v))] ?? ''
/** A series of numbers over 12 months, x being the month index. */
const monthly = (seed: number, base: number, spread: number) => walk(seed, 12, base, spread, 5, 100).map((v, i) => [i, v] as [number, number])
const offset = 'none' as D3PStackOffset
const order = 'none' as D3PStackOrder
const names = ['Search', 'Social', 'Direct', 'Email']
const inputs = names.map((name, i) => new D3PSeries({ bus, name, data: monthly(i + 1, 25, 18) }))
// the stack derives one series per input, with the base (y0) of each layer
const stack = new D3PStack({ bus, series: inputs, offset, order })
const dx = new D3PAxisDomain({ bus, domain: [0, 11] })
const dy = new D3PAxisDomain({ bus, domain: [0, 1] })
const auto = new D3PAutoDomain({ bus })
for (const layer of stack.series) auto.linkSeries(layer, [dx, dy])
const x = new D3PAxis({ bus, name: 'x', domain: dx, props: { tickFormat: month } })
const y = new D3PAxis({ bus, name: 'y', domain: dy, position: 'left', props: { grid: { enabled: true }, tickFormat: offset === 'expand' ? d3.format('.0%') : null } })
const layers = stack.series.map((layer, i) => new D3PAreaRenderer({ bus, series: layer, props: { style: { color: COLORS[i], opacity: 0.85, curve: 'monotone' } } }))
const cursor = new D3PCursorIndicator({ bus })
const tooltip = new D3PTooltip({ bus })
const legend = new D3PLegendBundle({ bus })
const objects = [x, y, ...layers, cursor, tooltip, legend]
const chart = new D3PChart({ container, bus })
const stopArea = d3pAutoInteractionArea(chart) // before the objects: the cursor, the tooltip and the tools ask for an interaction area
objects.forEach((o) => o.addToChart(chart))
const stopTooltip = d3pDomTooltip(tooltip)
const stopLegend = d3pDomLegend(legend)