Unlisted
Edited
Sep 23, 2024
1 fork
1 star
Insert cell
Insert cell
{
const formatSum = d3.format(".1s");

const padding = 10;

const r = 74; // constant radius

const color = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

const arc = d3.arc()
.padRadius(50);

const pie = d3.pie()
.sort(null)
.padAngle(0.02)
.value((d) => d.population);

color.domain(data.columns.slice(1));

const legend = d3.select("body").append("svg")
.attr("class", "legend")
.attr("width", 120)
.attr("height", (data.columns.length - 1) * 20)
.selectAll("g")
.data(data.columns.slice(1).reverse())
.enter().append("g")
.attr("transform", (d, i) => `translate(0,${i * 20})`);

legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);

legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.text((d) => d);

const wrapper = d3.create("div");
const svg = wrapper.selectAll(".pie")
.data(data.sort((a, b) => b.sum - a.sum))
.enter().append("svg")
.attr("class", "pie")
.each(multiple)
.select("g");

const label = svg.append("text")
.attr("class", "label");

label.append("tspan")
.attr("class", "label-name")
.attr("x", 0)
.attr("dy", "-.2em")
.text((d) => d.state);

label.append("tspan")
.attr("class", "label-value")
.attr("x", 0)
.attr("dy", "1.1em")
.text((d) => formatSum(d.sum));

function multiple(d) {
const svg = d3.select(this)
.attr("width", r * 2)
.attr("height", r * 2)
.append("g")
.attr("transform", `translate(${r},${r})`);

svg.selectAll(".arc")
.data((d) => pie(d.ages))
.enter().append("path")
.attr("class", "arc")
.attr("d", arc.outerRadius(r).innerRadius(r * 0.6))
.style("fill", (d) => color(d.data.age));
}

wrapper.append("style").text(`
.pie {margin: 4px;}
.legend {vertical-align: top;}
.label {font: 10px sans-serif;text-anchor: middle;}
.label-name {font-weight: bold;}
`);
return wrapper.node();
}
Insert cell
data = FileAttachment("state-age.csv")
.csv()
.then((data) => {
const columns = data.columns.slice(1);
data.forEach((d, i) => data[i] = ({
state: d.State,
sum: d3.sum(columns, (key) => +d[key]),
ages: columns.map((key) => ({ age: key, population: +d[key] }))
}));
return data;
})
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