Public
Edited
Apr 14, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', w)
.attr('height', h);
const nodes = [
{ id: "node1", group: 1, size: 12 },
{ id: "node2", group: 2, size: 15 },
{ id: "node3", group: 1, size: 8 },
{ id: "node4", group: 2, size: 20 },
{ id: "node5", group: 3, size: 10 },
{ id: "node6", group: 3, size: 14 },
{ id: "node7", group: 1, size: 16 },
{ id: "node8", group: 2, size: 11 },
{ id: "node9", group: 3, size: 9 },
{ id: "node10", group: 2, size: 7 }
];

const links = [
{ source: "node1", target: "node2", value: 2 },
{ source: "node2", target: "node3", value: 4 },
{ source: "node3", target: "node4", value: 3 },
{ source: "node4", target: "node1", value: 5 },
{ source: "node1", target: "node5", value: 1 },
{ source: "node6", target: "node5", value: 3 },
{ source: "node5", target: "node7", value: 2 },
{ source: "node6", target: "node8", value: 4 },
{ source: "node8", target: "node9", value: 2 },
{ source: "node9", target: "node10", value: 1 },
{ source: "node10", target: "node6", value: 3 }
];

const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id).strength(d => d.value * 0.1))
.force("charge", d3.forceManyBody().strength(-50))
.force("center", d3.forceCenter(w / 2, h / 2));

const link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links)
.enter().append("line")
.attr("class", "link");

const node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", d => d.size)
.attr("fill", d => {
switch (d.group) {
case 1: return "red";
case 2: return "green";
case 3: return "blue";
default: return "grey";
}
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

node.append("title")
.text(d => d.id);

simulation.on("tick", () => {
link.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);

node.attr("cx", d => d.x)
.attr("cy", d => d.y);
});

function dragstarted(event, d) {
if (!event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}

function dragged(event, d) {
d.fx = event.x;
d.fy = event.y;
}

function dragended(event, d) {
if (!event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
return svg.node()
}
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