svg = {
const svg = d3.select(DOM.svg(width, height));
const graph = d3
.csvParse(myData, types)
.map((d) => ({ ...d, t: 0 }))
.sort((a, b) => b.size - a.size);
let hovered;
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);
d.r = (d.r>=50) ? (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);
path
.attr("d", d => drawArcs(d))
.attr('transform', d => `translate(${d.x}, ${d.y})`)
.attr("fill", "transparent")
text
.attr("visibility", (d) => (d.r >= 20) ? "visible" : "hidden")
.attr("fill", "#ff00ff")
.attr("letter-spacing", ".05rem")
.attr("font-size", 16)
.attr("font-weight", "bold")
.attr("font-family", "sans-serif")
.attr("startOffset", "72%")
.attr('text-anchor', 'middle')
})
.alpha(1)
.restart();
const node = svg
.append("g")
.selectAll("circle")
.data(graph)
.join("circle")
const path = svg
.append("g")
.selectAll("path")
.data(graph)
.join("path")
.attr("id", d => d.country)
.style("pointer-events", "none")
const text = svg
.append("g")
.selectAll("text")
.data(graph)
.join("text")
.style("pointer-events", "none")
.append("textPath")
.attr("href", (d) => "#" + d.country)
.text(d => d.country)
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();
}