1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129 |
- ;(function(undefined) {
- 'use strict';
-
- var _root = this,
- inWebWorker = !('document' in _root);
-
- var Worker = function(undefined) {
- 'use strict';
-
- var W = {
-
- ppn: 10,
- ppe: 3,
- ppr: 9,
- maxForce: 10,
- iterations: 0,
- converged: false,
-
- settings: {
- linLogMode: false,
- outboundAttractionDistribution: false,
- adjustSizes: false,
- edgeWeightInfluence: 0,
- scalingRatio: 1,
- strongGravityMode: false,
- gravity: 1,
- slowDown: 1,
- barnesHutOptimize: false,
- barnesHutTheta: 0.5,
- startingIterations: 1,
- iterationsPerRender: 1
- }
- };
- var NodeMatrix,
- EdgeMatrix,
- RegionMatrix;
-
- function extend() {
- var i,
- k,
- res = {},
- l = arguments.length;
- for (i = l - 1; i >= 0; i--)
- for (k in arguments[i])
- res[k] = arguments[i][k];
- return res;
- }
- function __emptyObject(obj) {
- var k;
- for (k in obj)
- if (!('hasOwnProperty' in obj) || obj.hasOwnProperty(k))
- delete obj[k];
- return obj;
- }
-
- var nodeProperties = {
- x: 0,
- y: 1,
- dx: 2,
- dy: 3,
- old_dx: 4,
- old_dy: 5,
- mass: 6,
- convergence: 7,
- size: 8,
- fixed: 9
- };
- var edgeProperties = {
- source: 0,
- target: 1,
- weight: 2
- };
- var regionProperties = {
- node: 0,
- centerX: 1,
- centerY: 2,
- size: 3,
- nextSibling: 4,
- firstChild: 5,
- mass: 6,
- massCenterX: 7,
- massCenterY: 8
- };
- function np(i, p) {
-
- if ((i % W.ppn) !== 0)
- throw 'np: non correct (' + i + ').';
- if (i !== parseInt(i))
- throw 'np: non int.';
- if (p in nodeProperties)
- return i + nodeProperties[p];
- else
- throw 'ForceAtlas2.Worker - ' +
- 'Inexistant node property given (' + p + ').';
- }
- function ep(i, p) {
-
- if ((i % W.ppe) !== 0)
- throw 'ep: non correct (' + i + ').';
- if (i !== parseInt(i))
- throw 'ep: non int.';
- if (p in edgeProperties)
- return i + edgeProperties[p];
- else
- throw 'ForceAtlas2.Worker - ' +
- 'Inexistant edge property given (' + p + ').';
- }
- function rp(i, p) {
-
- if ((i % W.ppr) !== 0)
- throw 'rp: non correct (' + i + ').';
- if (i !== parseInt(i))
- throw 'rp: non int.';
- if (p in regionProperties)
- return i + regionProperties[p];
- else
- throw 'ForceAtlas2.Worker - ' +
- 'Inexistant region property given (' + p + ').';
- }
-
- function nan(v) {
- if (isNaN(v))
- throw 'NaN alert!';
- }
-
- function init(nodes, edges, config) {
- config = config || {};
- var i, l;
-
- NodeMatrix = nodes;
- EdgeMatrix = edges;
-
- W.nodesLength = NodeMatrix.length;
- W.edgesLength = EdgeMatrix.length;
-
- configure(config);
- }
- function configure(o) {
- W.settings = extend(o, W.settings);
- }
-
-
- function pass() {
- var a, i, j, l, r, n, n1, n2, e, w, g, k, m;
- var outboundAttCompensation,
- coefficient,
- xDist,
- yDist,
- ewc,
- mass,
- distance,
- size,
- factor;
-
-
-
- for (n = 0; n < W.nodesLength; n += W.ppn) {
- NodeMatrix[np(n, 'old_dx')] = NodeMatrix[np(n, 'dx')];
- NodeMatrix[np(n, 'old_dy')] = NodeMatrix[np(n, 'dy')];
- NodeMatrix[np(n, 'dx')] = 0;
- NodeMatrix[np(n, 'dy')] = 0;
- }
-
- if (W.settings.outboundAttractionDistribution) {
- outboundAttCompensation = 0;
- for (n = 0; n < W.nodesLength; n += W.ppn) {
- outboundAttCompensation += NodeMatrix[np(n, 'mass')];
- }
- outboundAttCompensation /= W.nodesLength;
- }
-
-
- if (W.settings.barnesHutOptimize) {
- var minX = Infinity,
- maxX = -Infinity,
- minY = Infinity,
- maxY = -Infinity,
- q, q0, q1, q2, q3;
-
-
- RegionMatrix = [];
-
- for (n = 0; n < W.nodesLength; n += W.ppn) {
- minX = Math.min(minX, NodeMatrix[np(n, 'x')]);
- maxX = Math.max(maxX, NodeMatrix[np(n, 'x')]);
- minY = Math.min(minY, NodeMatrix[np(n, 'y')]);
- maxY = Math.max(maxY, NodeMatrix[np(n, 'y')]);
- }
-
- RegionMatrix[rp(0, 'node')] = -1;
- RegionMatrix[rp(0, 'centerX')] = (minX + maxX) / 2;
- RegionMatrix[rp(0, 'centerY')] = (minY + maxY) / 2;
- RegionMatrix[rp(0, 'size')] = Math.max(maxX - minX, maxY - minY);
- RegionMatrix[rp(0, 'nextSibling')] = -1;
- RegionMatrix[rp(0, 'firstChild')] = -1;
- RegionMatrix[rp(0, 'mass')] = 0;
- RegionMatrix[rp(0, 'massCenterX')] = 0;
- RegionMatrix[rp(0, 'massCenterY')] = 0;
-
- l = 1;
- for (n = 0; n < W.nodesLength; n += W.ppn) {
-
- r = 0;
- while (true) {
-
-
- if (RegionMatrix[rp(r, 'firstChild')] >= 0) {
-
-
-
-
-
- if (NodeMatrix[np(n, 'x')] < RegionMatrix[rp(r, 'centerX')]) {
- if (NodeMatrix[np(n, 'y')] < RegionMatrix[rp(r, 'centerY')]) {
-
- q = RegionMatrix[rp(r, 'firstChild')];
- }
- else {
-
- q = RegionMatrix[rp(r, 'firstChild')] + W.ppr;
- }
- }
- else {
- if (NodeMatrix[np(n, 'y')] < RegionMatrix[rp(r, 'centerY')]) {
-
- q = RegionMatrix[rp(r, 'firstChild')] + W.ppr * 2;
- }
- else {
-
- q = RegionMatrix[rp(r, 'firstChild')] + W.ppr * 3;
- }
- }
-
- RegionMatrix[rp(r, 'massCenterX')] =
- (RegionMatrix[rp(r, 'massCenterX')] * RegionMatrix[rp(r, 'mass')] +
- NodeMatrix[np(n, 'x')] * NodeMatrix[np(n, 'mass')]) /
- (RegionMatrix[rp(r, 'mass')] + NodeMatrix[np(n, 'mass')]);
- RegionMatrix[rp(r, 'massCenterY')] =
- (RegionMatrix[rp(r, 'massCenterY')] * RegionMatrix[rp(r, 'mass')] +
- NodeMatrix[np(n, 'y')] * NodeMatrix[np(n, 'mass')]) /
- (RegionMatrix[rp(r, 'mass')] + NodeMatrix[np(n, 'mass')]);
- RegionMatrix[rp(r, 'mass')] += NodeMatrix[np(n, 'mass')];
-
- r = q;
- continue;
- }
- else {
-
-
- if (RegionMatrix[rp(r, 'node')] < 0) {
-
-
- RegionMatrix[rp(r, 'node')] = n;
- break;
- }
- else {
-
-
-
-
-
-
- RegionMatrix[rp(r, 'firstChild')] = l * W.ppr;
- w = RegionMatrix[rp(r, 'size')] / 2;
-
-
-
- g = RegionMatrix[rp(r, 'firstChild')];
- RegionMatrix[rp(g, 'node')] = -1;
- RegionMatrix[rp(g, 'centerX')] = RegionMatrix[rp(r, 'centerX')] - w;
- RegionMatrix[rp(g, 'centerY')] = RegionMatrix[rp(r, 'centerY')] - w;
- RegionMatrix[rp(g, 'size')] = w;
- RegionMatrix[rp(g, 'nextSibling')] = g + W.ppr;
- RegionMatrix[rp(g, 'firstChild')] = -1;
- RegionMatrix[rp(g, 'mass')] = 0;
- RegionMatrix[rp(g, 'massCenterX')] = 0;
- RegionMatrix[rp(g, 'massCenterY')] = 0;
-
- g += W.ppr;
- RegionMatrix[rp(g, 'node')] = -1;
- RegionMatrix[rp(g, 'centerX')] = RegionMatrix[rp(r, 'centerX')] - w;
- RegionMatrix[rp(g, 'centerY')] = RegionMatrix[rp(r, 'centerY')] + w;
- RegionMatrix[rp(g, 'size')] = w;
- RegionMatrix[rp(g, 'nextSibling')] = g + W.ppr;
- RegionMatrix[rp(g, 'firstChild')] = -1;
- RegionMatrix[rp(g, 'mass')] = 0;
- RegionMatrix[rp(g, 'massCenterX')] = 0;
- RegionMatrix[rp(g, 'massCenterY')] = 0;
-
- g += W.ppr;
- RegionMatrix[rp(g, 'node')] = -1;
- RegionMatrix[rp(g, 'centerX')] = RegionMatrix[rp(r, 'centerX')] + w;
- RegionMatrix[rp(g, 'centerY')] = RegionMatrix[rp(r, 'centerY')] - w;
- RegionMatrix[rp(g, 'size')] = w;
- RegionMatrix[rp(g, 'nextSibling')] = g + W.ppr;
- RegionMatrix[rp(g, 'firstChild')] = -1;
- RegionMatrix[rp(g, 'mass')] = 0;
- RegionMatrix[rp(g, 'massCenterX')] = 0;
- RegionMatrix[rp(g, 'massCenterY')] = 0;
-
- g += W.ppr;
- RegionMatrix[rp(g, 'node')] = -1;
- RegionMatrix[rp(g, 'centerX')] = RegionMatrix[rp(r, 'centerX')] + w;
- RegionMatrix[rp(g, 'centerY')] = RegionMatrix[rp(r, 'centerY')] + w;
- RegionMatrix[rp(g, 'size')] = w;
- RegionMatrix[rp(g, 'nextSibling')] = RegionMatrix[rp(r, 'nextSibling')];
- RegionMatrix[rp(g, 'firstChild')] = -1;
- RegionMatrix[rp(g, 'mass')] = 0;
- RegionMatrix[rp(g, 'massCenterX')] = 0;
- RegionMatrix[rp(g, 'massCenterY')] = 0;
- l += 4;
-
-
-
-
- if (NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'x')] < RegionMatrix[rp(r, 'centerX')]) {
- if (NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'y')] < RegionMatrix[rp(r, 'centerY')]) {
-
- q = RegionMatrix[rp(r, 'firstChild')];
- }
- else {
-
- q = RegionMatrix[rp(r, 'firstChild')] + W.ppr;
- }
- }
- else {
- if (NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'y')] < RegionMatrix[rp(r, 'centerY')]) {
-
- q = RegionMatrix[rp(r, 'firstChild')] + W.ppr * 2;
- }
- else {
-
- q = RegionMatrix[rp(r, 'firstChild')] + W.ppr * 3;
- }
- }
-
- RegionMatrix[rp(r, 'mass')] = NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'mass')];
- RegionMatrix[rp(r, 'massCenterX')] = NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'x')];
- RegionMatrix[rp(r, 'massCenterY')] = NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'y')];
- RegionMatrix[rp(q, 'node')] = RegionMatrix[rp(r, 'node')];
- RegionMatrix[rp(r, 'node')] = -1;
-
- if (NodeMatrix[np(n, 'x')] < RegionMatrix[rp(r, 'centerX')]) {
- if (NodeMatrix[np(n, 'y')] < RegionMatrix[rp(r, 'centerY')]) {
-
- q2 = RegionMatrix[rp(r, 'firstChild')];
- }
- else {
-
- q2 = RegionMatrix[rp(r, 'firstChild')] + W.ppr;
- }
- }
- else {
- if(NodeMatrix[np(n, 'y')] < RegionMatrix[rp(r, 'centerY')]) {
-
- q2 = RegionMatrix[rp(r, 'firstChild')] + W.ppr * 2;
- }
- else {
-
- q2 = RegionMatrix[rp(r, 'firstChild')] + W.ppr * 3;
- }
- }
- if (q === q2) {
-
-
- r = q;
- continue;
- }
-
-
- RegionMatrix[rp(q2, 'node')] = n;
- break;
- }
- }
- }
- }
- }
-
-
-
- if (W.settings.barnesHutOptimize) {
- coefficient = W.settings.scalingRatio;
-
- for (n = 0; n < W.nodesLength; n += W.ppn) {
-
- r = 0;
- while (true) {
- if (RegionMatrix[rp(r, 'firstChild')] >= 0) {
-
-
- distance = Math.sqrt(
- (Math.pow(NodeMatrix[np(n, 'x')] - RegionMatrix[rp(r, 'massCenterX')], 2)) +
- (Math.pow(NodeMatrix[np(n, 'y')] - RegionMatrix[rp(r, 'massCenterY')], 2))
- );
- if (2 * RegionMatrix[rp(r, 'size')] / distance < W.settings.barnesHutTheta) {
-
- xDist = NodeMatrix[np(n, 'x')] - RegionMatrix[rp(r, 'massCenterX')];
- yDist = NodeMatrix[np(n, 'y')] - RegionMatrix[rp(r, 'massCenterY')];
- if (W.settings.adjustSizes) {
-
- if (distance > 0) {
- factor = coefficient * NodeMatrix[np(n, 'mass')] *
- RegionMatrix[rp(r, 'mass')] / distance / distance;
- NodeMatrix[np(n, 'dx')] += xDist * factor;
- NodeMatrix[np(n, 'dy')] += yDist * factor;
- }
- else if (distance < 0) {
- factor = -coefficient * NodeMatrix[np(n, 'mass')] *
- RegionMatrix[rp(r, 'mass')] / distance;
- NodeMatrix[np(n, 'dx')] += xDist * factor;
- NodeMatrix[np(n, 'dy')] += yDist * factor;
- }
- }
- else {
-
- if (distance > 0) {
- factor = coefficient * NodeMatrix[np(n, 'mass')] *
- RegionMatrix[rp(r, 'mass')] / distance / distance;
- NodeMatrix[np(n, 'dx')] += xDist * factor;
- NodeMatrix[np(n, 'dy')] += yDist * factor;
- }
- }
-
- if (RegionMatrix[rp(r, 'nextSibling')] < 0)
- break;
- r = RegionMatrix[rp(r, 'nextSibling')];
- continue;
- }
- else {
-
- r = RegionMatrix[rp(r, 'firstChild')];
- continue;
- }
- }
- else {
-
-
- if (RegionMatrix[rp(r, 'node')] >= 0 && RegionMatrix[rp(r, 'node')] !== n) {
- xDist = NodeMatrix[np(n, 'x')] - NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'x')];
- yDist = NodeMatrix[np(n, 'y')] - NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'y')];
- distance = Math.sqrt(xDist * xDist + yDist * yDist);
- if (W.settings.adjustSizes) {
-
- if (distance > 0) {
- factor = coefficient * NodeMatrix[np(n, 'mass')] *
- NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'mass')] / distance / distance;
- NodeMatrix[np(n, 'dx')] += xDist * factor;
- NodeMatrix[np(n, 'dy')] += yDist * factor;
- }
- else if (distance < 0) {
- factor = -coefficient * NodeMatrix[np(n, 'mass')] *
- NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'mass')] / distance;
- NodeMatrix[np(n, 'dx')] += xDist * factor;
- NodeMatrix[np(n, 'dy')] += yDist * factor;
- }
- }
- else {
-
- if (distance > 0) {
- factor = coefficient * NodeMatrix[np(n, 'mass')] *
- NodeMatrix[np(RegionMatrix[rp(r, 'node')], 'mass')] / distance / distance;
- NodeMatrix[np(n, 'dx')] += xDist * factor;
- NodeMatrix[np(n, 'dy')] += yDist * factor;
- }
- }
- }
-
- if (RegionMatrix[rp(r, 'nextSibling')] < 0)
- break;
- r = RegionMatrix[rp(r, 'nextSibling')];
- continue;
- }
- }
- }
- }
- else {
- coefficient = W.settings.scalingRatio;
-
- for (n1 = 0; n1 < W.nodesLength; n1 += W.ppn) {
- for (n2 = 0; n2 < n1; n2 += W.ppn) {
-
- xDist = NodeMatrix[np(n1, 'x')] - NodeMatrix[np(n2, 'x')];
- yDist = NodeMatrix[np(n1, 'y')] - NodeMatrix[np(n2, 'y')];
- if (W.settings.adjustSizes) {
-
- distance = Math.sqrt(xDist * xDist + yDist * yDist) -
- NodeMatrix[np(n1, 'size')] -
- NodeMatrix[np(n2, 'size')];
- if (distance > 0) {
- factor = coefficient *
- NodeMatrix[np(n1, 'mass')] *
- NodeMatrix[np(n2, 'mass')] /
- distance / distance;
-
- NodeMatrix[np(n1, 'dx')] += xDist * factor;
- NodeMatrix[np(n1, 'dy')] += yDist * factor;
- NodeMatrix[np(n2, 'dx')] += xDist * factor;
- NodeMatrix[np(n2, 'dy')] += yDist * factor;
- }
- else if (distance < 0) {
- factor = 100 * coefficient *
- NodeMatrix[np(n1, 'mass')] *
- NodeMatrix[np(n2, 'mass')];
-
- NodeMatrix[np(n1, 'dx')] += xDist * factor;
- NodeMatrix[np(n1, 'dy')] += yDist * factor;
- NodeMatrix[np(n2, 'dx')] -= xDist * factor;
- NodeMatrix[np(n2, 'dy')] -= yDist * factor;
- }
- }
- else {
-
- distance = Math.sqrt(xDist * xDist + yDist * yDist);
- if (distance > 0) {
- factor = coefficient *
- NodeMatrix[np(n1, 'mass')] *
- NodeMatrix[np(n2, 'mass')] /
- distance / distance;
-
- NodeMatrix[np(n1, 'dx')] += xDist * factor;
- NodeMatrix[np(n1, 'dy')] += yDist * factor;
- NodeMatrix[np(n2, 'dx')] -= xDist * factor;
- NodeMatrix[np(n2, 'dy')] -= yDist * factor;
- }
- }
- }
- }
- }
-
-
- g = W.settings.gravity / W.settings.scalingRatio;
- coefficient = W.settings.scalingRatio;
- for (n = 0; n < W.nodesLength; n += W.ppn) {
- factor = 0;
-
- xDist = NodeMatrix[np(n, 'x')];
- yDist = NodeMatrix[np(n, 'y')];
- distance = Math.sqrt(
- Math.pow(xDist, 2) + Math.pow(yDist, 2)
- );
- if (W.settings.strongGravityMode) {
-
- if (distance > 0)
- factor = coefficient * NodeMatrix[np(n, 'mass')] * g;
- }
- else {
-
- if (distance > 0)
- factor = coefficient * NodeMatrix[np(n, 'mass')] * g / distance;
- }
-
- NodeMatrix[np(n, 'dx')] -= xDist * factor;
- NodeMatrix[np(n, 'dy')] -= yDist * factor;
- }
-
-
- coefficient = 1 *
- (W.settings.outboundAttractionDistribution ?
- outboundAttCompensation :
- 1);
-
-
- for (e = 0; e < W.edgesLength; e += W.ppe) {
- n1 = EdgeMatrix[ep(e, 'source')];
- n2 = EdgeMatrix[ep(e, 'target')];
- w = EdgeMatrix[ep(e, 'weight')];
-
- ewc = Math.pow(w, W.settings.edgeWeightInfluence);
-
- xDist = NodeMatrix[np(n1, 'x')] - NodeMatrix[np(n2, 'x')];
- yDist = NodeMatrix[np(n1, 'y')] - NodeMatrix[np(n2, 'y')];
-
- if (W.settings.adjustSizes) {
- distance = Math.sqrt(
- (Math.pow(xDist, 2) + Math.pow(yDist, 2)) -
- NodeMatrix[np(n1, 'size')] -
- NodeMatrix[np(n2, 'size')]
- );
- if (W.settings.linLogMode) {
- if (W.settings.outboundAttractionDistribution) {
-
- if (distance > 0) {
- factor = -coefficient * ewc * Math.log(1 + distance) /
- distance /
- NodeMatrix[np(n1, 'mass')];
- }
- }
- else {
-
- if (distance > 0) {
- factor = -coefficient * ewc * Math.log(1 + distance) / distance;
- }
- }
- }
- else {
- if (W.settings.outboundAttractionDistribution) {
-
- if (distance > 0) {
- factor = -coefficient * ewc / NodeMatrix[np(n1, 'mass')];
- }
- }
- else {
-
- if (distance > 0) {
- factor = -coefficient * ewc;
- }
- }
- }
- }
- else {
- distance = Math.sqrt(
- Math.pow(xDist, 2) + Math.pow(yDist, 2)
- );
- if (W.settings.linLogMode) {
- if (W.settings.outboundAttractionDistribution) {
-
- if (distance > 0) {
- factor = -coefficient * ewc * Math.log(1 + distance) /
- distance /
- NodeMatrix[np(n1, 'mass')];
- }
- }
- else {
-
- if (distance > 0)
- factor = -coefficient * ewc * Math.log(1 + distance) / distance;
- }
- }
- else {
- if (W.settings.outboundAttractionDistribution) {
-
-
- distance = 1;
- factor = -coefficient * ewc / NodeMatrix[np(n1, 'mass')];
- }
- else {
-
-
- distance = 1;
- factor = -coefficient * ewc;
- }
- }
- }
-
-
- if (distance > 0) {
-
- NodeMatrix[np(n1, 'dx')] += xDist * factor;
- NodeMatrix[np(n1, 'dy')] += yDist * factor;
- NodeMatrix[np(n2, 'dx')] -= xDist * factor;
- NodeMatrix[np(n2, 'dy')] -= yDist * factor;
- }
- }
-
-
- var force,
- swinging,
- traction,
- nodespeed;
-
- if (W.settings.adjustSizes) {
- for (n = 0; n < W.nodesLength; n += W.ppn) {
- if (!NodeMatrix[np(n, 'fixed')]) {
- force = Math.sqrt(
- Math.pow(NodeMatrix[np(n, 'dx')], 2) +
- Math.pow(NodeMatrix[np(n, 'dy')], 2)
- );
- if (force > W.maxForce) {
- NodeMatrix[np(n, 'dx')] =
- NodeMatrix[np(n, 'dx')] * W.maxForce / force;
- NodeMatrix[np(n, 'dy')] =
- NodeMatrix[np(n, 'dy')] * W.maxForce / force;
- }
- swinging = NodeMatrix[np(n, 'mass')] *
- Math.sqrt(
- (NodeMatrix[np(n, 'old_dx')] - NodeMatrix[np(n, 'dx')]) *
- (NodeMatrix[np(n, 'old_dx')] - NodeMatrix[np(n, 'dx')]) +
- (NodeMatrix[np(n, 'old_dy')] - NodeMatrix[np(n, 'dy')]) *
- (NodeMatrix[np(n, 'old_dy')] - NodeMatrix[np(n, 'dy')])
- );
- traction = Math.sqrt(
- (NodeMatrix[np(n, 'old_dx')] + NodeMatrix[np(n, 'dx')]) *
- (NodeMatrix[np(n, 'old_dx')] + NodeMatrix[np(n, 'dx')]) +
- (NodeMatrix[np(n, 'old_dy')] + NodeMatrix[np(n, 'dy')]) *
- (NodeMatrix[np(n, 'old_dy')] + NodeMatrix[np(n, 'dy')])
- ) / 2;
- nodespeed =
- 0.1 * Math.log(1 + traction) / (1 + Math.sqrt(swinging));
-
- NodeMatrix[np(n, 'x')] =
- NodeMatrix[np(n, 'x')] + NodeMatrix[np(n, 'dx')] *
- (nodespeed / W.settings.slowDown);
- NodeMatrix[np(n, 'y')] =
- NodeMatrix[np(n, 'y')] + NodeMatrix[np(n, 'dy')] *
- (nodespeed / W.settings.slowDown);
- }
- }
- }
- else {
- for (n = 0; n < W.nodesLength; n += W.ppn) {
- if (!NodeMatrix[np(n, 'fixed')]) {
- swinging = NodeMatrix[np(n, 'mass')] *
- Math.sqrt(
- (NodeMatrix[np(n, 'old_dx')] - NodeMatrix[np(n, 'dx')]) *
- (NodeMatrix[np(n, 'old_dx')] - NodeMatrix[np(n, 'dx')]) +
- (NodeMatrix[np(n, 'old_dy')] - NodeMatrix[np(n, 'dy')]) *
- (NodeMatrix[np(n, 'old_dy')] - NodeMatrix[np(n, 'dy')])
- );
- traction = Math.sqrt(
- (NodeMatrix[np(n, 'old_dx')] + NodeMatrix[np(n, 'dx')]) *
- (NodeMatrix[np(n, 'old_dx')] + NodeMatrix[np(n, 'dx')]) +
- (NodeMatrix[np(n, 'old_dy')] + NodeMatrix[np(n, 'dy')]) *
- (NodeMatrix[np(n, 'old_dy')] + NodeMatrix[np(n, 'dy')])
- ) / 2;
- nodespeed = NodeMatrix[np(n, 'convergence')] *
- Math.log(1 + traction) / (1 + Math.sqrt(swinging));
-
- NodeMatrix[np(n, 'convergence')] =
- Math.min(1, Math.sqrt(
- nodespeed *
- (Math.pow(NodeMatrix[np(n, 'dx')], 2) +
- Math.pow(NodeMatrix[np(n, 'dy')], 2)) /
- (1 + Math.sqrt(swinging))
- ));
-
- NodeMatrix[np(n, 'x')] =
- NodeMatrix[np(n, 'x')] + NodeMatrix[np(n, 'dx')] *
- (nodespeed / W.settings.slowDown);
- NodeMatrix[np(n, 'y')] =
- NodeMatrix[np(n, 'y')] + NodeMatrix[np(n, 'dy')] *
- (nodespeed / W.settings.slowDown);
- }
- }
- }
-
- W.iterations++;
- }
-
-
- var sendNewCoords;
- if (typeof window !== 'undefined' && window.document) {
-
- sendNewCoords = function() {
- var e;
- if (document.createEvent) {
- e = document.createEvent('Event');
- e.initEvent('newCoords', true, false);
- }
- else {
- e = document.createEventObject();
- e.eventType = 'newCoords';
- }
- e.eventName = 'newCoords';
- e.data = {
- nodes: NodeMatrix.buffer
- };
- requestAnimationFrame(function() {
- document.dispatchEvent(e);
- });
- };
- }
- else {
-
- sendNewCoords = function() {
- self.postMessage(
- {nodes: NodeMatrix.buffer},
- [NodeMatrix.buffer]
- );
- };
- }
-
- function run(n) {
- for (var i = 0; i < n; i++)
- pass();
- sendNewCoords();
- }
-
- var listener = function(e) {
- switch (e.data.action) {
- case 'start':
- init(
- new Float32Array(e.data.nodes),
- new Float32Array(e.data.edges),
- e.data.config
- );
-
- run(W.settings.startingIterations);
- break;
- case 'loop':
- NodeMatrix = new Float32Array(e.data.nodes);
- run(W.settings.iterationsPerRender);
- break;
- case 'config':
-
- configure(e.data.config);
- break;
- case 'kill':
-
- __emptyObject(W);
- NodeMatrix = null;
- EdgeMatrix = null;
- RegionMatrix = null;
- self.removeEventListener('message', listener);
- break;
- default:
- }
- };
-
- self.addEventListener('message', listener);
- };
-
- function crush(fnString) {
- var pattern,
- i,
- l;
- var np = [
- 'x',
- 'y',
- 'dx',
- 'dy',
- 'old_dx',
- 'old_dy',
- 'mass',
- 'convergence',
- 'size',
- 'fixed'
- ];
- var ep = [
- 'source',
- 'target',
- 'weight'
- ];
- var rp = [
- 'node',
- 'centerX',
- 'centerY',
- 'size',
- 'nextSibling',
- 'firstChild',
- 'mass',
- 'massCenterX',
- 'massCenterY'
- ];
-
-
- for (i = 0, l = rp.length; i < l; i++) {
- pattern = new RegExp('rp\\(([^,]*), \'' + rp[i] + '\'\\)', 'g');
- fnString = fnString.replace(
- pattern,
- (i === 0) ? '$1' : '$1 + ' + i
- );
- }
-
- for (i = 0, l = np.length; i < l; i++) {
- pattern = new RegExp('np\\(([^,]*), \'' + np[i] + '\'\\)', 'g');
- fnString = fnString.replace(
- pattern,
- (i === 0) ? '$1' : '$1 + ' + i
- );
- }
-
- for (i = 0, l = ep.length; i < l; i++) {
- pattern = new RegExp('ep\\(([^,]*), \'' + ep[i] + '\'\\)', 'g');
- fnString = fnString.replace(
- pattern,
- (i === 0) ? '$1' : '$1 + ' + i
- );
- }
- return fnString;
- }
-
- function getWorkerFn() {
- var fnString = crush ? crush(Worker.toString()) : Worker.toString();
- return ';(' + fnString + ').call(this);';
- }
- if (inWebWorker) {
-
- eval(getWorkerFn());
- }
- else {
-
- if (typeof sigma === 'undefined')
- throw 'sigma is not declared';
- sigma.prototype.getForceAtlas2Worker = getWorkerFn;
- }
- }).call(this);
|