Public
Edited
Jun 29, 2023
2 forks
18 stars
Also listed in…
Meta
Simulation
Insert cell
Insert cell
Insert cell
{
/*
* The observer will call _draw(data)_ each time the worker yields _data_.
* it returns a function that allows us to terminate the worker when this cell is reevaluated
* cheeky version: `invalidation.then(observer(draw))`
*/
const terminate = observer(draw);
invalidation.then(terminate);

const context = DOM.context2d(width, height);
return context.canvas;

replay; // reevaluates this cell when we press the button

function draw(data) {
context.clearRect(0, 0, width, height);
if (data.progress > 0) {
context.fillStyle = "red";
context.fillRect(0, 0, data.progress, 2);
}

context.save();
context.translate(width / 2, height / 2);

context.globalAlpha = Math.exp(-data.progress / 200);

context.beginPath();
for (const c of data.links) {
context.moveTo(c.source.x, c.source.y);
context.lineTo(c.target.x, c.target.y);
}
context.lineWidth = 0.25;
context.stroke();

context.beginPath();
for (const c of data.nodes) {
context.moveTo(c.x, c.y);
context.arc(c.x, c.y, 1.5, 0, tau);
}
context.fillStyle = "#000";
context.fill();

context.restore();
}
}
Insert cell
Insert cell
function* simulation(data) {
const nodes = data.nodes,
links = data.links;

const simulation = d3.forceSimulation(nodes)
.force("charge", d3.forceManyBody().strength(-3))
.force("link", d3.forceLink(links).strength(1))
.force("x", d3.forceX())
.force("y", d3.forceY())
.stop();

let n =
Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay());
for (; n-- > 0; ) {
simulation.tick();
yield { progress: n, nodes: nodes, links: links };
}
}
Insert cell
Insert cell
import {worker} from "@fil/worker"
Insert cell
observer = worker(
simulation,
{ nodes, links },
`importScripts(${await require.resolve("d3@7").then(JSON.stringify)});`
)
Insert cell
d3 = "🤖" // placeholder — the actual instance of d3 is loaded above in the worker’s preamble.
Insert cell
Insert cell
N = 4 * width
Insert cell
nodes = Array.from({ length: N }, (_, index) => ({ index }))
Insert cell
Insert cell
height = (width * 0.9) | 0
Insert cell
tau = 2 * Math.PI
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