Unlisted
Edited
Nov 28, 2022
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 }))
.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); //here set node radius based on d.r and d.t values

path
.attr("d", d => drawArcs(d))
.attr('transform', d => `translate(${d.x}, ${d.y})`)
.attr("fill", "transparent") //#ff0000

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") //Helvetica Neue, Arial

.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();
}
Insert cell
Insert cell
Insert cell
Insert cell
nodePadding = 6.5;
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
//combinations
function drawArcs(d) {
const arc = d3.arc()

//zero
.innerRadius(d.r-5)
.outerRadius(d.r)
.startAngle(0)
.endAngle(2*Math.PI)

/* //first and second
.innerRadius(d.r+15)
.outerRadius(d.r)
.startAngle(0)
.endAngle(2*Math.PI)

//first and second
.innerRadius(d.r+5)
.outerRadius(d.r)
.startAngle(Math.PI)
.endAngle(-Math.PI)

//third
.innerRadius(d.r+15)
.outerRadius(d.r)
.startAngle(40)
.endAngle(-20)
//fourth
.innerRadius(0)
.outerRadius(d.r+5)
.startAngle(-Math.PI)
.endAngle(Math.PI)

//fifth
.innerRadius(0)
.outerRadius(d.r)
.startAngle(Math.PI*2)
.endAngle(0)
//sixth
.innerRadius(0)
.outerRadius(d.r+15)
.startAngle(Math.PI*2)
.endAngle(0)
*/

return arc();
}

/* ---------- to put into simulation: -----------

//zero
.attr("startOffset", "72%")
.attr('text-anchor', 'middle')

//first
.attr("text-anchor", "start")

//second
.attr("startOffset", "75%")
.attr("text-anchor", "middle")

//third
.attr("startOffset", "45%")
.attr("text-anchor", "middle")

//fourth, fifth and sixth
.attr("startOffset", "50%") //or 45%
.attr('text-anchor', 'middle')

------------------------------------------------ */
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