Public
Edited
Sep 16, 2022
Fork of Simple D3
2 forks
2 stars
Insert cell
Insert cell
Insert cell
svg = {
const svg = d3.select(DOM.svg(width, height));

const graph = d3
.csvParse(myData, types)
.map((d) => ({ ...d, t: 0 })) //add the .t property, initially at 0
.sort((a, b) => b.size - a.size); //sort the nodes so that the bigger ones are at the back

console.log('graph: ', graph);

let hovered; //a sort of flag to check if the circle is hovered

//update the simulation based on my data
/* simulation.nodes(myData) create the nodes with our data (a list of objects) by inserting
the typical properties of the nodes (index, x, y, vx, vy) used for the simulation,
for more info: https://github.com/d3/d3-force */
simulation
.nodes(graph)
.force("collide", collide)
.on("tick", () => {
node
.attr("r", (d) => {
d.t = (d === hovered) ? (1-(1-d.t)*0.96) : (d.t*0.96); //lower 0.9X value to handle transition time
d.r = (d.r >= 75) ? (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)
.attr("fill", (d) => color(d.continent));
collide
.radius((d) => d.r + nodePadding); //here set node radius based on d.r and d.t values
text
.text((d) => d.country)
.attr("visibility", (d) => (d.r >= 45) ? "visible" : "hidden")
.attr("x", (d) => d.x)
.attr("y", (d) => d.y)
.attr("text-anchor", "middle")
.attr("alignment-baseline", "central")
.attr("font-size", 12)
.attr("font-weight", "bold")
.attr("font-family", "sans-serif");
})
.alpha(1)
.restart();

const node = svg
.append("g")
.selectAll("circle")
.data(graph)
.join("circle");

const text = svg
.append('g')
.selectAll('text')
.data(graph)
.join('text')
.style("pointer-events", "none");

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
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
collide = d3
.forceCollide()
.strength(0.5)
.radius((d) => d.radius + nodePadding)
.iterations(1);
Insert cell
nodePadding = 4.5;
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