d3-force/src/simulation.js

68 lines
1.6 KiB
JavaScript
Raw Normal View History

2016-04-06 04:50:36 +08:00
import {timer as newTimer} from "d3-timer";
import {dispatch as newDispatch} from "d3-dispatch";
export default function(nodes) {
2016-04-07 04:21:23 +08:00
var frame = 0,
frameMax = 300,
alphaDecay = -0.03,
velocityDecay = 0.9,
2016-04-06 04:50:36 +08:00
timer = newTimer(tick),
2016-04-07 04:21:23 +08:00
dispatch = newDispatch("start", "beforetick", "tick", "end");
2016-04-06 04:50:36 +08:00
2016-04-07 04:21:23 +08:00
function start() {
if (frame < Infinity) {
frame = 0;
dispatch.call("start", this);
timer.restart(tick);
2016-04-06 04:50:36 +08:00
} else {
2016-04-07 04:21:23 +08:00
frame = 0;
}
}
function stop() {
if (frame < Infinity) {
frame = Infinity;
dispatch.call("end", this);
timer.stop();
2016-04-06 04:50:36 +08:00
}
}
function tick() {
2016-04-07 04:21:23 +08:00
if (++frame > frameMax) return stop();
2016-04-06 04:50:36 +08:00
2016-04-07 04:21:23 +08:00
dispatch.call("beforetick", this, Math.exp(frame * alphaDecay));
2016-04-06 04:50:36 +08:00
for (var i = 0, n = nodes.length, node; i < n; ++i) {
node = nodes[i];
2016-04-07 04:21:23 +08:00
node.x += node.vx *= velocityDecay;
node.y += node.vy *= velocityDecay;
2016-04-06 04:50:36 +08:00
}
dispatch.call("tick", this);
}
return {
nodes: function(_) {
return arguments.length ? (nodes = _, this) : nodes;
},
start: function() {
2016-04-07 04:21:23 +08:00
return start(), this;
2016-04-06 04:50:36 +08:00
},
stop: function() {
2016-04-07 04:21:23 +08:00
return stop(), this;
2016-04-06 04:50:36 +08:00
},
2016-04-07 04:21:23 +08:00
frameMax: function(_) {
return arguments.length ? (frameMax = _, this) : frameMax;
2016-04-06 04:50:36 +08:00
},
alphaDecay: function(_) {
return arguments.length ? (alphaDecay = +_, this) : alphaDecay;
},
2016-04-07 04:21:23 +08:00
friction: function(_) {
return arguments.length ? (velocityDecay = 1 - _, this) : 1 - velocityDecay;
2016-04-06 04:50:36 +08:00
},
on: function(name, _) {
return arguments.length > 1 ? (dispatch.on(name, _), this) : dispatch.on(name);
}
};
}