{
const N = 13;
const data = {
nodes: [
{ id: "o" },
{ id: "a" },
{ id: "b" },
{ id: "c" },
{ id: "a1" },
{ id: "a2" },
{ id: "b1" },
{ id: "b2" },
{ id: "b3" },
{ id: "c1" },
{ id: "c2" },
{ id: "c3" },
{ id: "c4" },
],
links: [
{ source: "o", target: "a" },
{ source: "o", target: "b" },
{ source: "o", target: "c" },
{ source: "a1", target: "a" },
{ source: "a2", target: "a" },
{ source: "b1", target: "b" },
{ source: "b2", target: "b" },
{ source: "b3", target: "b" },
{ source: "c1", target: "c" },
{ source: "c2", target: "c" },
{ source: "c3", target: "c" },
{ source: "c4", target: "c" },
]
};
const layout = d3
.forceSimulation(data.nodes)
.force(
"charge",
d3.forceManyBody().strength(() => -100)
)
.force(
"links",
d3
.forceLink(data.links)
.id((node) => node.id)
.strength((link) => (link.source.id === 0 ? 0.5 : 1))
)
.force("center", d3.forceCenter(width / 2, height / 2));
const svg = d3.select(chart);
layout.on("tick", function ticked() {
svg
.selectAll("path.link")
.data(data.links)
.join("path")
.attr("class", "link")
.style("fill", "none")
.style("stroke", (d) => (d.source.id === 0 ? "blue" : "red"))
.attr("d", (d) => {
const path = d3.path();
path.moveTo(d.source.x, d.source.y);
path.lineTo(d.target.x, d.target.y);
return path;
});
svg
.selectAll("circle.node")
.data(data.nodes, (d) => d.id)
.join("circle")
.attr("class", "node")
.attr("r", 5)
.attr("cx", (d) => d.x)
.attr("cy", (d) => d.y);
});
}