Published unlisted
Edited
Sep 4, 2022
Insert cell
Insert cell
Insert cell
svg = {
const svg = d3.select(DOM.svg(width, height));
const nodePadding = 2.5;

const graph = d3
.csvParse(myData, types)
.map((d) => ({ ...d, t: 0 }))
.sort((a, b) => b.size - a.size);

// update the simulation based on the data
let hovered;
const collide = d3
.forceCollide()
.strength(0.5)
.radius((d) => d.radius + nodePadding)
.iterations(1);
simulation
.nodes(graph)
.force("collide", collide)
.on("tick", () => {
node
.attr("r", (d) => {
d.t = d === hovered ? 1 - (1 - d.t) * 0.9 : d.t * 0.9;
d.r = (1 - d.t) * d.radius + d.t * Math.max(d.radius * 1.2, 50);
return d.r;
})
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y);
collide.radius((d) => d.r + nodePadding);
})
.alpha(1)
.restart();

const node = svg
.append("g")
.attr("class", "node")
.selectAll("circle")
.data(graph)
.join("circle")
.attr("fill", (d) => color(d.continent));

node
.on("pointerenter", (event, d) => {
hovered = d;
simulation.tick();
})
.on("pointerout", (event, d) => {
hovered = null;
simulation.tick();
});

node.call(
d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended)
);

return svg.node();
}
Insert cell
color = d3.scaleOrdinal([
"#66c2a5",
"#fc8d62",
"#8da0cb",
"#e78ac3",
"#a6d854",
"#ffd92f",
"#e5c494",
"#b3b3b3"
])
Insert cell
simulation = d3.forceSimulation()
.force("forceX", d3.forceX().strength(.1).x(width * .5))
.force("forceY", d3.forceY().strength(.1).y(height * .5))
.force("center", d3.forceCenter().x(width * .5).y(height * .5))
.force("charge", d3.forceManyBody().strength(-15));
Insert cell
function dragstarted(event, d) {
if (!event.active) simulation.alphaTarget(0.03).restart();
d.fx = d.x;
d.fy = d.y;
}
Insert cell
function dragged(event, d) {
d.fx = event.x;
d.fy = event.y;
}
Insert cell
function dragended(event, d) {
if (!event.active) simulation.alphaTarget(0.03);
d.fx = null;
d.fy = null;
}
Insert cell
function types(d) {
const sizeDivisor = 100;
d.gdp = +d.gdp;
d.size = +d.gdp / sizeDivisor;
d.size < 3 ? (d.radius = 3) : (d.radius = d.size);
return d;
}
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