Published
Edited
Feb 28, 2020
4 stars
Insert cell
Insert cell
svg = {
const svg = d3.select(DOM.svg(size[0], size[1]));
const nodes = new Array(n).fill(0)
.map((_, i) => {
return {
index: i,
r: rand(radius[0], radius[1]),
fill: color(i),
charge: 0,
};
});
// Push a fake node onto the end of the collection of nodes.
const mouse = {
index: n,
x: center[0],
y: center[1],
r: 0,
fill: "none",
isMouse: true,
};
nodes.push(mouse);
svg.selectAll("circle")
.data(nodes)
.join("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", d => d.r)
.attr("fill", d => d.fill);
simulation.nodes(nodes).alpha(0.9).restart();
simulation.on("tick", () => {
svg.selectAll("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y);
});
svg
.on("mouseenter", () => {
console.log("mouseenter");
})
.on("mousemove", () => {
const pos = d3.mouse(svg.node());
mouse.r = radius[1];
mouse.fx = pos[0];
mouse.fy = pos[1];
simulation.alpha(0.9).restart();
console.log("mousemove", pos);
})
.on("mouseleave", () => {
console.log("mouseleave");
});
return svg.node();
}
Insert cell
Insert cell
Insert cell
function forceCollide() {

const alpha = 0.5;
let nodes = [];

function force() {
const quadtree = d3.quadtree()
.x(d => d.x)
.y(d => d.y)
.addAll(nodes);
for (const node of nodes) {
quadtree.visit((visited, x1, y1, x2, y2) => {
let updated = false;
if (visited.data && (visited.data !== node)) {
const actualDistance = distance(node, visited.data);
const minAllowedDistance = node.r + visited.data.r;
if (actualDistance < minAllowedDistance) {
const movementConstant = (actualDistance - minAllowedDistance) / actualDistance * alpha;
const deltaX = (node.x - visited.data.x) * movementConstant;
const deltaY = (node.y - visited.data.y) * movementConstant;

node.x -= deltaX;
node.y -= deltaY;
visited.data.x += deltaX;
visited.data.y += deltaY;
updated = true;
}
}
return updated;
});
}
}

// Forces must have an initializer function that accepts an array of nodes.
force.initialize = function (_nodes) {
nodes = _nodes;
}

return force;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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