Public
Edited
Jan 7
Insert cell
Insert cell
Insert cell
Insert cell
rolled = d3.rollup(
cars,
V => V.length,
d => d.year,
d => d.name.split(" ")[0],
)
Insert cell
Insert cell
stack = d3.stack()
.keys(manufacturers)
// value() normally expects wide format data. like {"AMC": 3} as its input. We dont have that.
// Instead value will recieve the entries in our (outer) internmap.
// We can unpack that and return the value from the (inner) internmap for each key.
.value(([year, counts], key) => {
return counts.get(key)
})
.order(d3.stackOrderDescending)
Insert cell
Insert cell
stack(rolled)
Insert cell
Insert cell
flattened = stack(rolled).flatMap((group, i) => group.map((d, j) => [
...d,
[...rolled.keys()][j],
manufacturers[i]
]))
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.barY(
flattened,
{
y1: d => d[0],
y2: d => d[1],
x: d => d[2],
fill: d => d[3],
title: d => `${d[3]}: ${d[1] - d[0]}`,
stroke: "white",
tip: "xy"
}
),
Plot.tip(
flattened,
Plot.pointer({
x: "year",
y1: "y1",
y2: "y2",
title: d => `${d[3]}: ${d[1] - d[0]}`,
fill: "#black"
})
)
],
x: {label: "Year"},
y: {label: "# Cars by Manufacturer"}
})
Insert cell
Insert cell
function rollupStack() {

let value = (D) => D.length;
let group = (d, i) => i;
let key = (d, i) => i;
const stack = d3.stack().value(
([, group], key) => group.get(key)
)
function main(data) {
stack.keys([...d3.union(data.map( d => key(d)))]);
const rolled = d3.rollup(data, value, group, key);
const stackKeys = stack.keys()();
const rollKeys = [...rolled.keys()];
return stack(rolled).flatMap((group, i) => {
return group.map(([start, end, ...rest] , j) => {
return [start, end, rollKeys[j], stackKeys[i], ...rest];
})
})
}
// Stack Options
main.order = (x) => {
if (x === undefined) return stack.order();
stack.order(x)
return main;
}
main.offset = (x) => {
if (x === undefined) return stack.offset();
stack.offset(x);
return main;
}
// Rollup Options
main.value = (x) => {
if (x === undefined) return value;
value = x;
return main;
}
main.group = (x) => {
if (x === undefined) return group;
group = x;
return main;
}
main.key = (x) => {
if (x === undefined) return key;
key = x;
return main;
}
return main
}
Insert cell
rs = rollupStack()
.group(d => d.year)
.key(d => d.name.split(" ")[0])
.value(D => D.length)
.order(d3.stackOrderDescending)
Insert cell
Plot.barY(rs(cars), {
x: d => d[2],
y1: d => d[0],
y2: d => d[1],
fill: d => d[3],
title: d => `${d[3]}: ${d[1] - d[0]}`,
tip: "xy",
stroke: "white"
}).plot()

Insert cell
Inputs.table(cars.filter(d => d.year == 77 && d.name.startsWith("Subaru")))
Insert cell
Insert cell
{

const rs2 = rollupStack()
.group(d => d.date)
.key(d => d.industry)
.value(D => d3.sum(D, d => d.unemployed))
.order(d3.stackOrderInsideOut)
.offset(d3.stackOffsetWiggle)
const stacked = rs2(industries);
return Plot.plot({
marks: [
Plot.areaY(
stacked,
{
x: d => d[2],
y1: d => d[0],
y2: d => d[1],
fill: d => d[3],
title: d => `${d[3]} (${d[2].getFullYear()}): ${d3.format('.0d')(d[1] - d[0])}`,
tip: "xy",
stroke: "white"
}
)
],
y: {label: "Unemployment"},
x: {label: "Year"},
color: {legend: true, label: "Industry"},
height: 500,
width
})

}
Insert cell
industries

Insert cell
// Get our unique keys for the stack.
manufacturers = [...d3.union(cars.map(d => d.name.split(" ")[0]))]
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