Published
Edited
Mar 4, 2021
Fork of Hierarchies
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Nest with the super_cat variable
nest = d3
.nest()
.key(d => d.super_cat)
.entries(data)
.map(d => {
return {
name: d.key,
children: d.values
};
})
Insert cell
// Subnest with the sub_cat variable
nest.forEach(
d =>
(d.children = d3
.nest()
.key(x => x.sub_cat)
.entries(d.children)
.map(x => {
return {
name: x.key,
value: x.values[0].value
};
}))
)
Insert cell
formattedData = ({ name: "States", children: nest })
Insert cell
Insert cell
Insert cell
import { chart as sun_chart } with { formattedData as data } from '@d3/sunburst'
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Modified from: https://observablehq.com/@d3/tidy-tree
tree_chart = {
const root = tree(data2);

let x0 = null;
let x1 = null;
root.each(d => {
if (d.x > x1) x1 = d.x;
if (d.x < x0) x0 = d.x;
});

const unnested = raw_data.filter(d => d.date == "2020-03-01");

const max = d3.max(data2.children, d => +d.value);

const sizeScale = d3
.scaleLinear()
.range([0, max])
.domain([0, max]);

const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, x1 - x0 + root.dx * 2]);

const g = svg
.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.attr("transform", `translate(${root.dy / 3},${root.dx - x0})`);

const link = g
.append("g")
.attr("fill", "none")
.attr("stroke", "#555")
.attr("stroke-opacity", 0.4)
.attr("stroke-width", 1.5)
.selectAll("path")
.data(root.links())
.join("path")
.attr(
"d",
d3
.linkHorizontal()
.x(d => d.y)
.y(d => d.x)
);

const node = g
.append("g")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 3)
.selectAll("g")
.data(root.descendants())
.join("g")
.attr("transform", d => `translate(${d.y},${d.x})`);

node
.append("circle")
.attr("fill", d => (d.children ? "#555" : "#999"))
.attr("r", d => (d.data.value ? sizeScale(d.data.value) : sizeScale(max)));

node
.append("text")
.attr("dy", "0.31em")
.attr("x", d => (d.children ? -6 : 6))
.attr("text-anchor", d => (d.children ? "end" : "start"))
.text(d => d.data.name)
.clone(true)
.lower()
.attr("stroke", "white");

return svg.node();
}
Insert cell
// Filtering to March 1st, as otherwise the tree would be MASSIVE
data2 = {
const csv = await FileAttachment("us-counties.csv").text();
var data2 = d3.csvParse(csv);

var data2 = data2.filter(d => d.date == "2020-03-01");
data2 = _.uniqBy(data2, d => d.fips);
data2 = d3
.nest()
.key(d => d.state)
.entries(data2)
.map(d => {
return {
name: d.key,
children: d.values,
value: d3.sum(d.values, v => +v.cases)
};
});

data2.forEach(
d =>
(d.children = d3
.nest()
.key(x => x.county)
.entries(d.children)
.map(x => {
return {
name: x.key,
value: x.values[0].cases
};
}))
);

data2 = { name: "Early Regions", children: data2 };
return data2;
}
Insert cell
tree = data => {
const root = d3.hierarchy(data2);
root.dx = 30;
root.dy = width / (root.height + 1);
return d3.tree().nodeSize([root.dx, root.dy])(root);
}
Insert cell
Insert cell
Insert cell
tree_map
Insert cell
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