Public
Edited
Dec 5, 2022
Paused
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
anim = {
// React to the button push
redo;

// Setup the graph
let nodes = d3.range(50).map((i) => ({ id: i }));
let links = [];
for (let i = 0; i < nodes.length; i++) {
for (let j = i + 1; j < nodes.length; j++) {
if (j <= 3 || d3.randomUniform(0, 1)() < 0.05) {
links.push({ source: i, target: j });
}
}
}
let G = { nodes, links };

// Run the simulation 300 ticks and record the positions of the nodes
d3.forceSimulation()
.nodes(G.nodes)
.force("charge", d3.forceManyBody())
.force("link", d3.forceLink(G.links))
.stop()
.tick(300);
let [xmin, xmax] = d3.extent(G.nodes.map((node) => node.x));
let [ymin, ymax] = d3.extent(G.nodes.map((node) => node.y));

// Reset the graph
G.nodes.forEach(function (node) {
delete node.index;
delete node.x;
delete node.y;
delete node.vx;
delete node.vy;
});
G.links.forEach(function (link) {
delete link.index;
});

// Set up the SVG
let x_scale = d3
.scaleLinear()
.domain([xmin, xmax])
.range([pad, w - pad]);
let y_scale = d3
.scaleLinear()
.domain([ymin, ymax])
.range([h - pad, pad]);
let svg = d3
.create("svg")
.attr("width", w)
.attr("height", h)
.attr("viewBox", [0, 0, w, h])
.style("border", "solid 1px black");

// Add the graph to the SVG
let graph = svg.append("g");
let link = graph
.append("g")
.attr("stroke", "black")
.attr("stroke-opacity", 0.9)
.attr("stroke-width", 1)
.selectAll("line")
.data(G.links)
.join("line");
const node = graph
.append("g")
.selectAll("circle")
.data(G.nodes)
.join("circle")
.attr("r", 4)
.attr("class", (d) => (d.id < 3 ? "zoom" : "dangle"))
.attr("fill", (d) => (d.id < 3 ? "red" : "black"));

// Run the simulation again.
let simulation = d3
.forceSimulation()
.nodes(G.nodes)
.force("charge", d3.forceManyBody())
.force("link", d3.forceLink(G.links))
.on("tick", function () {
link
.attr("x1", (d) => x_scale(d.source.x))
.attr("y1", (d) => y_scale(d.source.y))
.attr("x2", (d) => x_scale(d.target.x))
.attr("y2", (d) => y_scale(d.target.y));
node.attr("cx", (d) => x_scale(d.x)).attr("cy", (d) => y_scale(d.y));
});

Object.assign(svg.node(), { x_scale, y_scale, xmin, xmax, ymin, ymax });

return svg.node();
}
Insert cell
w = d3.min([800, width])
Insert cell
h = 0.625 * w
Insert cell
pad = 5
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