Public
Edited
Jan 12, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
contested = data
.filter(d => d.category === "none")
.sort((a, b) => d3.descending(a.votes, b.votes))
Insert cell
totalD = d3.sum(data.filter(d => d.category === "D").map(d => d.votes))
Insert cell
totalR = d3.sum(data.filter(d => d.category === "R").map(d => d.votes))
Insert cell
decided = new Map(
Object.entries(selectStates).filter(([key, value]) => value !== "none")
)
Insert cell
treeData = {
const root = {
name: "",
votes: 0,
votesD: totalD,
votesR: totalR,
pruned: false
};
function buildTree(node, depth) {
if (depth < contested.length && !winner(node)) {
const state = contested[depth];
node.children = [
{
name: state.name,
shortname: state.shortname,
party: "D",
votes: state.votes,
votesD: node.votesD + state.votes,
votesR: node.votesR,
pruned:
node.pruned ||
(decided.has(state.name) && decided.get(state.name) === "R")
},
{
name: state.name,
shortname: state.shortname,
party: "R",
votes: state.votes,
votesD: node.votesD,
votesR: node.votesR + state.votes,
pruned:
node.pruned ||
(decided.has(state.name) && decided.get(state.name) === "D")
}
];
node.children.forEach(child => buildTree(child, depth + 1));
}
return node;
}
return buildTree(root, 0);
}
Insert cell
function autoBox() {
document.body.appendChild(this);
const { x, y, width, height } = this.getBBox();
document.body.removeChild(this);
return [x - 5, y, width + 10, height];
}
Insert cell
tree = d3
.cluster()
.size([2 * Math.PI, radius])
.separation((a, b) => (a.parent == b.parent ? 1 : 2) / a.depth)
Insert cell
radius = 390
Insert cell
targetWidth = Math.min(width, radius * 2)
Insert cell
circleSize = d3
.scaleSqrt()
.domain(d3.extent(contested.map(d => d.votes)))
.range([2.5, 6.5])
Insert cell
votesScale = d3
.scaleLinear()
.domain([0, 538])
.range([0, targetWidth])
Insert cell
result = d =>
d.votesD > 269
? "D"
: d.votesR > 269
? "R"
: d.votesD === 269 && d.votesR === 269
? "tie"
: null
Insert cell
winner = d => {
const outcome = result(d);
return !outcome || outcome === "tie" ? null : outcome;
}
Insert cell
partyColor = d => (d.party === "D" ? colorD : d.party === "R" ? colorR : "#888")
Insert cell
colorD = "#2a72c9"
Insert cell
colorR = "#c92a2a"
Insert cell
prunedOpacity = 0.05
Insert cell
normalOpacity = 0.3
Insert cell
fullOpacity = 1.0
Insert cell
strokeOpacity = (pruned, highlight) =>
pruned ? prunedOpacity : highlight ? fullOpacity : normalOpacity
Insert cell
stateLabel = d => (width > 800 ? d.name : d.shortname)
Insert cell
candidateD = "Biden"
Insert cell
candidateR = "Trump"
Insert cell
import { form } from "@mbostock/form-input"
Insert cell
d3 = require("d3@6")
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more