Node-Red configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

d3-force.js 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. // https://d3js.org/d3-force/ v3.0.0 Copyright 2010-2021 Mike Bostock
  2. (function (global, factory) {
  3. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-quadtree'), require('d3-dispatch'), require('d3-timer')) :
  4. typeof define === 'function' && define.amd ? define(['exports', 'd3-quadtree', 'd3-dispatch', 'd3-timer'], factory) :
  5. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3, global.d3, global.d3));
  6. }(this, (function (exports, d3Quadtree, d3Dispatch, d3Timer) { 'use strict';
  7. function center(x, y) {
  8. var nodes, strength = 1;
  9. if (x == null) x = 0;
  10. if (y == null) y = 0;
  11. function force() {
  12. var i,
  13. n = nodes.length,
  14. node,
  15. sx = 0,
  16. sy = 0;
  17. for (i = 0; i < n; ++i) {
  18. node = nodes[i], sx += node.x, sy += node.y;
  19. }
  20. for (sx = (sx / n - x) * strength, sy = (sy / n - y) * strength, i = 0; i < n; ++i) {
  21. node = nodes[i], node.x -= sx, node.y -= sy;
  22. }
  23. }
  24. force.initialize = function(_) {
  25. nodes = _;
  26. };
  27. force.x = function(_) {
  28. return arguments.length ? (x = +_, force) : x;
  29. };
  30. force.y = function(_) {
  31. return arguments.length ? (y = +_, force) : y;
  32. };
  33. force.strength = function(_) {
  34. return arguments.length ? (strength = +_, force) : strength;
  35. };
  36. return force;
  37. }
  38. function constant(x) {
  39. return function() {
  40. return x;
  41. };
  42. }
  43. function jiggle(random) {
  44. return (random() - 0.5) * 1e-6;
  45. }
  46. function x$2(d) {
  47. return d.x + d.vx;
  48. }
  49. function y$2(d) {
  50. return d.y + d.vy;
  51. }
  52. function collide(radius) {
  53. var nodes,
  54. radii,
  55. random,
  56. strength = 1,
  57. iterations = 1;
  58. if (typeof radius !== "function") radius = constant(radius == null ? 1 : +radius);
  59. function force() {
  60. var i, n = nodes.length,
  61. tree,
  62. node,
  63. xi,
  64. yi,
  65. ri,
  66. ri2;
  67. for (var k = 0; k < iterations; ++k) {
  68. tree = d3Quadtree.quadtree(nodes, x$2, y$2).visitAfter(prepare);
  69. for (i = 0; i < n; ++i) {
  70. node = nodes[i];
  71. ri = radii[node.index], ri2 = ri * ri;
  72. xi = node.x + node.vx;
  73. yi = node.y + node.vy;
  74. tree.visit(apply);
  75. }
  76. }
  77. function apply(quad, x0, y0, x1, y1) {
  78. var data = quad.data, rj = quad.r, r = ri + rj;
  79. if (data) {
  80. if (data.index > node.index) {
  81. var x = xi - data.x - data.vx,
  82. y = yi - data.y - data.vy,
  83. l = x * x + y * y;
  84. if (l < r * r) {
  85. if (x === 0) x = jiggle(random), l += x * x;
  86. if (y === 0) y = jiggle(random), l += y * y;
  87. l = (r - (l = Math.sqrt(l))) / l * strength;
  88. node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
  89. node.vy += (y *= l) * r;
  90. data.vx -= x * (r = 1 - r);
  91. data.vy -= y * r;
  92. }
  93. }
  94. return;
  95. }
  96. return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
  97. }
  98. }
  99. function prepare(quad) {
  100. if (quad.data) return quad.r = radii[quad.data.index];
  101. for (var i = quad.r = 0; i < 4; ++i) {
  102. if (quad[i] && quad[i].r > quad.r) {
  103. quad.r = quad[i].r;
  104. }
  105. }
  106. }
  107. function initialize() {
  108. if (!nodes) return;
  109. var i, n = nodes.length, node;
  110. radii = new Array(n);
  111. for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
  112. }
  113. force.initialize = function(_nodes, _random) {
  114. nodes = _nodes;
  115. random = _random;
  116. initialize();
  117. };
  118. force.iterations = function(_) {
  119. return arguments.length ? (iterations = +_, force) : iterations;
  120. };
  121. force.strength = function(_) {
  122. return arguments.length ? (strength = +_, force) : strength;
  123. };
  124. force.radius = function(_) {
  125. return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), initialize(), force) : radius;
  126. };
  127. return force;
  128. }
  129. function index(d) {
  130. return d.index;
  131. }
  132. function find(nodeById, nodeId) {
  133. var node = nodeById.get(nodeId);
  134. if (!node) throw new Error("node not found: " + nodeId);
  135. return node;
  136. }
  137. function link(links) {
  138. var id = index,
  139. strength = defaultStrength,
  140. strengths,
  141. distance = constant(30),
  142. distances,
  143. nodes,
  144. count,
  145. bias,
  146. random,
  147. iterations = 1;
  148. if (links == null) links = [];
  149. function defaultStrength(link) {
  150. return 1 / Math.min(count[link.source.index], count[link.target.index]);
  151. }
  152. function force(alpha) {
  153. for (var k = 0, n = links.length; k < iterations; ++k) {
  154. for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
  155. link = links[i], source = link.source, target = link.target;
  156. x = target.x + target.vx - source.x - source.vx || jiggle(random);
  157. y = target.y + target.vy - source.y - source.vy || jiggle(random);
  158. l = Math.sqrt(x * x + y * y);
  159. l = (l - distances[i]) / l * alpha * strengths[i];
  160. x *= l, y *= l;
  161. target.vx -= x * (b = bias[i]);
  162. target.vy -= y * b;
  163. source.vx += x * (b = 1 - b);
  164. source.vy += y * b;
  165. }
  166. }
  167. }
  168. function initialize() {
  169. if (!nodes) return;
  170. var i,
  171. n = nodes.length,
  172. m = links.length,
  173. nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d])),
  174. link;
  175. for (i = 0, count = new Array(n); i < m; ++i) {
  176. link = links[i], link.index = i;
  177. if (typeof link.source !== "object") link.source = find(nodeById, link.source);
  178. if (typeof link.target !== "object") link.target = find(nodeById, link.target);
  179. count[link.source.index] = (count[link.source.index] || 0) + 1;
  180. count[link.target.index] = (count[link.target.index] || 0) + 1;
  181. }
  182. for (i = 0, bias = new Array(m); i < m; ++i) {
  183. link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
  184. }
  185. strengths = new Array(m), initializeStrength();
  186. distances = new Array(m), initializeDistance();
  187. }
  188. function initializeStrength() {
  189. if (!nodes) return;
  190. for (var i = 0, n = links.length; i < n; ++i) {
  191. strengths[i] = +strength(links[i], i, links);
  192. }
  193. }
  194. function initializeDistance() {
  195. if (!nodes) return;
  196. for (var i = 0, n = links.length; i < n; ++i) {
  197. distances[i] = +distance(links[i], i, links);
  198. }
  199. }
  200. force.initialize = function(_nodes, _random) {
  201. nodes = _nodes;
  202. random = _random;
  203. initialize();
  204. };
  205. force.links = function(_) {
  206. return arguments.length ? (links = _, initialize(), force) : links;
  207. };
  208. force.id = function(_) {
  209. return arguments.length ? (id = _, force) : id;
  210. };
  211. force.iterations = function(_) {
  212. return arguments.length ? (iterations = +_, force) : iterations;
  213. };
  214. force.strength = function(_) {
  215. return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initializeStrength(), force) : strength;
  216. };
  217. force.distance = function(_) {
  218. return arguments.length ? (distance = typeof _ === "function" ? _ : constant(+_), initializeDistance(), force) : distance;
  219. };
  220. return force;
  221. }
  222. // https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
  223. const a = 1664525;
  224. const c = 1013904223;
  225. const m = 4294967296; // 2^32
  226. function lcg() {
  227. let s = 1;
  228. return () => (s = (a * s + c) % m) / m;
  229. }
  230. function x$1(d) {
  231. return d.x;
  232. }
  233. function y$1(d) {
  234. return d.y;
  235. }
  236. var initialRadius = 10,
  237. initialAngle = Math.PI * (3 - Math.sqrt(5));
  238. function simulation(nodes) {
  239. var simulation,
  240. alpha = 1,
  241. alphaMin = 0.001,
  242. alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
  243. alphaTarget = 0,
  244. velocityDecay = 0.6,
  245. forces = new Map(),
  246. stepper = d3Timer.timer(step),
  247. event = d3Dispatch.dispatch("tick", "end"),
  248. random = lcg();
  249. if (nodes == null) nodes = [];
  250. function step() {
  251. tick();
  252. event.call("tick", simulation);
  253. if (alpha < alphaMin) {
  254. stepper.stop();
  255. event.call("end", simulation);
  256. }
  257. }
  258. function tick(iterations) {
  259. var i, n = nodes.length, node;
  260. if (iterations === undefined) iterations = 1;
  261. for (var k = 0; k < iterations; ++k) {
  262. alpha += (alphaTarget - alpha) * alphaDecay;
  263. forces.forEach(function(force) {
  264. force(alpha);
  265. });
  266. for (i = 0; i < n; ++i) {
  267. node = nodes[i];
  268. if (node.fx == null) node.x += node.vx *= velocityDecay;
  269. else node.x = node.fx, node.vx = 0;
  270. if (node.fy == null) node.y += node.vy *= velocityDecay;
  271. else node.y = node.fy, node.vy = 0;
  272. }
  273. }
  274. return simulation;
  275. }
  276. function initializeNodes() {
  277. for (var i = 0, n = nodes.length, node; i < n; ++i) {
  278. node = nodes[i], node.index = i;
  279. if (node.fx != null) node.x = node.fx;
  280. if (node.fy != null) node.y = node.fy;
  281. if (isNaN(node.x) || isNaN(node.y)) {
  282. var radius = initialRadius * Math.sqrt(0.5 + i), angle = i * initialAngle;
  283. node.x = radius * Math.cos(angle);
  284. node.y = radius * Math.sin(angle);
  285. }
  286. if (isNaN(node.vx) || isNaN(node.vy)) {
  287. node.vx = node.vy = 0;
  288. }
  289. }
  290. }
  291. function initializeForce(force) {
  292. if (force.initialize) force.initialize(nodes, random);
  293. return force;
  294. }
  295. initializeNodes();
  296. return simulation = {
  297. tick: tick,
  298. restart: function() {
  299. return stepper.restart(step), simulation;
  300. },
  301. stop: function() {
  302. return stepper.stop(), simulation;
  303. },
  304. nodes: function(_) {
  305. return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes;
  306. },
  307. alpha: function(_) {
  308. return arguments.length ? (alpha = +_, simulation) : alpha;
  309. },
  310. alphaMin: function(_) {
  311. return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
  312. },
  313. alphaDecay: function(_) {
  314. return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
  315. },
  316. alphaTarget: function(_) {
  317. return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
  318. },
  319. velocityDecay: function(_) {
  320. return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
  321. },
  322. randomSource: function(_) {
  323. return arguments.length ? (random = _, forces.forEach(initializeForce), simulation) : random;
  324. },
  325. force: function(name, _) {
  326. return arguments.length > 1 ? ((_ == null ? forces.delete(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);
  327. },
  328. find: function(x, y, radius) {
  329. var i = 0,
  330. n = nodes.length,
  331. dx,
  332. dy,
  333. d2,
  334. node,
  335. closest;
  336. if (radius == null) radius = Infinity;
  337. else radius *= radius;
  338. for (i = 0; i < n; ++i) {
  339. node = nodes[i];
  340. dx = x - node.x;
  341. dy = y - node.y;
  342. d2 = dx * dx + dy * dy;
  343. if (d2 < radius) closest = node, radius = d2;
  344. }
  345. return closest;
  346. },
  347. on: function(name, _) {
  348. return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
  349. }
  350. };
  351. }
  352. function manyBody() {
  353. var nodes,
  354. node,
  355. random,
  356. alpha,
  357. strength = constant(-30),
  358. strengths,
  359. distanceMin2 = 1,
  360. distanceMax2 = Infinity,
  361. theta2 = 0.81;
  362. function force(_) {
  363. var i, n = nodes.length, tree = d3Quadtree.quadtree(nodes, x$1, y$1).visitAfter(accumulate);
  364. for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
  365. }
  366. function initialize() {
  367. if (!nodes) return;
  368. var i, n = nodes.length, node;
  369. strengths = new Array(n);
  370. for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);
  371. }
  372. function accumulate(quad) {
  373. var strength = 0, q, c, weight = 0, x, y, i;
  374. // For internal nodes, accumulate forces from child quadrants.
  375. if (quad.length) {
  376. for (x = y = i = 0; i < 4; ++i) {
  377. if ((q = quad[i]) && (c = Math.abs(q.value))) {
  378. strength += q.value, weight += c, x += c * q.x, y += c * q.y;
  379. }
  380. }
  381. quad.x = x / weight;
  382. quad.y = y / weight;
  383. }
  384. // For leaf nodes, accumulate forces from coincident quadrants.
  385. else {
  386. q = quad;
  387. q.x = q.data.x;
  388. q.y = q.data.y;
  389. do strength += strengths[q.data.index];
  390. while (q = q.next);
  391. }
  392. quad.value = strength;
  393. }
  394. function apply(quad, x1, _, x2) {
  395. if (!quad.value) return true;
  396. var x = quad.x - node.x,
  397. y = quad.y - node.y,
  398. w = x2 - x1,
  399. l = x * x + y * y;
  400. // Apply the Barnes-Hut approximation if possible.
  401. // Limit forces for very close nodes; randomize direction if coincident.
  402. if (w * w / theta2 < l) {
  403. if (l < distanceMax2) {
  404. if (x === 0) x = jiggle(random), l += x * x;
  405. if (y === 0) y = jiggle(random), l += y * y;
  406. if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
  407. node.vx += x * quad.value * alpha / l;
  408. node.vy += y * quad.value * alpha / l;
  409. }
  410. return true;
  411. }
  412. // Otherwise, process points directly.
  413. else if (quad.length || l >= distanceMax2) return;
  414. // Limit forces for very close nodes; randomize direction if coincident.
  415. if (quad.data !== node || quad.next) {
  416. if (x === 0) x = jiggle(random), l += x * x;
  417. if (y === 0) y = jiggle(random), l += y * y;
  418. if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
  419. }
  420. do if (quad.data !== node) {
  421. w = strengths[quad.data.index] * alpha / l;
  422. node.vx += x * w;
  423. node.vy += y * w;
  424. } while (quad = quad.next);
  425. }
  426. force.initialize = function(_nodes, _random) {
  427. nodes = _nodes;
  428. random = _random;
  429. initialize();
  430. };
  431. force.strength = function(_) {
  432. return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initialize(), force) : strength;
  433. };
  434. force.distanceMin = function(_) {
  435. return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
  436. };
  437. force.distanceMax = function(_) {
  438. return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
  439. };
  440. force.theta = function(_) {
  441. return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
  442. };
  443. return force;
  444. }
  445. function radial(radius, x, y) {
  446. var nodes,
  447. strength = constant(0.1),
  448. strengths,
  449. radiuses;
  450. if (typeof radius !== "function") radius = constant(+radius);
  451. if (x == null) x = 0;
  452. if (y == null) y = 0;
  453. function force(alpha) {
  454. for (var i = 0, n = nodes.length; i < n; ++i) {
  455. var node = nodes[i],
  456. dx = node.x - x || 1e-6,
  457. dy = node.y - y || 1e-6,
  458. r = Math.sqrt(dx * dx + dy * dy),
  459. k = (radiuses[i] - r) * strengths[i] * alpha / r;
  460. node.vx += dx * k;
  461. node.vy += dy * k;
  462. }
  463. }
  464. function initialize() {
  465. if (!nodes) return;
  466. var i, n = nodes.length;
  467. strengths = new Array(n);
  468. radiuses = new Array(n);
  469. for (i = 0; i < n; ++i) {
  470. radiuses[i] = +radius(nodes[i], i, nodes);
  471. strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes);
  472. }
  473. }
  474. force.initialize = function(_) {
  475. nodes = _, initialize();
  476. };
  477. force.strength = function(_) {
  478. return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initialize(), force) : strength;
  479. };
  480. force.radius = function(_) {
  481. return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), initialize(), force) : radius;
  482. };
  483. force.x = function(_) {
  484. return arguments.length ? (x = +_, force) : x;
  485. };
  486. force.y = function(_) {
  487. return arguments.length ? (y = +_, force) : y;
  488. };
  489. return force;
  490. }
  491. function x(x) {
  492. var strength = constant(0.1),
  493. nodes,
  494. strengths,
  495. xz;
  496. if (typeof x !== "function") x = constant(x == null ? 0 : +x);
  497. function force(alpha) {
  498. for (var i = 0, n = nodes.length, node; i < n; ++i) {
  499. node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
  500. }
  501. }
  502. function initialize() {
  503. if (!nodes) return;
  504. var i, n = nodes.length;
  505. strengths = new Array(n);
  506. xz = new Array(n);
  507. for (i = 0; i < n; ++i) {
  508. strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
  509. }
  510. }
  511. force.initialize = function(_) {
  512. nodes = _;
  513. initialize();
  514. };
  515. force.strength = function(_) {
  516. return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initialize(), force) : strength;
  517. };
  518. force.x = function(_) {
  519. return arguments.length ? (x = typeof _ === "function" ? _ : constant(+_), initialize(), force) : x;
  520. };
  521. return force;
  522. }
  523. function y(y) {
  524. var strength = constant(0.1),
  525. nodes,
  526. strengths,
  527. yz;
  528. if (typeof y !== "function") y = constant(y == null ? 0 : +y);
  529. function force(alpha) {
  530. for (var i = 0, n = nodes.length, node; i < n; ++i) {
  531. node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
  532. }
  533. }
  534. function initialize() {
  535. if (!nodes) return;
  536. var i, n = nodes.length;
  537. strengths = new Array(n);
  538. yz = new Array(n);
  539. for (i = 0; i < n; ++i) {
  540. strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
  541. }
  542. }
  543. force.initialize = function(_) {
  544. nodes = _;
  545. initialize();
  546. };
  547. force.strength = function(_) {
  548. return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initialize(), force) : strength;
  549. };
  550. force.y = function(_) {
  551. return arguments.length ? (y = typeof _ === "function" ? _ : constant(+_), initialize(), force) : y;
  552. };
  553. return force;
  554. }
  555. exports.forceCenter = center;
  556. exports.forceCollide = collide;
  557. exports.forceLink = link;
  558. exports.forceManyBody = manyBody;
  559. exports.forceRadial = radial;
  560. exports.forceSimulation = simulation;
  561. exports.forceX = x;
  562. exports.forceY = y;
  563. Object.defineProperty(exports, '__esModule', { value: true });
  564. })));