This feels a bit cleaner since you don’t need to track the name of the fixing
force externally. It also enforces that fixing happens after the application of
any forces.
This lets you set the “desired” alpha for the simulation, and have the
simulation smoothly interpolate towards the desired value. By default, the
target value is zero, such that the simulation cools. However, by setting it to
a non-zero value, such as during a drag interaction, you can also use it to have
the simulation heat. Fixes#26.
This commit also changes simulation.restart so that it no longer resets the
alpha to one, and changes the meaning of simulation.alphaDecay. The new default
alphaDecay now cause the simulation to end after 300 ticks, instead of 345.
Fixes#23. This doesn’t catch all degenerate configurations, such as when x = y,
but it at least handles a common case for geometric constraints. As an added
bonus, this commit avoids extraneous jiggling in the many-body force when
visiting testing the target node’s quadtree cell.
This changes simulation.tick to always advance the simulation one step,
regardless of the current value of alpha and alphaMin. If alpha is less than
alphaMin after this step, simulation.tick returns true, indicating that the
simulation can be safely ended.
Furthermore, simulation.tick no longer dispatches a tick event; the tick event
is only dispatched by the simulation’s internal timer. This is now consistent
with simulation.stop, which likewise does not dispatch an end event; the end
event is only dispatched when the simulation’s internal timer stops.
Rather than initialize the node positions randomly, use a phyllotaxis. This is
just as good, and means the resulting behavior will be deterministic as long as
no nodes are exactly coincident.
Calling simulation.stop no longer resets the alpha, so a subsequent call to
simulation.start now resumes the simulation, and you can call simulation.tick to
run the simulation manually.
This commit also removes the start event. There’s not much of a point to the
start event since it’s impossible to listen for it in the normal case: the event
is dispatched during the construction of the simulation before any listeners can
be registered. Even in other cases, the simulation is always restarted manually,
so you could always notify a listener manually at the same time. Furthermore,
supporting a start event would require us to track whether the timer is running,
so it’s simpler to just leave it out. (And lastly, eliminating the start event
avoids some confusion about the relationship between simulation.stop and the end
event, which are unrelated!)
Lastly, simplify the recalculation of the current iteration when changing the
alpha decay rate constant.
Fix#7 - forces are now mutable, so it’s easier to change their settings and
they behave more like other configurable objects in D3 (though less like curves,
easing functions and interpolators).
Fix#9 - forces now have a dedicated interface rather than just being beforetick
listeners. This allows forces to be re-initialized when the nodes change.
Fix#10 - d3.forcePosition now initializes node positions and velocities.