Published
Edited
Jun 29, 2020
Insert cell
Insert cell
md`## Plot`
Insert cell
{
const svg = d3.select(DOM.svg(width, height));

svg.append('g').call(xAxis);
svg.append('g').call(yAxis);

const group = svg
.append('g')
.selectAll('g')
.data(data.series)
.join('g')
.attr('transform', d => `translate(0, ${y(d.name)})`);

group
.append('path')
.attr('fill', '#eee')
.attr('d', d => area(d.values));

group
.append('path')
.attr('fill', 'none')
.attr('stroke', '#222')
.attr('d', d => line(d.values));

return svg.node();
}
Insert cell
Insert cell
overlap = 3
Insert cell
Insert cell
Insert cell
x = d3
.scaleTime()
.domain(d3.extent(data.dates))
.range([margin.left, width - margin.right])
Insert cell
y = d3
.scalePoint()
.domain(data.series.map(d => d.name))
.range([margin.top, height - margin.bottom])
Insert cell
z = d3
.scaleLinear()
.domain([0, d3.max(data.series, d => d3.max(d.values))])
.nice()
.range([0, -overlap * y.step()])
Insert cell
xAxis = g =>
g
.attr('transform', `translate(0,${height - margin.bottom})`)
.call(
d3
.axisBottom(x)
.ticks(width / 80)
.tickSizeOuter(0)
)
.call(g => g.select('.domain').remove())
Insert cell
yAxis = g =>
g
.attr('transform', `translate(${margin.left}, 0)`)
.call(
d3
.axisLeft(y)
.tickSize(0)
.tickPadding(4)
)
.call(g => g.select('.domain').remove())
Insert cell
area = d3
.area()
.curve(d3.curveBasis)
.defined(d => !isNaN(d))
.x((d, i) => x(data.dates[i]))
.y0(0)
.y1(d => z(d))
Insert cell
line = area.lineY1()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more