Public
Edited
Jul 18, 2023
6 forks
23 stars
Insert cell
Insert cell
Insert cell
chart = {
const width = 928;
const height = 600;
const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("width", width)
.attr("height", height)
.attr("style", "max-width: 100%; height: auto;");

const g = svg.append("g");

simulation.on("tick", () => {
g.selectAll("circle:not(.exit)")
.data(simulation.nodes(), d => d.id)
.join(
enter => enter.append("circle")
.attr("fill", d => d3.interpolateSinebow(d.id))
.attr("r", 1)
.transition()
.duration(2000)
.attr("r", 19)
.selection(),
update => update
.attr("cx", d => d.x)
.attr("cy", d => d.y),
exit => exit
.classed("exit", true)
.transition()
.duration(2000)
.attr("fill", "#eee")
.attr("r", 1)
.remove()
);
});

return svg.node();
}
Insert cell
simulation = d3.forceSimulation()
.force("collide", d3.forceCollide().radius(20))
.force("manyBody", d3.forceManyBody().strength(30))
.force("center", d3.forceCenter().strength(smooth ? 0.01 : 1))
.alpha(0.1)
.alphaDecay(0)
Insert cell
nodes = {
const nodes = [];
while (true) {
const [x, y] = d3.pointRadial(2 * Math.PI * Math.random(), 200);
nodes.push({id: Math.random(), x, y});
if (nodes.length > 20) nodes.splice(Math.random() * nodes.length, 1);
simulation.nodes(nodes);
yield nodes;
await Promises.tick(500);
}
}
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