🏠 back to Observable

Odd behavior with order of cells and force simulations

I’ve been having a host of odd issues as I try to play around with d3-force in observable notebooks.

I’ve tracked down how to reproduce one especially odd guy I’ve been running into, but can’t tell exactly what the underlying issue is. and would love to understand what is going on.

I have a notebook that explores the issue here:

But I’ll give the tl;dr here too:

  1. I set up a simulation with a faulty set of nodes (due to a syntax error)
  2. I fix the error, but the simulation with the faulty data appears to continue running, throwing an error in the console with each time step
    Visually, this results in all of my nodes being stacked on top of each other
  3. If I refresh after fixing the error, the simulation works as expected, but I’m unclear why the refresh fixes this, and would love to not have to refresh to fix it.

Welcome @jimmcnulty41!

Your question is a fun one. Here’s an issue that I couldn’t come up with a good solution for (hoping some d3 experts will drop by with better advice): if nodes is bad then d3.forceSimulation(nodes) starts an infinite loop which spams errors, and there doesn’t seem to be any way to stop it except by refreshing the page.

See my comments in chart here:

chart2 is working fine; in my fork I added some invalidation logic and then commented it out since as far as I can tell it doesn’t have anything to do with what’s happening here.

In addition to the invalidation code that should be added in any case, one can catch the error by initializing the sim without nodes and wrapping potentially dangerous logic in a try/catch:

  const sim = d3.forceSimulation();
  try {
      .force("charge", d3.forceManyBody())
      .force("center", d3.forceCenter(width / 2, height / 2));
        .on("tick", () => {
          nodeSelection.attr("cx", d => d.x).attr("cy", d => d.y);
  catch(e) {
    throw e;

I think the timer is launched

before the simulation is initialized

it might be worth opening an issue at https://github.com/d3/d3-force/issues


It might be similar to this issue https://github.com/d3/d3-force/issues/45