Public
Edited
Dec 1, 2022
1 fork
5 stars
Insert cell
Insert cell
<style>
.tooltip {
padding: 8px 12px;
color: white;
border-radius: 6px;
border: 2px solid rgba(255,255,255,0.5);
box-shadow: 0 1px 4px 0 rgba(0,0,0,0.2);
pointer-events: none;
transform: translate(-50%, -100%);
font-family: "Helvetica", sans-serif;
background: rgba(20,10,30,0.6);
transition: 0.2s opacity ease-out, 0.1s border-color ease-out;
}
.tooltip.blur {
backdrop-filter: blur(4px);
}
.tooltip.light {
background: rgba(250,240,255,0.2);
text-shadow: 0 0 3px black;
}
.tooltip.blur.light {
backdrop-filter: blur(7px);
}
</style>
Insert cell
Insert cell
{
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.style("background", "#2D2537")
.style("box-shadow", "0 0 20px 0 inset rgba(10,10,10,0.1)");

d3.selectAll("div.tooltip").remove(); // clear tooltips from before
const tooltip = d3
.select("body")
.append("div")
.attr("class", `tooltip ${classes}`)
.style("position", "absolute")
.style("opacity", 0)
// .style("visibility", "hidden")
.text("I'm a circle!");

const nodes = data.map((d) => ({ ...d }));

const circles = svg
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("r", (d) => d.r)
.attr("fill", (d) => color(d.group));

circles
.on("mouseover", (_evt, d) => {
tooltip
.style("opacity", 1)
.html(`x = ${d.x.toFixed(2)}<br>y = ${d.y.toFixed(2)}`)
.style("border-color", color(d.group));
})
.on("mousemove", (evt, d) => {
tooltip
.style("top", evt.pageY - 10 + "px")
.style("left", evt.pageX + 10 + "px");
})
.on("mouseout", () => {
tooltip.style("opacity", 0);
});

const simulation = d3
.forceSimulation(nodes)
.alphaTarget(0.3)
.velocityDecay(0.1)
.force("x", d3.forceX().strength((0.01 * height) / width))
.force("y", d3.forceY().strength(0.01))
.force(
"collide",
d3
.forceCollide()
.radius((d) => d.r + 4)
.iterations(3)
)
.force(
"charge",
d3.forceManyBody().strength((d, i) => -1)
)
.on("tick", function () {
circles
.data(nodes)
.join("circle")
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y);
});

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
height = 500
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