source: node_modules/d3-force/src/simulation.js@ e4c61dd

Last change on this file since e4c61dd was e4c61dd, checked in by istevanoska <ilinastevanoska@…>, 6 months ago

Prototype 1.1

  • Property mode set to 100644
File size: 3.8 KB
RevLine 
[e4c61dd]1import {dispatch} from "d3-dispatch";
2import {timer} from "d3-timer";
3import lcg from "./lcg.js";
4
5export function x(d) {
6 return d.x;
7}
8
9export function y(d) {
10 return d.y;
11}
12
13var initialRadius = 10,
14 initialAngle = Math.PI * (3 - Math.sqrt(5));
15
16export default function(nodes) {
17 var simulation,
18 alpha = 1,
19 alphaMin = 0.001,
20 alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
21 alphaTarget = 0,
22 velocityDecay = 0.6,
23 forces = new Map(),
24 stepper = timer(step),
25 event = dispatch("tick", "end"),
26 random = lcg();
27
28 if (nodes == null) nodes = [];
29
30 function step() {
31 tick();
32 event.call("tick", simulation);
33 if (alpha < alphaMin) {
34 stepper.stop();
35 event.call("end", simulation);
36 }
37 }
38
39 function tick(iterations) {
40 var i, n = nodes.length, node;
41
42 if (iterations === undefined) iterations = 1;
43
44 for (var k = 0; k < iterations; ++k) {
45 alpha += (alphaTarget - alpha) * alphaDecay;
46
47 forces.forEach(function(force) {
48 force(alpha);
49 });
50
51 for (i = 0; i < n; ++i) {
52 node = nodes[i];
53 if (node.fx == null) node.x += node.vx *= velocityDecay;
54 else node.x = node.fx, node.vx = 0;
55 if (node.fy == null) node.y += node.vy *= velocityDecay;
56 else node.y = node.fy, node.vy = 0;
57 }
58 }
59
60 return simulation;
61 }
62
63 function initializeNodes() {
64 for (var i = 0, n = nodes.length, node; i < n; ++i) {
65 node = nodes[i], node.index = i;
66 if (node.fx != null) node.x = node.fx;
67 if (node.fy != null) node.y = node.fy;
68 if (isNaN(node.x) || isNaN(node.y)) {
69 var radius = initialRadius * Math.sqrt(0.5 + i), angle = i * initialAngle;
70 node.x = radius * Math.cos(angle);
71 node.y = radius * Math.sin(angle);
72 }
73 if (isNaN(node.vx) || isNaN(node.vy)) {
74 node.vx = node.vy = 0;
75 }
76 }
77 }
78
79 function initializeForce(force) {
80 if (force.initialize) force.initialize(nodes, random);
81 return force;
82 }
83
84 initializeNodes();
85
86 return simulation = {
87 tick: tick,
88
89 restart: function() {
90 return stepper.restart(step), simulation;
91 },
92
93 stop: function() {
94 return stepper.stop(), simulation;
95 },
96
97 nodes: function(_) {
98 return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes;
99 },
100
101 alpha: function(_) {
102 return arguments.length ? (alpha = +_, simulation) : alpha;
103 },
104
105 alphaMin: function(_) {
106 return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
107 },
108
109 alphaDecay: function(_) {
110 return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
111 },
112
113 alphaTarget: function(_) {
114 return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
115 },
116
117 velocityDecay: function(_) {
118 return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
119 },
120
121 randomSource: function(_) {
122 return arguments.length ? (random = _, forces.forEach(initializeForce), simulation) : random;
123 },
124
125 force: function(name, _) {
126 return arguments.length > 1 ? ((_ == null ? forces.delete(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);
127 },
128
129 find: function(x, y, radius) {
130 var i = 0,
131 n = nodes.length,
132 dx,
133 dy,
134 d2,
135 node,
136 closest;
137
138 if (radius == null) radius = Infinity;
139 else radius *= radius;
140
141 for (i = 0; i < n; ++i) {
142 node = nodes[i];
143 dx = x - node.x;
144 dy = y - node.y;
145 d2 = dx * dx + dy * dy;
146 if (d2 < radius) closest = node, radius = d2;
147 }
148
149 return closest;
150 },
151
152 on: function(name, _) {
153 return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
154 }
155 };
156}
Note: See TracBrowser for help on using the repository browser.