import constant from "./constant"; import jiggle from "./jiggle"; /** * Modified link force algorithm * - simplify calculations for parameters locked for spring model * - replace the use of links {} with loop. greatly reduce memory usage * - removed other unused functions * Alpha should be constant 1 for accurate simulation */ export default function() { var dataSizeFactor, distance = constant(30), distances = [], nodes, stableVelocity = 0, stableVeloHandler = null, latestVelocityDiff = 0, iterations = 1; function force(alpha) { let n = nodes.length; // Cache old velocity for comparison later if (stableVeloHandler!==null && stableVelocity>=0) { for (let i = n-1, node; i>=0; i--) { node = nodes[i]; node.oldvx = node.vx; node.oldvy = node.vy; } } // Each iteration in a tick for (var k = 0, source, target, i, j, x, y, l; k < iterations; ++k) { // For each link for (i = 1; i < n; i++) for (j = 0; j < i; j++) { // jiggle so l won't be zero and divide by zero error after this source = nodes[i]; target = nodes[j]; x = target.x + target.vx - source.x - source.vx || jiggle(); y = target.y + target.vy - source.y - source.vy || jiggle(); l = Math.sqrt(x * x + y * y); l = (l - distances[i*(i-1)/2+j]) / l * dataSizeFactor * alpha; x *= l, y *= l; target.vx -= x; target.vy -= y; source.vx += x; source.vy += y; } } // Calculate velocity changes, aka force applied. if (stableVeloHandler!==null && stableVelocity>=0) { let velocityDiff = 0; for (let i = n-1, node; i>=0; i--) { node = nodes[i]; velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy)); } velocityDiff /= n; latestVelocityDiff = velocityDiff; if(velocityDiff