Public
Edited
Mar 14, 2023
Paused
12 stars
Insert cell
Insert cell
Insert cell
graph1 = {
refresh1;
return {
nodes: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }],
edges: [
{ source: 1, target: 5 },
{ source: 4, target: 5 },
{ source: 4, target: 6 },
{ source: 3, target: 2 },
{ source: 5, target: 2 },
{ source: 1, target: 2 },
{ source: 3, target: 4 }
],
getId: (node) => node.id
};
}
Insert cell
Insert cell
simulation1 = d3
.forceSimulation()
.force("fCentre", d3.forceCenter(w * 0.25, h * 0.5))
.force("fSpace", d3.forceManyBody().strength(-1000))
.force("fEdge", d3.forceLink().id(graph1.getId))
Insert cell
Insert cell
function clone(g) {
return {
nodes: g.nodes.map((n) => ({ ...n })),
edges: g.edges.map((e) => ({ ...e }))
};
}
Insert cell
Insert cell
Insert cell
{
const g = clone(graph1);
simulation1.nodes(g.nodes);
simulation1.force("fEdge").links(g.edges);
simulation1.stop();
simulation1.tick(100); // Run simulation for 100 tick cycles.

const toLine = (e) => [
[e.source.x, e.source.y],
[e.target.x, e.target.y]
];
const toPoint = (n) => [n.x, n.y];

return new Renderer(w, h)
.fill("rgb(220,140,95)")
.pointSize(18)
.lines(g.edges.map(toLine))
.stroke("white")
.points(g.nodes.map(toPoint))
.render();
}
Insert cell
Insert cell
Insert cell
Insert cell
{
const g = clone(graph1);
const toLine = (e) => [
[e.source.x, e.source.y],
[e.target.x, e.target.y]
];
const toPoint = (n) => [n.x, n.y];
const r = new Renderer(w, h).fill("rgb(220,140,95)").pointSize(18);
const drawFrame = () => {
r.clear()
.stroke("black")
.lines(g.edges.map(toLine))
.stroke("white")
.points(g.nodes.map(toPoint));
};

simulation2.nodes(g.nodes).on("tick", drawFrame);
simulation2.force("fEdge").links(g.edges);
return r.render();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function drawFrame() {
// Turns an edge into a set of Bezier control points.
const flowCurve = (e) => [
[e.source.x, e.source.y],
[
e.target.x - bendy * (e.source.y - e.target.y),
e.target.y + bendy * (e.source.x - e.target.x)
],
[e.target.x, e.target.y],
[e.target.x, e.target.y]
];

r.clear().fill().stroke("rgba(120,50,25,0.7)").strokeWidth(6);
graph2.edges.forEach((e) => r.bezier(flowCurve(e)));

r.fill("rgb(220,140,95)").stroke("rgb(120,50,25)").strokeWidth(3);
graph2.nodes.forEach((n) => r.ellipse(n.x, n.y, 30, 20));

r.fill("black").stroke();
graph2.nodes.forEach((n) => r.text(n.id, n.x, n.y));
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
graph3 = {
refresh3;

return {
nodes: [
{ id: 1, label: "a" },
{ id: 2, label: "b" },
{ id: 3, label: "c" },
{ id: 4, label: "d" },
{ id: 5, label: "e" },
{ id: 6, label: "f" }
],
edges: [
{ source: 1, target: 5, w: 15 },
{ source: 4, target: 5, w: 5 },
{ source: 4, target: 6, w: 1 },
{ source: 3, target: 2, w: 2 },
{ source: 5, target: 2, w: 3 },
{ source: 1, target: 2, w: 8 },
{ source: 3, target: 4, w: 25 }
],
getId: (node) => node.id
};
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
simulation5 = d3
.forceSimulation()
.force("fCentre", d3.forceCenter(w * 0.25, h * 0.5))
.force("fSpace", d3.forceManyBody().strength(-200))
.force(
"fEdge",
d3
.forceLink()
.id(graph3.getId)
.distance((e) => 5 * (28 - e.w))
)
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