Skip to content

Commit

Permalink
Fix #18 - allow manual ticking.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mbostock committed Apr 26, 2016
1 parent 3810e0f commit e532b18
Showing 1 changed file with 16 additions and 22 deletions.
38 changes: 16 additions & 22 deletions src/simulation.js
Expand Up @@ -13,40 +13,38 @@ export function y(d) {
export default function(nodes) {
var simulation,
iteration = 0,
alpha = 1,
alphaMin = 0.0001,
alphaDecay = -0.02,
drag = 0.5,
force = map(),
ticker = timer(tick),
event = dispatch("start", "tick", "end");
event = dispatch("tick", "end");

if (nodes == null) nodes = [];

function start() {
if (iteration < Infinity) {
iteration = 0, alpha = 1;
} else {
iteration = 0, alpha = 1;
event.call("start", simulation);
ticker.restart(tick);
}
iteration = 0;
ticker.restart(tick);
return simulation;
}

function stop() {
if (iteration < Infinity) {
iteration = Infinity, alpha = 0;
event.call("end", simulation);
ticker.stop();
}
ticker.stop();
return simulation;
}

function tick() {
alpha = Math.exp(++iteration * alphaDecay);
if (!(alpha > alphaMin)) return stop();
force.each(apply);
var alpha = Math.exp(++iteration * alphaDecay);

if (!(alpha > alphaMin)) {
ticker.stop();
event.call("end", simulation);
return;
}

force.each(function(force) {
force(alpha);
});

for (var i = 0, n = nodes.length, node; i < n; ++i) {
node = nodes[i];
Expand All @@ -72,10 +70,6 @@ export default function(nodes) {
return force;
}

function apply(force) {
force(alpha);
}

initializeNodes();

return simulation = {
Expand All @@ -92,7 +86,7 @@ export default function(nodes) {
},

alphaDecay: function(_) {
return arguments.length ? (alphaDecay = -_, iteration = alphaDecay ? Math.round(Math.log(alpha) / alphaDecay) : 0, simulation) : -alphaDecay;
return arguments.length ? (iteration = +_ ? Math.round(iteration * alphaDecay / -_) : 0, alphaDecay = -_, simulation) : -alphaDecay;
},

drag: function(_) {
Expand Down

0 comments on commit e532b18

Please sign in to comment.