New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

graphology-layout-forceatlas2

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphology-layout-forceatlas2 - npm Package Compare versions

Comparing version 0.4.2 to 0.4.3

55

build/graphology-layout-forceatlas2.js

@@ -260,3 +260,3 @@ (function webpackUniversalModuleDefinition(root, factory) {

// Initializing variables
var l, r, n, n1, n2, e, w, g;
var l, r, n, n1, n2, rn, e, w, g, s;

@@ -266,2 +266,6 @@ var order = NodeMatrix.length,

var adjustSizes = options.adjustSizes;
var thetaSquared = options.barnesHutTheta * options.barnesHutTheta;
var outboundAttCompensation,

@@ -595,3 +599,3 @@ coefficient,

// We run the Barnes Hut test to see if we are at the right distance
distance = Math.sqrt(
distance = (
(Math.pow(NodeMatrix[n + NODE_X] - RegionMatrix[r + REGION_MASS_CENTER_X], 2)) +

@@ -601,4 +605,6 @@ (Math.pow(NodeMatrix[n + NODE_Y] - RegionMatrix[r + REGION_MASS_CENTER_Y], 2))

if (2 * RegionMatrix[r + REGION_SIZE] / distance < options.barnesHutTheta) {
s = RegionMatrix[r + REGION_SIZE];
if ((4 * s * s) / distance < thetaSquared) {
// We treat the region as a single body, and we repulse

@@ -609,3 +615,3 @@

if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -615,3 +621,3 @@ //-- Linear Anti-collision Repulsion

factor = coefficient * NodeMatrix[n + NODE_MASS] *
RegionMatrix[r + REGION_MASS] / distance / distance;
RegionMatrix[r + REGION_MASS] / distance;

@@ -623,3 +629,3 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

factor = -coefficient * NodeMatrix[n + NODE_MASS] *
RegionMatrix[r + REGION_MASS] / distance;
RegionMatrix[r + REGION_MASS] / Math.sqrt(distance);

@@ -635,3 +641,3 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

factor = coefficient * NodeMatrix[n + NODE_MASS] *
RegionMatrix[r + REGION_MASS] / distance / distance;
RegionMatrix[r + REGION_MASS] / distance;

@@ -644,7 +650,7 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

// When this is done, we iterate. We have to look at the next sibling.
if (RegionMatrix[r + REGION_NEXT_SIBLING] < 0)
r = RegionMatrix[r + REGION_NEXT_SIBLING];
if (r < 0)
break; // No next sibling: we have finished the tree
r = RegionMatrix[r + REGION_NEXT_SIBLING];
continue;
}

@@ -663,10 +669,11 @@ else {

// If there is a node r[0] and it is not n, then repulse
rn = RegionMatrix[r + REGION_NODE];
if (RegionMatrix[r + REGION_NODE] >= 0 && RegionMatrix[r + REGION_NODE] !== n) {
xDist = NodeMatrix[n + NODE_X] - NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_X];
yDist = NodeMatrix[n + NODE_Y] - NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y];
if (rn >= 0 && rn !== n) {
xDist = NodeMatrix[n + NODE_X] - NodeMatrix[rn + NODE_X];
yDist = NodeMatrix[n + NODE_Y] - NodeMatrix[rn + NODE_Y];
distance = Math.sqrt(xDist * xDist + yDist * yDist);
distance = xDist * xDist + yDist * yDist;
if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -676,3 +683,3 @@ //-- Linear Anti-collision Repulsion

factor = coefficient * NodeMatrix[n + NODE_MASS] *
NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance / distance;
NodeMatrix[rn + NODE_MASS] / distance;

@@ -684,3 +691,3 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

factor = -coefficient * NodeMatrix[n + NODE_MASS] *
NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance;
NodeMatrix[rn + NODE_MASS] / Math.sqrt(distance);

@@ -696,3 +703,3 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

factor = coefficient * NodeMatrix[n + NODE_MASS] *
NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance / distance;
NodeMatrix[rn + NODE_MASS] / distance;

@@ -707,5 +714,7 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

// When this is done, we iterate. We have to look at the next sibling.
if (RegionMatrix[r + REGION_NEXT_SIBLING] < 0)
r = RegionMatrix[r + REGION_NEXT_SIBLING];
if (r < 0)
break; // No next sibling: we have finished the tree
r = RegionMatrix[r + REGION_NEXT_SIBLING];
continue;

@@ -727,3 +736,3 @@ }

if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -839,3 +848,3 @@ //-- Anticollision Linear Repulsion

// Applying attraction to nodes
if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -948,3 +957,3 @@ distance = Math.sqrt(

// MATH: sqrt and square distances
if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -951,0 +960,0 @@ for (n = 0; n < order; n += PPN) {

@@ -1,1 +0,1 @@

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.forceAtlas2=e():t.forceAtlas2=e()}("undefined"!=typeof self?self:this,function(){return function(t){function e(n){if(o[n])return o[n].exports;var a=o[n]={i:n,l:!1,exports:{}};return t[n].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var o={};return e.m=t,e.c=o,e.d=function(t,o,n){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,"a",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,o){function n(t,e,o){if(!r(e))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");"number"==typeof o&&(o={iterations:o});var n=o.iterations;if("number"!=typeof n)throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(n<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var a=s.assign({},u,o.settings),l=s.validateSettings(a);if(l)throw new Error("graphology-layout-forceatlas2: "+l.message);var g,f=s.graphToByteArrays(e);for(g=0;g<n;g++)i(a,f.nodes,f.edges);return t?void s.assignLayoutChanges(e,f.nodes):s.collectLayoutChanges(e,f.nodes)}function a(t){var e=t.order;return{barnesHutOptimize:e>2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(e)}}var r=o(1),i=o(2),s=o(3),u=o(4),l=n.bind(null,!1);l.assign=n.bind(null,!0),l.inferSettings=a,t.exports=l},function(t,e){t.exports=function(t){return null!==t&&"object"==typeof t&&"function"==typeof t.addUndirectedEdgeWithKey&&"function"==typeof t.dropNode&&"boolean"==typeof t.multi}},function(t,e){t.exports=function(t,e,o){var n,a,r,i,s,u,l,g,f,h,d,b,c,p,y,M=e.length,w=o.length,m=[];for(r=0;r<M;r+=10)e[r+4]=e[r+2],e[r+5]=e[r+3],e[r+2]=0,e[r+3]=0;if(t.outboundAttractionDistribution){for(f=0,r=0;r<M;r+=10)f+=e[r+6];f/=M/10}if(t.barnesHutOptimize){var v,A,D,x=1/0,z=-1/0,j=1/0,q=-1/0;for(r=0;r<M;r+=10)x=Math.min(x,e[r+0]),z=Math.max(z,e[r+0]),j=Math.min(j,e[r+1]),q=Math.max(q,e[r+1]);var H=z-x,S=q-j;for(H>S?(j-=(H-S)/2,q=j+H):(x-=(S-H)/2,z=x+S),m[0]=-1,m[1]=(x+z)/2,m[2]=(j+q)/2,m[3]=Math.max(z-x,q-j),m[4]=-1,m[5]=-1,m[6]=0,m[7]=0,m[8]=0,n=1,r=0;r<M;r+=10)for(a=0,D=3;;){if(!(m[a+5]>=0)){if(m[a+0]<0){m[a+0]=r;break}if(m[a+5]=9*n,l=m[a+3]/2,g=m[a+5],m[g+0]=-1,m[g+1]=m[a+1]-l,m[g+2]=m[a+2]-l,m[g+3]=l,m[g+4]=g+9,m[g+5]=-1,m[g+6]=0,m[g+7]=0,m[g+8]=0,g+=9,m[g+0]=-1,m[g+1]=m[a+1]-l,m[g+2]=m[a+2]+l,m[g+3]=l,m[g+4]=g+9,m[g+5]=-1,m[g+6]=0,m[g+7]=0,m[g+8]=0,g+=9,m[g+0]=-1,m[g+1]=m[a+1]+l,m[g+2]=m[a+2]-l,m[g+3]=l,m[g+4]=g+9,m[g+5]=-1,m[g+6]=0,m[g+7]=0,m[g+8]=0,g+=9,m[g+0]=-1,m[g+1]=m[a+1]+l,m[g+2]=m[a+2]+l,m[g+3]=l,m[g+4]=m[a+4],m[g+5]=-1,m[g+6]=0,m[g+7]=0,m[g+8]=0,n+=4,v=e[m[a+0]+0]<m[a+1]?e[m[a+0]+1]<m[a+2]?m[a+5]:m[a+5]+9:e[m[a+0]+1]<m[a+2]?m[a+5]+18:m[a+5]+27,m[a+6]=e[m[a+0]+6],m[a+7]=e[m[a+0]+0],m[a+8]=e[m[a+0]+1],m[v+0]=m[a+0],m[a+0]=-1,A=e[r+0]<m[a+1]?e[r+1]<m[a+2]?m[a+5]:m[a+5]+9:e[r+1]<m[a+2]?m[a+5]+18:m[a+5]+27,v===A){if(D--){a=v;continue}D=3;break}m[A+0]=r;break}v=e[r+0]<m[a+1]?e[r+1]<m[a+2]?m[a+5]:m[a+5]+9:e[r+1]<m[a+2]?m[a+5]+18:m[a+5]+27,m[a+7]=(m[a+7]*m[a+6]+e[r+0]*e[r+6])/(m[a+6]+e[r+6]),m[a+8]=(m[a+8]*m[a+6]+e[r+1]*e[r+6])/(m[a+6]+e[r+6]),m[a+6]+=e[r+6],a=v}}if(t.barnesHutOptimize)for(h=t.scalingRatio,r=0;r<M;r+=10)for(a=0;;)if(m[a+5]>=0){if(p=Math.sqrt(Math.pow(e[r+0]-m[a+7],2)+Math.pow(e[r+1]-m[a+8],2)),2*m[a+3]/p<t.barnesHutTheta){if(d=e[r+0]-m[a+7],b=e[r+1]-m[a+8],t.adjustSizes?p>0?(y=h*e[r+6]*m[a+6]/p/p,e[r+2]+=d*y,e[r+3]+=b*y):p<0&&(y=-h*e[r+6]*m[a+6]/p,e[r+2]+=d*y,e[r+3]+=b*y):p>0&&(y=h*e[r+6]*m[a+6]/p/p,e[r+2]+=d*y,e[r+3]+=b*y),m[a+4]<0)break;a=m[a+4];continue}a=m[a+5]}else{if(m[a+0]>=0&&m[a+0]!==r&&(d=e[r+0]-e[m[a+0]+0],b=e[r+1]-e[m[a+0]+1],p=Math.sqrt(d*d+b*b),t.adjustSizes?p>0?(y=h*e[r+6]*e[m[a+0]+6]/p/p,e[r+2]+=d*y,e[r+3]+=b*y):p<0&&(y=-h*e[r+6]*e[m[a+0]+6]/p,e[r+2]+=d*y,e[r+3]+=b*y):p>0&&(y=h*e[r+6]*e[m[a+0]+6]/p/p,e[r+2]+=d*y,e[r+3]+=b*y)),m[a+4]<0)break;a=m[a+4]}else for(h=t.scalingRatio,i=0;i<M;i+=10)for(s=0;s<i;s+=10)d=e[i+0]-e[s+0],b=e[i+1]-e[s+1],t.adjustSizes?(p=Math.sqrt(d*d+b*b)-e[i+8]-e[s+8],p>0?(y=h*e[i+6]*e[s+6]/p/p,e[i+2]+=d*y,e[i+3]+=b*y,e[s+2]+=d*y,e[s+3]+=b*y):p<0&&(y=100*h*e[i+6]*e[s+6],e[i+2]+=d*y,e[i+3]+=b*y,e[s+2]-=d*y,e[s+3]-=b*y)):(p=Math.sqrt(d*d+b*b))>0&&(y=h*e[i+6]*e[s+6]/p/p,e[i+2]+=d*y,e[i+3]+=b*y,e[s+2]-=d*y,e[s+3]-=b*y);for(g=t.gravity/t.scalingRatio,h=t.scalingRatio,r=0;r<M;r+=10)y=0,d=e[r+0],b=e[r+1],p=Math.sqrt(Math.pow(d,2)+Math.pow(b,2)),t.strongGravityMode?p>0&&(y=h*e[r+6]*g):p>0&&(y=h*e[r+6]*g/p),e[r+2]-=d*y,e[r+3]-=b*y;for(h=1*(t.outboundAttractionDistribution?f:1),u=0;u<w;u+=3)i=o[u+0],s=o[u+1],l=o[u+2],c=Math.pow(l,t.edgeWeightInfluence),d=e[i+0]-e[s+0],b=e[i+1]-e[s+1],t.adjustSizes?(p=Math.sqrt(Math.pow(d,2)+Math.pow(b,2)-e[i+8]-e[s+8]),t.linLogMode?t.outboundAttractionDistribution?p>0&&(y=-h*c*Math.log(1+p)/p/e[i+6]):p>0&&(y=-h*c*Math.log(1+p)/p):t.outboundAttractionDistribution?p>0&&(y=-h*c/e[i+6]):p>0&&(y=-h*c)):(p=Math.sqrt(Math.pow(d,2)+Math.pow(b,2)),t.linLogMode?t.outboundAttractionDistribution?p>0&&(y=-h*c*Math.log(1+p)/p/e[i+6]):p>0&&(y=-h*c*Math.log(1+p)/p):t.outboundAttractionDistribution?(p=1,y=-h*c/e[i+6]):(p=1,y=-h*c)),p>0&&(e[i+2]+=d*y,e[i+3]+=b*y,e[s+2]-=d*y,e[s+3]-=b*y);var O,L,R,T,W,E;if(t.adjustSizes)for(r=0;r<M;r+=10)e[r+9]||(O=Math.sqrt(Math.pow(e[r+2],2)+Math.pow(e[r+3],2)),O>10&&(e[r+2]=10*e[r+2]/O,e[r+3]=10*e[r+3]/O),L=e[r+6]*Math.sqrt((e[r+4]-e[r+2])*(e[r+4]-e[r+2])+(e[r+5]-e[r+3])*(e[r+5]-e[r+3])),R=Math.sqrt((e[r+4]+e[r+2])*(e[r+4]+e[r+2])+(e[r+5]+e[r+3])*(e[r+5]+e[r+3]))/2,T=.1*Math.log(1+R)/(1+Math.sqrt(L)),W=e[r+0]+e[r+2]*(T/t.slowDown),e[r+0]=W,E=e[r+1]+e[r+3]*(T/t.slowDown),e[r+1]=E);else for(r=0;r<M;r+=10)e[r+9]||(L=e[r+6]*Math.sqrt((e[r+4]-e[r+2])*(e[r+4]-e[r+2])+(e[r+5]-e[r+3])*(e[r+5]-e[r+3])),R=Math.sqrt((e[r+4]+e[r+2])*(e[r+4]+e[r+2])+(e[r+5]+e[r+3])*(e[r+5]+e[r+3]))/2,T=e[r+7]*Math.log(1+R)/(1+Math.sqrt(L)),e[r+7]=Math.min(1,Math.sqrt(T*(Math.pow(e[r+2],2)+Math.pow(e[r+3],2))/(1+Math.sqrt(L)))),W=e[r+0]+e[r+2]*(T/t.slowDown),e[r+0]=W,E=e[r+1]+e[r+3]*(T/t.slowDown),e[r+1]=E);return{}}},function(t,e){e.assign=function(t){t=t||{};var e,o,n,a=Array.prototype.slice.call(arguments).slice(1);for(e=0,n=a.length;e<n;e++)if(a[e])for(o in a[e])t[o]=a[e][o];return t},e.validateSettings=function(t){return"linLogMode"in t&&"boolean"!=typeof t.linLogMode?{message:"the `linLogMode` setting should be a boolean."}:"outboundAttractionDistribution"in t&&"boolean"!=typeof t.outboundAttractionDistribution?{message:"the `outboundAttractionDistribution` setting should be a boolean."}:"adjustSizes"in t&&"boolean"!=typeof t.adjustSizes?{message:"the `adjustSizes` setting should be a boolean."}:"edgeWeightInfluence"in t&&"number"!=typeof t.edgeWeightInfluence&&t.edgeWeightInfluence<0?{message:"the `edgeWeightInfluence` setting should be a number >= 0."}:"scalingRatio"in t&&"number"!=typeof t.scalingRatio&&t.scalingRatio<0?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in t&&"boolean"!=typeof t.strongGravityMode?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in t&&"number"!=typeof t.gravity&&t.gravity<0?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in t&&"number"!=typeof t.slowDown&&t.slowDown<0?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in t&&"boolean"!=typeof t.barnesHutOptimize?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in t&&"number"!=typeof t.barnesHutTheta&&t.barnesHutTheta<0?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null},e.graphToByteArrays=function(t){var e,o,n=t.nodes(),a=t.edges(),r=n.length,i=a.length,s={},u=new Float32Array(10*r),l=new Float32Array(3*i);for(e=o=0;e<r;e++)s[n[e]]=o,u[o]=t.getNodeAttribute(n[e],"x"),u[o+1]=t.getNodeAttribute(n[e],"y"),u[o+2]=0,u[o+3]=0,u[o+4]=0,u[o+5]=0,u[o+6]=1+t.degree(n[e]),u[o+7]=1,u[o+8]=t.getNodeAttribute(n[e],"size")||1,u[o+9]=0,o+=10;for(e=o=0;e<i;e++)l[o]=s[t.source(a[e])],l[o+1]=s[t.target(a[e])],l[o+2]=t.getEdgeAttribute(a[e],"weight")||0,o+=3;return{nodes:u,edges:l}},e.assignLayoutChanges=function(t,e){for(var o=t.nodes(),n=0,a=0,r=e.length;n<r;n+=10)t.setNodeAttribute(o[a],"x",e[n]),t.setNodeAttribute(o[a],"y",e[n+1]),a++},e.collectLayoutChanges=function(t,e){for(var o=t.nodes(),n=Object.create(null),a=0,r=0,i=e.length;a<i;a+=10)n[o[r]]={x:e[a],y:e[a+1]},r++;return n}},function(t,e){t.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:0,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}}])});
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.forceAtlas2=e():t.forceAtlas2=e()}("undefined"!=typeof self?self:this,function(){return function(t){function e(n){if(o[n])return o[n].exports;var r=o[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var o={};return e.m=t,e.c=o,e.d=function(t,o,n){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,"a",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,o){function n(t,e,o){if(!a(e))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");"number"==typeof o&&(o={iterations:o});var n=o.iterations;if("number"!=typeof n)throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(n<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var r=s.assign({},u,o.settings),l=s.validateSettings(r);if(l)throw new Error("graphology-layout-forceatlas2: "+l.message);var g,f=s.graphToByteArrays(e);for(g=0;g<n;g++)i(r,f.nodes,f.edges);return t?void s.assignLayoutChanges(e,f.nodes):s.collectLayoutChanges(e,f.nodes)}function r(t){var e=t.order;return{barnesHutOptimize:e>2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(e)}}var a=o(1),i=o(2),s=o(3),u=o(4),l=n.bind(null,!1);l.assign=n.bind(null,!0),l.inferSettings=r,t.exports=l},function(t,e){t.exports=function(t){return null!==t&&"object"==typeof t&&"function"==typeof t.addUndirectedEdgeWithKey&&"function"==typeof t.dropNode&&"boolean"==typeof t.multi}},function(t,e){t.exports=function(t,e,o){var n,r,a,i,s,u,l,g,f,h,b,d,c,p,y,M,w,m=e.length,v=o.length,A=t.adjustSizes,D=t.barnesHutTheta*t.barnesHutTheta,x=[];for(a=0;a<m;a+=10)e[a+4]=e[a+2],e[a+5]=e[a+3],e[a+2]=0,e[a+3]=0;if(t.outboundAttractionDistribution){for(b=0,a=0;a<m;a+=10)b+=e[a+6];b/=m/10}if(t.barnesHutOptimize){var q,H,z,j=1/0,O=-1/0,L=1/0,R=-1/0;for(a=0;a<m;a+=10)j=Math.min(j,e[a+0]),O=Math.max(O,e[a+0]),L=Math.min(L,e[a+1]),R=Math.max(R,e[a+1]);var T=O-j,S=R-L;for(T>S?(L-=(T-S)/2,R=L+T):(j-=(S-T)/2,O=j+S),x[0]=-1,x[1]=(j+O)/2,x[2]=(L+R)/2,x[3]=Math.max(O-j,R-L),x[4]=-1,x[5]=-1,x[6]=0,x[7]=0,x[8]=0,n=1,a=0;a<m;a+=10)for(r=0,z=3;;){if(!(x[r+5]>=0)){if(x[r+0]<0){x[r+0]=a;break}if(x[r+5]=9*n,g=x[r+3]/2,f=x[r+5],x[f+0]=-1,x[f+1]=x[r+1]-g,x[f+2]=x[r+2]-g,x[f+3]=g,x[f+4]=f+9,x[f+5]=-1,x[f+6]=0,x[f+7]=0,x[f+8]=0,f+=9,x[f+0]=-1,x[f+1]=x[r+1]-g,x[f+2]=x[r+2]+g,x[f+3]=g,x[f+4]=f+9,x[f+5]=-1,x[f+6]=0,x[f+7]=0,x[f+8]=0,f+=9,x[f+0]=-1,x[f+1]=x[r+1]+g,x[f+2]=x[r+2]-g,x[f+3]=g,x[f+4]=f+9,x[f+5]=-1,x[f+6]=0,x[f+7]=0,x[f+8]=0,f+=9,x[f+0]=-1,x[f+1]=x[r+1]+g,x[f+2]=x[r+2]+g,x[f+3]=g,x[f+4]=x[r+4],x[f+5]=-1,x[f+6]=0,x[f+7]=0,x[f+8]=0,n+=4,q=e[x[r+0]+0]<x[r+1]?e[x[r+0]+1]<x[r+2]?x[r+5]:x[r+5]+9:e[x[r+0]+1]<x[r+2]?x[r+5]+18:x[r+5]+27,x[r+6]=e[x[r+0]+6],x[r+7]=e[x[r+0]+0],x[r+8]=e[x[r+0]+1],x[q+0]=x[r+0],x[r+0]=-1,H=e[a+0]<x[r+1]?e[a+1]<x[r+2]?x[r+5]:x[r+5]+9:e[a+1]<x[r+2]?x[r+5]+18:x[r+5]+27,q===H){if(z--){r=q;continue}z=3;break}x[H+0]=a;break}q=e[a+0]<x[r+1]?e[a+1]<x[r+2]?x[r+5]:x[r+5]+9:e[a+1]<x[r+2]?x[r+5]+18:x[r+5]+27,x[r+7]=(x[r+7]*x[r+6]+e[a+0]*e[a+6])/(x[r+6]+e[a+6]),x[r+8]=(x[r+8]*x[r+6]+e[a+1]*e[a+6])/(x[r+6]+e[a+6]),x[r+6]+=e[a+6],r=q}}if(t.barnesHutOptimize){for(d=t.scalingRatio,a=0;a<m;a+=10)for(r=0;;)if(x[r+5]>=0){if(M=Math.pow(e[a+0]-x[r+7],2)+Math.pow(e[a+1]-x[r+8],2),4*(h=x[r+3])*h/M<D){if(c=e[a+0]-x[r+7],p=e[a+1]-x[r+8],!0===A?M>0?(w=d*e[a+6]*x[r+6]/M,e[a+2]+=c*w,e[a+3]+=p*w):M<0&&(w=-d*e[a+6]*x[r+6]/Math.sqrt(M),e[a+2]+=c*w,e[a+3]+=p*w):M>0&&(w=d*e[a+6]*x[r+6]/M,e[a+2]+=c*w,e[a+3]+=p*w),(r=x[r+4])<0)break;continue}r=x[r+5]}else if(u=x[r+0],u>=0&&u!==a&&(c=e[a+0]-e[u+0],p=e[a+1]-e[u+1],M=c*c+p*p,!0===A?M>0?(w=d*e[a+6]*e[u+6]/M,e[a+2]+=c*w,e[a+3]+=p*w):M<0&&(w=-d*e[a+6]*e[u+6]/Math.sqrt(M),e[a+2]+=c*w,e[a+3]+=p*w):M>0&&(w=d*e[a+6]*e[u+6]/M,e[a+2]+=c*w,e[a+3]+=p*w)),(r=x[r+4])<0)break}else for(d=t.scalingRatio,i=0;i<m;i+=10)for(s=0;s<i;s+=10)c=e[i+0]-e[s+0],p=e[i+1]-e[s+1],!0===A?(M=Math.sqrt(c*c+p*p)-e[i+8]-e[s+8],M>0?(w=d*e[i+6]*e[s+6]/M/M,e[i+2]+=c*w,e[i+3]+=p*w,e[s+2]+=c*w,e[s+3]+=p*w):M<0&&(w=100*d*e[i+6]*e[s+6],e[i+2]+=c*w,e[i+3]+=p*w,e[s+2]-=c*w,e[s+3]-=p*w)):(M=Math.sqrt(c*c+p*p))>0&&(w=d*e[i+6]*e[s+6]/M/M,e[i+2]+=c*w,e[i+3]+=p*w,e[s+2]-=c*w,e[s+3]-=p*w);for(f=t.gravity/t.scalingRatio,d=t.scalingRatio,a=0;a<m;a+=10)w=0,c=e[a+0],p=e[a+1],M=Math.sqrt(Math.pow(c,2)+Math.pow(p,2)),t.strongGravityMode?M>0&&(w=d*e[a+6]*f):M>0&&(w=d*e[a+6]*f/M),e[a+2]-=c*w,e[a+3]-=p*w;for(d=1*(t.outboundAttractionDistribution?b:1),l=0;l<v;l+=3)i=o[l+0],s=o[l+1],g=o[l+2],y=Math.pow(g,t.edgeWeightInfluence),c=e[i+0]-e[s+0],p=e[i+1]-e[s+1],!0===A?(M=Math.sqrt(Math.pow(c,2)+Math.pow(p,2)-e[i+8]-e[s+8]),t.linLogMode?t.outboundAttractionDistribution?M>0&&(w=-d*y*Math.log(1+M)/M/e[i+6]):M>0&&(w=-d*y*Math.log(1+M)/M):t.outboundAttractionDistribution?M>0&&(w=-d*y/e[i+6]):M>0&&(w=-d*y)):(M=Math.sqrt(Math.pow(c,2)+Math.pow(p,2)),t.linLogMode?t.outboundAttractionDistribution?M>0&&(w=-d*y*Math.log(1+M)/M/e[i+6]):M>0&&(w=-d*y*Math.log(1+M)/M):t.outboundAttractionDistribution?(M=1,w=-d*y/e[i+6]):(M=1,w=-d*y)),M>0&&(e[i+2]+=c*w,e[i+3]+=p*w,e[s+2]-=c*w,e[s+3]-=p*w);var W,E,G,I,N,k;if(!0===A)for(a=0;a<m;a+=10)e[a+9]||(W=Math.sqrt(Math.pow(e[a+2],2)+Math.pow(e[a+3],2)),W>10&&(e[a+2]=10*e[a+2]/W,e[a+3]=10*e[a+3]/W),E=e[a+6]*Math.sqrt((e[a+4]-e[a+2])*(e[a+4]-e[a+2])+(e[a+5]-e[a+3])*(e[a+5]-e[a+3])),G=Math.sqrt((e[a+4]+e[a+2])*(e[a+4]+e[a+2])+(e[a+5]+e[a+3])*(e[a+5]+e[a+3]))/2,I=.1*Math.log(1+G)/(1+Math.sqrt(E)),N=e[a+0]+e[a+2]*(I/t.slowDown),e[a+0]=N,k=e[a+1]+e[a+3]*(I/t.slowDown),e[a+1]=k);else for(a=0;a<m;a+=10)e[a+9]||(E=e[a+6]*Math.sqrt((e[a+4]-e[a+2])*(e[a+4]-e[a+2])+(e[a+5]-e[a+3])*(e[a+5]-e[a+3])),G=Math.sqrt((e[a+4]+e[a+2])*(e[a+4]+e[a+2])+(e[a+5]+e[a+3])*(e[a+5]+e[a+3]))/2,I=e[a+7]*Math.log(1+G)/(1+Math.sqrt(E)),e[a+7]=Math.min(1,Math.sqrt(I*(Math.pow(e[a+2],2)+Math.pow(e[a+3],2))/(1+Math.sqrt(E)))),N=e[a+0]+e[a+2]*(I/t.slowDown),e[a+0]=N,k=e[a+1]+e[a+3]*(I/t.slowDown),e[a+1]=k);return{}}},function(t,e){e.assign=function(t){t=t||{};var e,o,n,r=Array.prototype.slice.call(arguments).slice(1);for(e=0,n=r.length;e<n;e++)if(r[e])for(o in r[e])t[o]=r[e][o];return t},e.validateSettings=function(t){return"linLogMode"in t&&"boolean"!=typeof t.linLogMode?{message:"the `linLogMode` setting should be a boolean."}:"outboundAttractionDistribution"in t&&"boolean"!=typeof t.outboundAttractionDistribution?{message:"the `outboundAttractionDistribution` setting should be a boolean."}:"adjustSizes"in t&&"boolean"!=typeof t.adjustSizes?{message:"the `adjustSizes` setting should be a boolean."}:"edgeWeightInfluence"in t&&"number"!=typeof t.edgeWeightInfluence&&t.edgeWeightInfluence<0?{message:"the `edgeWeightInfluence` setting should be a number >= 0."}:"scalingRatio"in t&&"number"!=typeof t.scalingRatio&&t.scalingRatio<0?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in t&&"boolean"!=typeof t.strongGravityMode?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in t&&"number"!=typeof t.gravity&&t.gravity<0?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in t&&"number"!=typeof t.slowDown&&t.slowDown<0?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in t&&"boolean"!=typeof t.barnesHutOptimize?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in t&&"number"!=typeof t.barnesHutTheta&&t.barnesHutTheta<0?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null},e.graphToByteArrays=function(t){var e,o,n=t.nodes(),r=t.edges(),a=n.length,i=r.length,s={},u=new Float32Array(10*a),l=new Float32Array(3*i);for(e=o=0;e<a;e++)s[n[e]]=o,u[o]=t.getNodeAttribute(n[e],"x"),u[o+1]=t.getNodeAttribute(n[e],"y"),u[o+2]=0,u[o+3]=0,u[o+4]=0,u[o+5]=0,u[o+6]=1+t.degree(n[e]),u[o+7]=1,u[o+8]=t.getNodeAttribute(n[e],"size")||1,u[o+9]=0,o+=10;for(e=o=0;e<i;e++)l[o]=s[t.source(r[e])],l[o+1]=s[t.target(r[e])],l[o+2]=t.getEdgeAttribute(r[e],"weight")||0,o+=3;return{nodes:u,edges:l}},e.assignLayoutChanges=function(t,e){for(var o=t.nodes(),n=0,r=0,a=e.length;n<a;n+=10)t.setNodeAttribute(o[r],"x",e[n]),t.setNodeAttribute(o[r],"y",e[n+1]),r++},e.collectLayoutChanges=function(t,e){for(var o=t.nodes(),n=Object.create(null),r=0,a=0,i=e.length;r<i;r+=10)n[o[a]]={x:e[r],y:e[r+1]},a++;return n}},function(t,e){t.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:0,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}}])});

@@ -59,3 +59,3 @@ /* eslint no-constant-condition: 0 */

// Initializing variables
var l, r, n, n1, n2, e, w, g;
var l, r, n, n1, n2, rn, e, w, g, s;

@@ -65,2 +65,6 @@ var order = NodeMatrix.length,

var adjustSizes = options.adjustSizes;
var thetaSquared = options.barnesHutTheta * options.barnesHutTheta;
var outboundAttCompensation,

@@ -394,3 +398,3 @@ coefficient,

// We run the Barnes Hut test to see if we are at the right distance
distance = Math.sqrt(
distance = (
(Math.pow(NodeMatrix[n + NODE_X] - RegionMatrix[r + REGION_MASS_CENTER_X], 2)) +

@@ -400,4 +404,6 @@ (Math.pow(NodeMatrix[n + NODE_Y] - RegionMatrix[r + REGION_MASS_CENTER_Y], 2))

if (2 * RegionMatrix[r + REGION_SIZE] / distance < options.barnesHutTheta) {
s = RegionMatrix[r + REGION_SIZE];
if ((4 * s * s) / distance < thetaSquared) {
// We treat the region as a single body, and we repulse

@@ -408,3 +414,3 @@

if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -414,3 +420,3 @@ //-- Linear Anti-collision Repulsion

factor = coefficient * NodeMatrix[n + NODE_MASS] *
RegionMatrix[r + REGION_MASS] / distance / distance;
RegionMatrix[r + REGION_MASS] / distance;

@@ -422,3 +428,3 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

factor = -coefficient * NodeMatrix[n + NODE_MASS] *
RegionMatrix[r + REGION_MASS] / distance;
RegionMatrix[r + REGION_MASS] / Math.sqrt(distance);

@@ -434,3 +440,3 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

factor = coefficient * NodeMatrix[n + NODE_MASS] *
RegionMatrix[r + REGION_MASS] / distance / distance;
RegionMatrix[r + REGION_MASS] / distance;

@@ -443,7 +449,7 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

// When this is done, we iterate. We have to look at the next sibling.
if (RegionMatrix[r + REGION_NEXT_SIBLING] < 0)
r = RegionMatrix[r + REGION_NEXT_SIBLING];
if (r < 0)
break; // No next sibling: we have finished the tree
r = RegionMatrix[r + REGION_NEXT_SIBLING];
continue;
}

@@ -462,10 +468,11 @@ else {

// If there is a node r[0] and it is not n, then repulse
rn = RegionMatrix[r + REGION_NODE];
if (RegionMatrix[r + REGION_NODE] >= 0 && RegionMatrix[r + REGION_NODE] !== n) {
xDist = NodeMatrix[n + NODE_X] - NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_X];
yDist = NodeMatrix[n + NODE_Y] - NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y];
if (rn >= 0 && rn !== n) {
xDist = NodeMatrix[n + NODE_X] - NodeMatrix[rn + NODE_X];
yDist = NodeMatrix[n + NODE_Y] - NodeMatrix[rn + NODE_Y];
distance = Math.sqrt(xDist * xDist + yDist * yDist);
distance = xDist * xDist + yDist * yDist;
if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -475,3 +482,3 @@ //-- Linear Anti-collision Repulsion

factor = coefficient * NodeMatrix[n + NODE_MASS] *
NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance / distance;
NodeMatrix[rn + NODE_MASS] / distance;

@@ -483,3 +490,3 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

factor = -coefficient * NodeMatrix[n + NODE_MASS] *
NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance;
NodeMatrix[rn + NODE_MASS] / Math.sqrt(distance);

@@ -495,3 +502,3 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

factor = coefficient * NodeMatrix[n + NODE_MASS] *
NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance / distance;
NodeMatrix[rn + NODE_MASS] / distance;

@@ -506,5 +513,7 @@ NodeMatrix[n + NODE_DX] += xDist * factor;

// When this is done, we iterate. We have to look at the next sibling.
if (RegionMatrix[r + REGION_NEXT_SIBLING] < 0)
r = RegionMatrix[r + REGION_NEXT_SIBLING];
if (r < 0)
break; // No next sibling: we have finished the tree
r = RegionMatrix[r + REGION_NEXT_SIBLING];
continue;

@@ -526,3 +535,3 @@ }

if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -638,3 +647,3 @@ //-- Anticollision Linear Repulsion

// Applying attraction to nodes
if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -747,3 +756,3 @@ distance = Math.sqrt(

// MATH: sqrt and square distances
if (options.adjustSizes) {
if (adjustSizes === true) {

@@ -750,0 +759,0 @@ for (n = 0; n < order; n += PPN) {

{
"name": "graphology-layout-forceatlas2",
"version": "0.4.2",
"version": "0.4.3",
"description": "ForceAtlas 2 layout algorithm for graphology.",

@@ -46,5 +46,6 @@ "main": "index.js",

"eslint": "^6.8.0",
"graphology": "0.15.2",
"graphology": "0.17.1",
"graphology-generators": "^0.10.1",
"mocha": "^7.0.1",
"graphology-layout": "^0.2.0",
"mocha": "^7.1.1",
"seedrandom": "^3.0.5",

@@ -61,5 +62,5 @@ "webpack": "^3.6.0",

"dependencies": {
"graphology-types": "^0.15.3",
"graphology-utils": "^1.6.0"
"graphology-types": "^0.16.0",
"graphology-utils": "^1.7.0"
}
}

@@ -755,3 +755,3 @@ (function webpackUniversalModuleDefinition(root, factory) {

module.exports = function() {
return __webpack_require__(6)("/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/**\n * Graphology ForceAtlas2 Layout Webworker\n * ========================================\n *\n * Web worker able to run the layout in a separate thread.\n */\nvar iterate = __webpack_require__(1);\n\nvar NODES,\n EDGES;\n\nself.addEventListener('message', function(event) {\n var data = event.data;\n\n NODES = new Float32Array(data.nodes);\n\n if (data.edges)\n EDGES = new Float32Array(data.edges);\n\n // Running the iteration\n iterate(\n data.settings,\n NODES,\n EDGES\n );\n\n // Sending result to supervisor\n self.postMessage({\n nodes: NODES.buffer\n }, [NODES.buffer]);\n});\n\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\n/* eslint no-constant-condition: 0 */\n/**\n * Graphology ForceAtlas2 Iteration\n * =================================\n *\n * Function used to perform a single iteration of the algorithm.\n */\n\n/**\n * Matrices properties accessors.\n */\nvar NODE_X = 0,\n NODE_Y = 1,\n NODE_DX = 2,\n NODE_DY = 3,\n NODE_OLD_DX = 4,\n NODE_OLD_DY = 5,\n NODE_MASS = 6,\n NODE_CONVERGENCE = 7,\n NODE_SIZE = 8,\n NODE_FIXED = 9;\n\nvar EDGE_SOURCE = 0,\n EDGE_TARGET = 1,\n EDGE_WEIGHT = 2;\n\nvar REGION_NODE = 0,\n REGION_CENTER_X = 1,\n REGION_CENTER_Y = 2,\n REGION_SIZE = 3,\n REGION_NEXT_SIBLING = 4,\n REGION_FIRST_CHILD = 5,\n REGION_MASS = 6,\n REGION_MASS_CENTER_X = 7,\n REGION_MASS_CENTER_Y = 8;\n\nvar SUBDIVISION_ATTEMPTS = 3;\n\n/**\n * Constants.\n */\nvar PPN = 10,\n PPE = 3,\n PPR = 9;\n\nvar MAX_FORCE = 10;\n\n/**\n * Function used to perform a single interation of the algorithm.\n *\n * @param {object} options - Layout options.\n * @param {Float32Array} NodeMatrix - Node data.\n * @param {Float32Array} EdgeMatrix - Edge data.\n * @return {object} - Some metadata.\n */\nmodule.exports = function iterate(options, NodeMatrix, EdgeMatrix) {\n\n // Initializing variables\n var l, r, n, n1, n2, e, w, g;\n\n var order = NodeMatrix.length,\n size = EdgeMatrix.length;\n\n var outboundAttCompensation,\n coefficient,\n xDist,\n yDist,\n ewc,\n distance,\n factor;\n\n var RegionMatrix = [];\n\n // 1) Initializing layout data\n //-----------------------------\n\n // Resetting positions & computing max values\n for (n = 0; n < order; n += PPN) {\n NodeMatrix[n + NODE_OLD_DX] = NodeMatrix[n + NODE_DX];\n NodeMatrix[n + NODE_OLD_DY] = NodeMatrix[n + NODE_DY];\n NodeMatrix[n + NODE_DX] = 0;\n NodeMatrix[n + NODE_DY] = 0;\n }\n\n // If outbound attraction distribution, compensate\n if (options.outboundAttractionDistribution) {\n outboundAttCompensation = 0;\n for (n = 0; n < order; n += PPN) {\n outboundAttCompensation += NodeMatrix[n + NODE_MASS];\n }\n\n outboundAttCompensation /= (order / PPN);\n }\n\n\n // 1.bis) Barnes-Hut computation\n //------------------------------\n\n if (options.barnesHutOptimize) {\n\n // Setting up\n var minX = Infinity,\n maxX = -Infinity,\n minY = Infinity,\n maxY = -Infinity,\n q, q2, subdivisionAttempts;\n\n // Computing min and max values\n for (n = 0; n < order; n += PPN) {\n minX = Math.min(minX, NodeMatrix[n + NODE_X]);\n maxX = Math.max(maxX, NodeMatrix[n + NODE_X]);\n minY = Math.min(minY, NodeMatrix[n + NODE_Y]);\n maxY = Math.max(maxY, NodeMatrix[n + NODE_Y]);\n }\n\n // squarify bounds, it's a quadtree\n var dx = maxX - minX, dy = maxY - minY;\n if (dx > dy) {\n minY -= (dx - dy) / 2;\n maxY = minY + dx;\n }\n else {\n minX -= (dy - dx) / 2;\n maxX = minX + dy;\n }\n\n // Build the Barnes Hut root region\n RegionMatrix[0 + REGION_NODE] = -1;\n RegionMatrix[0 + REGION_CENTER_X] = (minX + maxX) / 2;\n RegionMatrix[0 + REGION_CENTER_Y] = (minY + maxY) / 2;\n RegionMatrix[0 + REGION_SIZE] = Math.max(maxX - minX, maxY - minY);\n RegionMatrix[0 + REGION_NEXT_SIBLING] = -1;\n RegionMatrix[0 + REGION_FIRST_CHILD] = -1;\n RegionMatrix[0 + REGION_MASS] = 0;\n RegionMatrix[0 + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[0 + REGION_MASS_CENTER_Y] = 0;\n\n // Add each node in the tree\n l = 1;\n for (n = 0; n < order; n += PPN) {\n\n // Current region, starting with root\n r = 0;\n subdivisionAttempts = SUBDIVISION_ATTEMPTS;\n\n while (true) {\n // Are there sub-regions?\n\n // We look at first child index\n if (RegionMatrix[r + REGION_FIRST_CHILD] >= 0) {\n\n // There are sub-regions\n\n // We just iterate to find a \"leaf\" of the tree\n // that is an empty region or a region with a single node\n // (see next case)\n\n // Find the quadrant of n\n if (NodeMatrix[n + NODE_X] < RegionMatrix[r + REGION_CENTER_X]) {\n\n if (NodeMatrix[n + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Left quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD];\n }\n else {\n\n // Bottom Left quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR;\n }\n }\n else {\n if (NodeMatrix[n + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Right quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 2;\n }\n else {\n\n // Bottom Right quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 3;\n }\n }\n\n // Update center of mass and mass (we only do it for non-leave regions)\n RegionMatrix[r + REGION_MASS_CENTER_X] =\n (RegionMatrix[r + REGION_MASS_CENTER_X] * RegionMatrix[r + REGION_MASS] +\n NodeMatrix[n + NODE_X] * NodeMatrix[n + NODE_MASS]) /\n (RegionMatrix[r + REGION_MASS] + NodeMatrix[n + NODE_MASS]);\n\n RegionMatrix[r + REGION_MASS_CENTER_Y] =\n (RegionMatrix[r + REGION_MASS_CENTER_Y] * RegionMatrix[r + REGION_MASS] +\n NodeMatrix[n + NODE_Y] * NodeMatrix[n + NODE_MASS]) /\n (RegionMatrix[r + REGION_MASS] + NodeMatrix[n + NODE_MASS]);\n\n RegionMatrix[r + REGION_MASS] += NodeMatrix[n + NODE_MASS];\n\n // Iterate on the right quadrant\n r = q;\n continue;\n }\n else {\n\n // There are no sub-regions: we are in a \"leaf\"\n\n // Is there a node in this leave?\n if (RegionMatrix[r + REGION_NODE] < 0) {\n\n // There is no node in region:\n // we record node n and go on\n RegionMatrix[r + REGION_NODE] = n;\n break;\n }\n else {\n\n // There is a node in this region\n\n // We will need to create sub-regions, stick the two\n // nodes (the old one r[0] and the new one n) in two\n // subregions. If they fall in the same quadrant,\n // we will iterate.\n\n // Create sub-regions\n RegionMatrix[r + REGION_FIRST_CHILD] = l * PPR;\n w = RegionMatrix[r + REGION_SIZE] / 2; // new size (half)\n\n // NOTE: we use screen coordinates\n // from Top Left to Bottom Right\n\n // Top Left sub-region\n g = RegionMatrix[r + REGION_FIRST_CHILD];\n\n RegionMatrix[g + REGION_NODE] = -1;\n RegionMatrix[g + REGION_CENTER_X] = RegionMatrix[r + REGION_CENTER_X] - w;\n RegionMatrix[g + REGION_CENTER_Y] = RegionMatrix[r + REGION_CENTER_Y] - w;\n RegionMatrix[g + REGION_SIZE] = w;\n RegionMatrix[g + REGION_NEXT_SIBLING] = g + PPR;\n RegionMatrix[g + REGION_FIRST_CHILD] = -1;\n RegionMatrix[g + REGION_MASS] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_Y] = 0;\n\n // Bottom Left sub-region\n g += PPR;\n RegionMatrix[g + REGION_NODE] = -1;\n RegionMatrix[g + REGION_CENTER_X] = RegionMatrix[r + REGION_CENTER_X] - w;\n RegionMatrix[g + REGION_CENTER_Y] = RegionMatrix[r + REGION_CENTER_Y] + w;\n RegionMatrix[g + REGION_SIZE] = w;\n RegionMatrix[g + REGION_NEXT_SIBLING] = g + PPR;\n RegionMatrix[g + REGION_FIRST_CHILD] = -1;\n RegionMatrix[g + REGION_MASS] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_Y] = 0;\n\n // Top Right sub-region\n g += PPR;\n RegionMatrix[g + REGION_NODE] = -1;\n RegionMatrix[g + REGION_CENTER_X] = RegionMatrix[r + REGION_CENTER_X] + w;\n RegionMatrix[g + REGION_CENTER_Y] = RegionMatrix[r + REGION_CENTER_Y] - w;\n RegionMatrix[g + REGION_SIZE] = w;\n RegionMatrix[g + REGION_NEXT_SIBLING] = g + PPR;\n RegionMatrix[g + REGION_FIRST_CHILD] = -1;\n RegionMatrix[g + REGION_MASS] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_Y] = 0;\n\n // Bottom Right sub-region\n g += PPR;\n RegionMatrix[g + REGION_NODE] = -1;\n RegionMatrix[g + REGION_CENTER_X] = RegionMatrix[r + REGION_CENTER_X] + w;\n RegionMatrix[g + REGION_CENTER_Y] = RegionMatrix[r + REGION_CENTER_Y] + w;\n RegionMatrix[g + REGION_SIZE] = w;\n RegionMatrix[g + REGION_NEXT_SIBLING] = RegionMatrix[r + REGION_NEXT_SIBLING];\n RegionMatrix[g + REGION_FIRST_CHILD] = -1;\n RegionMatrix[g + REGION_MASS] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_Y] = 0;\n\n l += 4;\n\n // Now the goal is to find two different sub-regions\n // for the two nodes: the one previously recorded (r[0])\n // and the one we want to add (n)\n\n // Find the quadrant of the old node\n if (NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_X] < RegionMatrix[r + REGION_CENTER_X]) {\n if (NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Left quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD];\n }\n else {\n\n // Bottom Left quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR;\n }\n }\n else {\n if (NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Right quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 2;\n }\n else {\n\n // Bottom Right quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 3;\n }\n }\n\n // We remove r[0] from the region r, add its mass to r and record it in q\n RegionMatrix[r + REGION_MASS] = NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS];\n RegionMatrix[r + REGION_MASS_CENTER_X] = NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_X];\n RegionMatrix[r + REGION_MASS_CENTER_Y] = NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y];\n\n RegionMatrix[q + REGION_NODE] = RegionMatrix[r + REGION_NODE];\n RegionMatrix[r + REGION_NODE] = -1;\n\n // Find the quadrant of n\n if (NodeMatrix[n + NODE_X] < RegionMatrix[r + REGION_CENTER_X]) {\n if (NodeMatrix[n + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Left quarter\n q2 = RegionMatrix[r + REGION_FIRST_CHILD];\n }\n else {\n // Bottom Left quarter\n q2 = RegionMatrix[r + REGION_FIRST_CHILD] + PPR;\n }\n }\n else {\n if (NodeMatrix[n + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Right quarter\n q2 = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 2;\n }\n else {\n\n // Bottom Right quarter\n q2 = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 3;\n }\n }\n\n if (q === q2) {\n\n // If both nodes are in the same quadrant,\n // we have to try it again on this quadrant\n if (subdivisionAttempts--) {\n r = q;\n continue; // while\n }\n else {\n // we are out of precision here, and we cannot subdivide anymore\n // but we have to break the loop anyway\n subdivisionAttempts = SUBDIVISION_ATTEMPTS;\n break; // while\n }\n\n }\n\n // If both quadrants are different, we record n\n // in its quadrant\n RegionMatrix[q2 + REGION_NODE] = n;\n break;\n }\n }\n }\n }\n }\n\n\n // 2) Repulsion\n //--------------\n // NOTES: adjustSizes = antiCollision & scalingRatio = coefficient\n\n if (options.barnesHutOptimize) {\n coefficient = options.scalingRatio;\n\n // Applying repulsion through regions\n for (n = 0; n < order; n += PPN) {\n\n // Computing leaf quad nodes iteration\n\n r = 0; // Starting with root region\n while (true) {\n\n if (RegionMatrix[r + REGION_FIRST_CHILD] >= 0) {\n\n // The region has sub-regions\n\n // We run the Barnes Hut test to see if we are at the right distance\n distance = Math.sqrt(\n (Math.pow(NodeMatrix[n + NODE_X] - RegionMatrix[r + REGION_MASS_CENTER_X], 2)) +\n (Math.pow(NodeMatrix[n + NODE_Y] - RegionMatrix[r + REGION_MASS_CENTER_Y], 2))\n );\n\n if (2 * RegionMatrix[r + REGION_SIZE] / distance < options.barnesHutTheta) {\n\n // We treat the region as a single body, and we repulse\n\n xDist = NodeMatrix[n + NODE_X] - RegionMatrix[r + REGION_MASS_CENTER_X];\n yDist = NodeMatrix[n + NODE_Y] - RegionMatrix[r + REGION_MASS_CENTER_Y];\n\n if (options.adjustSizes) {\n\n //-- Linear Anti-collision Repulsion\n if (distance > 0) {\n factor = coefficient * NodeMatrix[n + NODE_MASS] *\n RegionMatrix[r + REGION_MASS] / distance / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n else if (distance < 0) {\n factor = -coefficient * NodeMatrix[n + NODE_MASS] *\n RegionMatrix[r + REGION_MASS] / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n }\n else {\n\n //-- Linear Repulsion\n if (distance > 0) {\n factor = coefficient * NodeMatrix[n + NODE_MASS] *\n RegionMatrix[r + REGION_MASS] / distance / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n }\n\n // When this is done, we iterate. We have to look at the next sibling.\n if (RegionMatrix[r + REGION_NEXT_SIBLING] < 0)\n break; // No next sibling: we have finished the tree\n r = RegionMatrix[r + REGION_NEXT_SIBLING];\n continue;\n\n }\n else {\n\n // The region is too close and we have to look at sub-regions\n r = RegionMatrix[r + REGION_FIRST_CHILD];\n continue;\n }\n\n }\n else {\n\n // The region has no sub-region\n // If there is a node r[0] and it is not n, then repulse\n\n if (RegionMatrix[r + REGION_NODE] >= 0 && RegionMatrix[r + REGION_NODE] !== n) {\n xDist = NodeMatrix[n + NODE_X] - NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_X];\n yDist = NodeMatrix[n + NODE_Y] - NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y];\n\n distance = Math.sqrt(xDist * xDist + yDist * yDist);\n\n if (options.adjustSizes) {\n\n //-- Linear Anti-collision Repulsion\n if (distance > 0) {\n factor = coefficient * NodeMatrix[n + NODE_MASS] *\n NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n else if (distance < 0) {\n factor = -coefficient * NodeMatrix[n + NODE_MASS] *\n NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n }\n else {\n\n //-- Linear Repulsion\n if (distance > 0) {\n factor = coefficient * NodeMatrix[n + NODE_MASS] *\n NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS] / distance / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n }\n\n }\n\n // When this is done, we iterate. We have to look at the next sibling.\n if (RegionMatrix[r + REGION_NEXT_SIBLING] < 0)\n break; // No next sibling: we have finished the tree\n r = RegionMatrix[r + REGION_NEXT_SIBLING];\n continue;\n }\n }\n }\n }\n else {\n coefficient = options.scalingRatio;\n\n // Square iteration\n for (n1 = 0; n1 < order; n1 += PPN) {\n for (n2 = 0; n2 < n1; n2 += PPN) {\n\n // Common to both methods\n xDist = NodeMatrix[n1 + NODE_X] - NodeMatrix[n2 + NODE_X];\n yDist = NodeMatrix[n1 + NODE_Y] - NodeMatrix[n2 + NODE_Y];\n\n if (options.adjustSizes) {\n\n //-- Anticollision Linear Repulsion\n distance = Math.sqrt(xDist * xDist + yDist * yDist) -\n NodeMatrix[n1 + NODE_SIZE] -\n NodeMatrix[n2 + NODE_SIZE];\n\n if (distance > 0) {\n factor = coefficient *\n NodeMatrix[n1 + NODE_MASS] *\n NodeMatrix[n2 + NODE_MASS] /\n distance / distance;\n\n // Updating nodes' dx and dy\n NodeMatrix[n1 + NODE_DX] += xDist * factor;\n NodeMatrix[n1 + NODE_DY] += yDist * factor;\n\n NodeMatrix[n2 + NODE_DX] += xDist * factor;\n NodeMatrix[n2 + NODE_DY] += yDist * factor;\n }\n else if (distance < 0) {\n factor = 100 * coefficient *\n NodeMatrix[n1 + NODE_MASS] *\n NodeMatrix[n2 + NODE_MASS];\n\n // Updating nodes' dx and dy\n NodeMatrix[n1 + NODE_DX] += xDist * factor;\n NodeMatrix[n1 + NODE_DY] += yDist * factor;\n\n NodeMatrix[n2 + NODE_DX] -= xDist * factor;\n NodeMatrix[n2 + NODE_DY] -= yDist * factor;\n }\n }\n else {\n\n //-- Linear Repulsion\n distance = Math.sqrt(xDist * xDist + yDist * yDist);\n\n if (distance > 0) {\n factor = coefficient *\n NodeMatrix[n1 + NODE_MASS] *\n NodeMatrix[n2 + NODE_MASS] /\n distance / distance;\n\n // Updating nodes' dx and dy\n NodeMatrix[n1 + NODE_DX] += xDist * factor;\n NodeMatrix[n1 + NODE_DY] += yDist * factor;\n\n NodeMatrix[n2 + NODE_DX] -= xDist * factor;\n NodeMatrix[n2 + NODE_DY] -= yDist * factor;\n }\n }\n }\n }\n }\n\n\n // 3) Gravity\n //------------\n g = options.gravity / options.scalingRatio;\n coefficient = options.scalingRatio;\n for (n = 0; n < order; n += PPN) {\n factor = 0;\n\n // Common to both methods\n xDist = NodeMatrix[n + NODE_X];\n yDist = NodeMatrix[n + NODE_Y];\n distance = Math.sqrt(\n Math.pow(xDist, 2) + Math.pow(yDist, 2)\n );\n\n if (options.strongGravityMode) {\n\n //-- Strong gravity\n if (distance > 0)\n factor = coefficient * NodeMatrix[n + NODE_MASS] * g;\n }\n else {\n\n //-- Linear Anti-collision Repulsion n\n if (distance > 0)\n factor = coefficient * NodeMatrix[n + NODE_MASS] * g / distance;\n }\n\n // Updating node's dx and dy\n NodeMatrix[n + NODE_DX] -= xDist * factor;\n NodeMatrix[n + NODE_DY] -= yDist * factor;\n }\n\n // 4) Attraction\n //---------------\n coefficient = 1 *\n (options.outboundAttractionDistribution ?\n outboundAttCompensation :\n 1);\n\n // TODO: simplify distance\n // TODO: coefficient is always used as -c --> optimize?\n for (e = 0; e < size; e += PPE) {\n n1 = EdgeMatrix[e + EDGE_SOURCE];\n n2 = EdgeMatrix[e + EDGE_TARGET];\n w = EdgeMatrix[e + EDGE_WEIGHT];\n\n // Edge weight influence\n ewc = Math.pow(w, options.edgeWeightInfluence);\n\n // Common measures\n xDist = NodeMatrix[n1 + NODE_X] - NodeMatrix[n2 + NODE_X];\n yDist = NodeMatrix[n1 + NODE_Y] - NodeMatrix[n2 + NODE_Y];\n\n // Applying attraction to nodes\n if (options.adjustSizes) {\n\n distance = Math.sqrt(\n (Math.pow(xDist, 2) + Math.pow(yDist, 2)) -\n NodeMatrix[n1 + NODE_SIZE] -\n NodeMatrix[n2 + NODE_SIZE]\n );\n\n if (options.linLogMode) {\n if (options.outboundAttractionDistribution) {\n\n //-- LinLog Degree Distributed Anti-collision Attraction\n if (distance > 0) {\n factor = -coefficient * ewc * Math.log(1 + distance) /\n distance /\n NodeMatrix[n1 + NODE_MASS];\n }\n }\n else {\n\n //-- LinLog Anti-collision Attraction\n if (distance > 0) {\n factor = -coefficient * ewc * Math.log(1 + distance) / distance;\n }\n }\n }\n else {\n if (options.outboundAttractionDistribution) {\n\n //-- Linear Degree Distributed Anti-collision Attraction\n if (distance > 0) {\n factor = -coefficient * ewc / NodeMatrix[n1 + NODE_MASS];\n }\n }\n else {\n\n //-- Linear Anti-collision Attraction\n if (distance > 0) {\n factor = -coefficient * ewc;\n }\n }\n }\n }\n else {\n\n distance = Math.sqrt(\n Math.pow(xDist, 2) + Math.pow(yDist, 2)\n );\n\n if (options.linLogMode) {\n if (options.outboundAttractionDistribution) {\n\n //-- LinLog Degree Distributed Attraction\n if (distance > 0) {\n factor = -coefficient * ewc * Math.log(1 + distance) /\n distance /\n NodeMatrix[n1 + NODE_MASS];\n }\n }\n else {\n\n //-- LinLog Attraction\n if (distance > 0)\n factor = -coefficient * ewc * Math.log(1 + distance) / distance;\n }\n }\n else {\n if (options.outboundAttractionDistribution) {\n\n //-- Linear Attraction Mass Distributed\n // NOTE: Distance is set to 1 to override next condition\n distance = 1;\n factor = -coefficient * ewc / NodeMatrix[n1 + NODE_MASS];\n }\n else {\n\n //-- Linear Attraction\n // NOTE: Distance is set to 1 to override next condition\n distance = 1;\n factor = -coefficient * ewc;\n }\n }\n }\n\n // Updating nodes' dx and dy\n // TODO: if condition or factor = 1?\n if (distance > 0) {\n\n // Updating nodes' dx and dy\n NodeMatrix[n1 + NODE_DX] += xDist * factor;\n NodeMatrix[n1 + NODE_DY] += yDist * factor;\n\n NodeMatrix[n2 + NODE_DX] -= xDist * factor;\n NodeMatrix[n2 + NODE_DY] -= yDist * factor;\n }\n }\n\n\n // 5) Apply Forces\n //-----------------\n var force,\n swinging,\n traction,\n nodespeed,\n newX,\n newY;\n\n // MATH: sqrt and square distances\n if (options.adjustSizes) {\n\n for (n = 0; n < order; n += PPN) {\n if (!NodeMatrix[n + NODE_FIXED]) {\n force = Math.sqrt(\n Math.pow(NodeMatrix[n + NODE_DX], 2) +\n Math.pow(NodeMatrix[n + NODE_DY], 2)\n );\n\n if (force > MAX_FORCE) {\n NodeMatrix[n + NODE_DX] =\n NodeMatrix[n + NODE_DX] * MAX_FORCE / force;\n NodeMatrix[n + NODE_DY] =\n NodeMatrix[n + NODE_DY] * MAX_FORCE / force;\n }\n\n swinging = NodeMatrix[n + NODE_MASS] *\n Math.sqrt(\n (NodeMatrix[n + NODE_OLD_DX] - NodeMatrix[n + NODE_DX]) *\n (NodeMatrix[n + NODE_OLD_DX] - NodeMatrix[n + NODE_DX]) +\n (NodeMatrix[n + NODE_OLD_DY] - NodeMatrix[n + NODE_DY]) *\n (NodeMatrix[n + NODE_OLD_DY] - NodeMatrix[n + NODE_DY])\n );\n\n traction = Math.sqrt(\n (NodeMatrix[n + NODE_OLD_DX] + NodeMatrix[n + NODE_DX]) *\n (NodeMatrix[n + NODE_OLD_DX] + NodeMatrix[n + NODE_DX]) +\n (NodeMatrix[n + NODE_OLD_DY] + NodeMatrix[n + NODE_DY]) *\n (NodeMatrix[n + NODE_OLD_DY] + NodeMatrix[n + NODE_DY])\n ) / 2;\n\n nodespeed =\n 0.1 * Math.log(1 + traction) / (1 + Math.sqrt(swinging));\n\n // Updating node's positon\n newX = NodeMatrix[n + NODE_X] + NodeMatrix[n + NODE_DX] *\n (nodespeed / options.slowDown);\n NodeMatrix[n + NODE_X] = newX;\n\n newY = NodeMatrix[n + NODE_Y] + NodeMatrix[n + NODE_DY] *\n (nodespeed / options.slowDown);\n NodeMatrix[n + NODE_Y] = newY;\n }\n }\n }\n else {\n\n for (n = 0; n < order; n += PPN) {\n if (!NodeMatrix[n + NODE_FIXED]) {\n\n swinging = NodeMatrix[n + NODE_MASS] *\n Math.sqrt(\n (NodeMatrix[n + NODE_OLD_DX] - NodeMatrix[n + NODE_DX]) *\n (NodeMatrix[n + NODE_OLD_DX] - NodeMatrix[n + NODE_DX]) +\n (NodeMatrix[n + NODE_OLD_DY] - NodeMatrix[n + NODE_DY]) *\n (NodeMatrix[n + NODE_OLD_DY] - NodeMatrix[n + NODE_DY])\n );\n\n traction = Math.sqrt(\n (NodeMatrix[n + NODE_OLD_DX] + NodeMatrix[n + NODE_DX]) *\n (NodeMatrix[n + NODE_OLD_DX] + NodeMatrix[n + NODE_DX]) +\n (NodeMatrix[n + NODE_OLD_DY] + NodeMatrix[n + NODE_DY]) *\n (NodeMatrix[n + NODE_OLD_DY] + NodeMatrix[n + NODE_DY])\n ) / 2;\n\n nodespeed = NodeMatrix[n + NODE_CONVERGENCE] *\n Math.log(1 + traction) / (1 + Math.sqrt(swinging));\n\n // Updating node convergence\n NodeMatrix[n + NODE_CONVERGENCE] =\n Math.min(1, Math.sqrt(\n nodespeed *\n (Math.pow(NodeMatrix[n + NODE_DX], 2) +\n Math.pow(NodeMatrix[n + NODE_DY], 2)) /\n (1 + Math.sqrt(swinging))\n ));\n\n // Updating node's positon\n newX = NodeMatrix[n + NODE_X] + NodeMatrix[n + NODE_DX] *\n (nodespeed / options.slowDown);\n NodeMatrix[n + NODE_X] = newX;\n\n newY = NodeMatrix[n + NODE_Y] + NodeMatrix[n + NODE_DY] *\n (nodespeed / options.slowDown);\n NodeMatrix[n + NODE_Y] = newY;\n }\n }\n }\n\n // We return the information about the layout (no need to return the matrices)\n return {};\n};\n\n\n/***/ })\n/******/ ]);", null);
return __webpack_require__(6)("/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/**\n * Graphology ForceAtlas2 Layout Webworker\n * ========================================\n *\n * Web worker able to run the layout in a separate thread.\n */\nvar iterate = __webpack_require__(1);\n\nvar NODES,\n EDGES;\n\nself.addEventListener('message', function(event) {\n var data = event.data;\n\n NODES = new Float32Array(data.nodes);\n\n if (data.edges)\n EDGES = new Float32Array(data.edges);\n\n // Running the iteration\n iterate(\n data.settings,\n NODES,\n EDGES\n );\n\n // Sending result to supervisor\n self.postMessage({\n nodes: NODES.buffer\n }, [NODES.buffer]);\n});\n\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\n/* eslint no-constant-condition: 0 */\n/**\n * Graphology ForceAtlas2 Iteration\n * =================================\n *\n * Function used to perform a single iteration of the algorithm.\n */\n\n/**\n * Matrices properties accessors.\n */\nvar NODE_X = 0,\n NODE_Y = 1,\n NODE_DX = 2,\n NODE_DY = 3,\n NODE_OLD_DX = 4,\n NODE_OLD_DY = 5,\n NODE_MASS = 6,\n NODE_CONVERGENCE = 7,\n NODE_SIZE = 8,\n NODE_FIXED = 9;\n\nvar EDGE_SOURCE = 0,\n EDGE_TARGET = 1,\n EDGE_WEIGHT = 2;\n\nvar REGION_NODE = 0,\n REGION_CENTER_X = 1,\n REGION_CENTER_Y = 2,\n REGION_SIZE = 3,\n REGION_NEXT_SIBLING = 4,\n REGION_FIRST_CHILD = 5,\n REGION_MASS = 6,\n REGION_MASS_CENTER_X = 7,\n REGION_MASS_CENTER_Y = 8;\n\nvar SUBDIVISION_ATTEMPTS = 3;\n\n/**\n * Constants.\n */\nvar PPN = 10,\n PPE = 3,\n PPR = 9;\n\nvar MAX_FORCE = 10;\n\n/**\n * Function used to perform a single interation of the algorithm.\n *\n * @param {object} options - Layout options.\n * @param {Float32Array} NodeMatrix - Node data.\n * @param {Float32Array} EdgeMatrix - Edge data.\n * @return {object} - Some metadata.\n */\nmodule.exports = function iterate(options, NodeMatrix, EdgeMatrix) {\n\n // Initializing variables\n var l, r, n, n1, n2, rn, e, w, g, s;\n\n var order = NodeMatrix.length,\n size = EdgeMatrix.length;\n\n var adjustSizes = options.adjustSizes;\n\n var thetaSquared = options.barnesHutTheta * options.barnesHutTheta;\n\n var outboundAttCompensation,\n coefficient,\n xDist,\n yDist,\n ewc,\n distance,\n factor;\n\n var RegionMatrix = [];\n\n // 1) Initializing layout data\n //-----------------------------\n\n // Resetting positions & computing max values\n for (n = 0; n < order; n += PPN) {\n NodeMatrix[n + NODE_OLD_DX] = NodeMatrix[n + NODE_DX];\n NodeMatrix[n + NODE_OLD_DY] = NodeMatrix[n + NODE_DY];\n NodeMatrix[n + NODE_DX] = 0;\n NodeMatrix[n + NODE_DY] = 0;\n }\n\n // If outbound attraction distribution, compensate\n if (options.outboundAttractionDistribution) {\n outboundAttCompensation = 0;\n for (n = 0; n < order; n += PPN) {\n outboundAttCompensation += NodeMatrix[n + NODE_MASS];\n }\n\n outboundAttCompensation /= (order / PPN);\n }\n\n\n // 1.bis) Barnes-Hut computation\n //------------------------------\n\n if (options.barnesHutOptimize) {\n\n // Setting up\n var minX = Infinity,\n maxX = -Infinity,\n minY = Infinity,\n maxY = -Infinity,\n q, q2, subdivisionAttempts;\n\n // Computing min and max values\n for (n = 0; n < order; n += PPN) {\n minX = Math.min(minX, NodeMatrix[n + NODE_X]);\n maxX = Math.max(maxX, NodeMatrix[n + NODE_X]);\n minY = Math.min(minY, NodeMatrix[n + NODE_Y]);\n maxY = Math.max(maxY, NodeMatrix[n + NODE_Y]);\n }\n\n // squarify bounds, it's a quadtree\n var dx = maxX - minX, dy = maxY - minY;\n if (dx > dy) {\n minY -= (dx - dy) / 2;\n maxY = minY + dx;\n }\n else {\n minX -= (dy - dx) / 2;\n maxX = minX + dy;\n }\n\n // Build the Barnes Hut root region\n RegionMatrix[0 + REGION_NODE] = -1;\n RegionMatrix[0 + REGION_CENTER_X] = (minX + maxX) / 2;\n RegionMatrix[0 + REGION_CENTER_Y] = (minY + maxY) / 2;\n RegionMatrix[0 + REGION_SIZE] = Math.max(maxX - minX, maxY - minY);\n RegionMatrix[0 + REGION_NEXT_SIBLING] = -1;\n RegionMatrix[0 + REGION_FIRST_CHILD] = -1;\n RegionMatrix[0 + REGION_MASS] = 0;\n RegionMatrix[0 + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[0 + REGION_MASS_CENTER_Y] = 0;\n\n // Add each node in the tree\n l = 1;\n for (n = 0; n < order; n += PPN) {\n\n // Current region, starting with root\n r = 0;\n subdivisionAttempts = SUBDIVISION_ATTEMPTS;\n\n while (true) {\n // Are there sub-regions?\n\n // We look at first child index\n if (RegionMatrix[r + REGION_FIRST_CHILD] >= 0) {\n\n // There are sub-regions\n\n // We just iterate to find a \"leaf\" of the tree\n // that is an empty region or a region with a single node\n // (see next case)\n\n // Find the quadrant of n\n if (NodeMatrix[n + NODE_X] < RegionMatrix[r + REGION_CENTER_X]) {\n\n if (NodeMatrix[n + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Left quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD];\n }\n else {\n\n // Bottom Left quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR;\n }\n }\n else {\n if (NodeMatrix[n + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Right quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 2;\n }\n else {\n\n // Bottom Right quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 3;\n }\n }\n\n // Update center of mass and mass (we only do it for non-leave regions)\n RegionMatrix[r + REGION_MASS_CENTER_X] =\n (RegionMatrix[r + REGION_MASS_CENTER_X] * RegionMatrix[r + REGION_MASS] +\n NodeMatrix[n + NODE_X] * NodeMatrix[n + NODE_MASS]) /\n (RegionMatrix[r + REGION_MASS] + NodeMatrix[n + NODE_MASS]);\n\n RegionMatrix[r + REGION_MASS_CENTER_Y] =\n (RegionMatrix[r + REGION_MASS_CENTER_Y] * RegionMatrix[r + REGION_MASS] +\n NodeMatrix[n + NODE_Y] * NodeMatrix[n + NODE_MASS]) /\n (RegionMatrix[r + REGION_MASS] + NodeMatrix[n + NODE_MASS]);\n\n RegionMatrix[r + REGION_MASS] += NodeMatrix[n + NODE_MASS];\n\n // Iterate on the right quadrant\n r = q;\n continue;\n }\n else {\n\n // There are no sub-regions: we are in a \"leaf\"\n\n // Is there a node in this leave?\n if (RegionMatrix[r + REGION_NODE] < 0) {\n\n // There is no node in region:\n // we record node n and go on\n RegionMatrix[r + REGION_NODE] = n;\n break;\n }\n else {\n\n // There is a node in this region\n\n // We will need to create sub-regions, stick the two\n // nodes (the old one r[0] and the new one n) in two\n // subregions. If they fall in the same quadrant,\n // we will iterate.\n\n // Create sub-regions\n RegionMatrix[r + REGION_FIRST_CHILD] = l * PPR;\n w = RegionMatrix[r + REGION_SIZE] / 2; // new size (half)\n\n // NOTE: we use screen coordinates\n // from Top Left to Bottom Right\n\n // Top Left sub-region\n g = RegionMatrix[r + REGION_FIRST_CHILD];\n\n RegionMatrix[g + REGION_NODE] = -1;\n RegionMatrix[g + REGION_CENTER_X] = RegionMatrix[r + REGION_CENTER_X] - w;\n RegionMatrix[g + REGION_CENTER_Y] = RegionMatrix[r + REGION_CENTER_Y] - w;\n RegionMatrix[g + REGION_SIZE] = w;\n RegionMatrix[g + REGION_NEXT_SIBLING] = g + PPR;\n RegionMatrix[g + REGION_FIRST_CHILD] = -1;\n RegionMatrix[g + REGION_MASS] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_Y] = 0;\n\n // Bottom Left sub-region\n g += PPR;\n RegionMatrix[g + REGION_NODE] = -1;\n RegionMatrix[g + REGION_CENTER_X] = RegionMatrix[r + REGION_CENTER_X] - w;\n RegionMatrix[g + REGION_CENTER_Y] = RegionMatrix[r + REGION_CENTER_Y] + w;\n RegionMatrix[g + REGION_SIZE] = w;\n RegionMatrix[g + REGION_NEXT_SIBLING] = g + PPR;\n RegionMatrix[g + REGION_FIRST_CHILD] = -1;\n RegionMatrix[g + REGION_MASS] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_Y] = 0;\n\n // Top Right sub-region\n g += PPR;\n RegionMatrix[g + REGION_NODE] = -1;\n RegionMatrix[g + REGION_CENTER_X] = RegionMatrix[r + REGION_CENTER_X] + w;\n RegionMatrix[g + REGION_CENTER_Y] = RegionMatrix[r + REGION_CENTER_Y] - w;\n RegionMatrix[g + REGION_SIZE] = w;\n RegionMatrix[g + REGION_NEXT_SIBLING] = g + PPR;\n RegionMatrix[g + REGION_FIRST_CHILD] = -1;\n RegionMatrix[g + REGION_MASS] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_Y] = 0;\n\n // Bottom Right sub-region\n g += PPR;\n RegionMatrix[g + REGION_NODE] = -1;\n RegionMatrix[g + REGION_CENTER_X] = RegionMatrix[r + REGION_CENTER_X] + w;\n RegionMatrix[g + REGION_CENTER_Y] = RegionMatrix[r + REGION_CENTER_Y] + w;\n RegionMatrix[g + REGION_SIZE] = w;\n RegionMatrix[g + REGION_NEXT_SIBLING] = RegionMatrix[r + REGION_NEXT_SIBLING];\n RegionMatrix[g + REGION_FIRST_CHILD] = -1;\n RegionMatrix[g + REGION_MASS] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_X] = 0;\n RegionMatrix[g + REGION_MASS_CENTER_Y] = 0;\n\n l += 4;\n\n // Now the goal is to find two different sub-regions\n // for the two nodes: the one previously recorded (r[0])\n // and the one we want to add (n)\n\n // Find the quadrant of the old node\n if (NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_X] < RegionMatrix[r + REGION_CENTER_X]) {\n if (NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Left quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD];\n }\n else {\n\n // Bottom Left quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR;\n }\n }\n else {\n if (NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Right quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 2;\n }\n else {\n\n // Bottom Right quarter\n q = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 3;\n }\n }\n\n // We remove r[0] from the region r, add its mass to r and record it in q\n RegionMatrix[r + REGION_MASS] = NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_MASS];\n RegionMatrix[r + REGION_MASS_CENTER_X] = NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_X];\n RegionMatrix[r + REGION_MASS_CENTER_Y] = NodeMatrix[RegionMatrix[r + REGION_NODE] + NODE_Y];\n\n RegionMatrix[q + REGION_NODE] = RegionMatrix[r + REGION_NODE];\n RegionMatrix[r + REGION_NODE] = -1;\n\n // Find the quadrant of n\n if (NodeMatrix[n + NODE_X] < RegionMatrix[r + REGION_CENTER_X]) {\n if (NodeMatrix[n + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Left quarter\n q2 = RegionMatrix[r + REGION_FIRST_CHILD];\n }\n else {\n // Bottom Left quarter\n q2 = RegionMatrix[r + REGION_FIRST_CHILD] + PPR;\n }\n }\n else {\n if (NodeMatrix[n + NODE_Y] < RegionMatrix[r + REGION_CENTER_Y]) {\n\n // Top Right quarter\n q2 = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 2;\n }\n else {\n\n // Bottom Right quarter\n q2 = RegionMatrix[r + REGION_FIRST_CHILD] + PPR * 3;\n }\n }\n\n if (q === q2) {\n\n // If both nodes are in the same quadrant,\n // we have to try it again on this quadrant\n if (subdivisionAttempts--) {\n r = q;\n continue; // while\n }\n else {\n // we are out of precision here, and we cannot subdivide anymore\n // but we have to break the loop anyway\n subdivisionAttempts = SUBDIVISION_ATTEMPTS;\n break; // while\n }\n\n }\n\n // If both quadrants are different, we record n\n // in its quadrant\n RegionMatrix[q2 + REGION_NODE] = n;\n break;\n }\n }\n }\n }\n }\n\n\n // 2) Repulsion\n //--------------\n // NOTES: adjustSizes = antiCollision & scalingRatio = coefficient\n\n if (options.barnesHutOptimize) {\n coefficient = options.scalingRatio;\n\n // Applying repulsion through regions\n for (n = 0; n < order; n += PPN) {\n\n // Computing leaf quad nodes iteration\n\n r = 0; // Starting with root region\n while (true) {\n\n if (RegionMatrix[r + REGION_FIRST_CHILD] >= 0) {\n\n // The region has sub-regions\n\n // We run the Barnes Hut test to see if we are at the right distance\n distance = (\n (Math.pow(NodeMatrix[n + NODE_X] - RegionMatrix[r + REGION_MASS_CENTER_X], 2)) +\n (Math.pow(NodeMatrix[n + NODE_Y] - RegionMatrix[r + REGION_MASS_CENTER_Y], 2))\n );\n\n s = RegionMatrix[r + REGION_SIZE];\n\n if ((4 * s * s) / distance < thetaSquared) {\n\n // We treat the region as a single body, and we repulse\n\n xDist = NodeMatrix[n + NODE_X] - RegionMatrix[r + REGION_MASS_CENTER_X];\n yDist = NodeMatrix[n + NODE_Y] - RegionMatrix[r + REGION_MASS_CENTER_Y];\n\n if (adjustSizes === true) {\n\n //-- Linear Anti-collision Repulsion\n if (distance > 0) {\n factor = coefficient * NodeMatrix[n + NODE_MASS] *\n RegionMatrix[r + REGION_MASS] / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n else if (distance < 0) {\n factor = -coefficient * NodeMatrix[n + NODE_MASS] *\n RegionMatrix[r + REGION_MASS] / Math.sqrt(distance);\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n }\n else {\n\n //-- Linear Repulsion\n if (distance > 0) {\n factor = coefficient * NodeMatrix[n + NODE_MASS] *\n RegionMatrix[r + REGION_MASS] / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n }\n\n // When this is done, we iterate. We have to look at the next sibling.\n r = RegionMatrix[r + REGION_NEXT_SIBLING];\n if (r < 0)\n break; // No next sibling: we have finished the tree\n\n continue;\n }\n else {\n\n // The region is too close and we have to look at sub-regions\n r = RegionMatrix[r + REGION_FIRST_CHILD];\n continue;\n }\n\n }\n else {\n\n // The region has no sub-region\n // If there is a node r[0] and it is not n, then repulse\n rn = RegionMatrix[r + REGION_NODE];\n\n if (rn >= 0 && rn !== n) {\n xDist = NodeMatrix[n + NODE_X] - NodeMatrix[rn + NODE_X];\n yDist = NodeMatrix[n + NODE_Y] - NodeMatrix[rn + NODE_Y];\n\n distance = xDist * xDist + yDist * yDist;\n\n if (adjustSizes === true) {\n\n //-- Linear Anti-collision Repulsion\n if (distance > 0) {\n factor = coefficient * NodeMatrix[n + NODE_MASS] *\n NodeMatrix[rn + NODE_MASS] / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n else if (distance < 0) {\n factor = -coefficient * NodeMatrix[n + NODE_MASS] *\n NodeMatrix[rn + NODE_MASS] / Math.sqrt(distance);\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n }\n else {\n\n //-- Linear Repulsion\n if (distance > 0) {\n factor = coefficient * NodeMatrix[n + NODE_MASS] *\n NodeMatrix[rn + NODE_MASS] / distance;\n\n NodeMatrix[n + NODE_DX] += xDist * factor;\n NodeMatrix[n + NODE_DY] += yDist * factor;\n }\n }\n\n }\n\n // When this is done, we iterate. We have to look at the next sibling.\n r = RegionMatrix[r + REGION_NEXT_SIBLING];\n\n if (r < 0)\n break; // No next sibling: we have finished the tree\n\n continue;\n }\n }\n }\n }\n else {\n coefficient = options.scalingRatio;\n\n // Square iteration\n for (n1 = 0; n1 < order; n1 += PPN) {\n for (n2 = 0; n2 < n1; n2 += PPN) {\n\n // Common to both methods\n xDist = NodeMatrix[n1 + NODE_X] - NodeMatrix[n2 + NODE_X];\n yDist = NodeMatrix[n1 + NODE_Y] - NodeMatrix[n2 + NODE_Y];\n\n if (adjustSizes === true) {\n\n //-- Anticollision Linear Repulsion\n distance = Math.sqrt(xDist * xDist + yDist * yDist) -\n NodeMatrix[n1 + NODE_SIZE] -\n NodeMatrix[n2 + NODE_SIZE];\n\n if (distance > 0) {\n factor = coefficient *\n NodeMatrix[n1 + NODE_MASS] *\n NodeMatrix[n2 + NODE_MASS] /\n distance / distance;\n\n // Updating nodes' dx and dy\n NodeMatrix[n1 + NODE_DX] += xDist * factor;\n NodeMatrix[n1 + NODE_DY] += yDist * factor;\n\n NodeMatrix[n2 + NODE_DX] += xDist * factor;\n NodeMatrix[n2 + NODE_DY] += yDist * factor;\n }\n else if (distance < 0) {\n factor = 100 * coefficient *\n NodeMatrix[n1 + NODE_MASS] *\n NodeMatrix[n2 + NODE_MASS];\n\n // Updating nodes' dx and dy\n NodeMatrix[n1 + NODE_DX] += xDist * factor;\n NodeMatrix[n1 + NODE_DY] += yDist * factor;\n\n NodeMatrix[n2 + NODE_DX] -= xDist * factor;\n NodeMatrix[n2 + NODE_DY] -= yDist * factor;\n }\n }\n else {\n\n //-- Linear Repulsion\n distance = Math.sqrt(xDist * xDist + yDist * yDist);\n\n if (distance > 0) {\n factor = coefficient *\n NodeMatrix[n1 + NODE_MASS] *\n NodeMatrix[n2 + NODE_MASS] /\n distance / distance;\n\n // Updating nodes' dx and dy\n NodeMatrix[n1 + NODE_DX] += xDist * factor;\n NodeMatrix[n1 + NODE_DY] += yDist * factor;\n\n NodeMatrix[n2 + NODE_DX] -= xDist * factor;\n NodeMatrix[n2 + NODE_DY] -= yDist * factor;\n }\n }\n }\n }\n }\n\n\n // 3) Gravity\n //------------\n g = options.gravity / options.scalingRatio;\n coefficient = options.scalingRatio;\n for (n = 0; n < order; n += PPN) {\n factor = 0;\n\n // Common to both methods\n xDist = NodeMatrix[n + NODE_X];\n yDist = NodeMatrix[n + NODE_Y];\n distance = Math.sqrt(\n Math.pow(xDist, 2) + Math.pow(yDist, 2)\n );\n\n if (options.strongGravityMode) {\n\n //-- Strong gravity\n if (distance > 0)\n factor = coefficient * NodeMatrix[n + NODE_MASS] * g;\n }\n else {\n\n //-- Linear Anti-collision Repulsion n\n if (distance > 0)\n factor = coefficient * NodeMatrix[n + NODE_MASS] * g / distance;\n }\n\n // Updating node's dx and dy\n NodeMatrix[n + NODE_DX] -= xDist * factor;\n NodeMatrix[n + NODE_DY] -= yDist * factor;\n }\n\n // 4) Attraction\n //---------------\n coefficient = 1 *\n (options.outboundAttractionDistribution ?\n outboundAttCompensation :\n 1);\n\n // TODO: simplify distance\n // TODO: coefficient is always used as -c --> optimize?\n for (e = 0; e < size; e += PPE) {\n n1 = EdgeMatrix[e + EDGE_SOURCE];\n n2 = EdgeMatrix[e + EDGE_TARGET];\n w = EdgeMatrix[e + EDGE_WEIGHT];\n\n // Edge weight influence\n ewc = Math.pow(w, options.edgeWeightInfluence);\n\n // Common measures\n xDist = NodeMatrix[n1 + NODE_X] - NodeMatrix[n2 + NODE_X];\n yDist = NodeMatrix[n1 + NODE_Y] - NodeMatrix[n2 + NODE_Y];\n\n // Applying attraction to nodes\n if (adjustSizes === true) {\n\n distance = Math.sqrt(\n (Math.pow(xDist, 2) + Math.pow(yDist, 2)) -\n NodeMatrix[n1 + NODE_SIZE] -\n NodeMatrix[n2 + NODE_SIZE]\n );\n\n if (options.linLogMode) {\n if (options.outboundAttractionDistribution) {\n\n //-- LinLog Degree Distributed Anti-collision Attraction\n if (distance > 0) {\n factor = -coefficient * ewc * Math.log(1 + distance) /\n distance /\n NodeMatrix[n1 + NODE_MASS];\n }\n }\n else {\n\n //-- LinLog Anti-collision Attraction\n if (distance > 0) {\n factor = -coefficient * ewc * Math.log(1 + distance) / distance;\n }\n }\n }\n else {\n if (options.outboundAttractionDistribution) {\n\n //-- Linear Degree Distributed Anti-collision Attraction\n if (distance > 0) {\n factor = -coefficient * ewc / NodeMatrix[n1 + NODE_MASS];\n }\n }\n else {\n\n //-- Linear Anti-collision Attraction\n if (distance > 0) {\n factor = -coefficient * ewc;\n }\n }\n }\n }\n else {\n\n distance = Math.sqrt(\n Math.pow(xDist, 2) + Math.pow(yDist, 2)\n );\n\n if (options.linLogMode) {\n if (options.outboundAttractionDistribution) {\n\n //-- LinLog Degree Distributed Attraction\n if (distance > 0) {\n factor = -coefficient * ewc * Math.log(1 + distance) /\n distance /\n NodeMatrix[n1 + NODE_MASS];\n }\n }\n else {\n\n //-- LinLog Attraction\n if (distance > 0)\n factor = -coefficient * ewc * Math.log(1 + distance) / distance;\n }\n }\n else {\n if (options.outboundAttractionDistribution) {\n\n //-- Linear Attraction Mass Distributed\n // NOTE: Distance is set to 1 to override next condition\n distance = 1;\n factor = -coefficient * ewc / NodeMatrix[n1 + NODE_MASS];\n }\n else {\n\n //-- Linear Attraction\n // NOTE: Distance is set to 1 to override next condition\n distance = 1;\n factor = -coefficient * ewc;\n }\n }\n }\n\n // Updating nodes' dx and dy\n // TODO: if condition or factor = 1?\n if (distance > 0) {\n\n // Updating nodes' dx and dy\n NodeMatrix[n1 + NODE_DX] += xDist * factor;\n NodeMatrix[n1 + NODE_DY] += yDist * factor;\n\n NodeMatrix[n2 + NODE_DX] -= xDist * factor;\n NodeMatrix[n2 + NODE_DY] -= yDist * factor;\n }\n }\n\n\n // 5) Apply Forces\n //-----------------\n var force,\n swinging,\n traction,\n nodespeed,\n newX,\n newY;\n\n // MATH: sqrt and square distances\n if (adjustSizes === true) {\n\n for (n = 0; n < order; n += PPN) {\n if (!NodeMatrix[n + NODE_FIXED]) {\n force = Math.sqrt(\n Math.pow(NodeMatrix[n + NODE_DX], 2) +\n Math.pow(NodeMatrix[n + NODE_DY], 2)\n );\n\n if (force > MAX_FORCE) {\n NodeMatrix[n + NODE_DX] =\n NodeMatrix[n + NODE_DX] * MAX_FORCE / force;\n NodeMatrix[n + NODE_DY] =\n NodeMatrix[n + NODE_DY] * MAX_FORCE / force;\n }\n\n swinging = NodeMatrix[n + NODE_MASS] *\n Math.sqrt(\n (NodeMatrix[n + NODE_OLD_DX] - NodeMatrix[n + NODE_DX]) *\n (NodeMatrix[n + NODE_OLD_DX] - NodeMatrix[n + NODE_DX]) +\n (NodeMatrix[n + NODE_OLD_DY] - NodeMatrix[n + NODE_DY]) *\n (NodeMatrix[n + NODE_OLD_DY] - NodeMatrix[n + NODE_DY])\n );\n\n traction = Math.sqrt(\n (NodeMatrix[n + NODE_OLD_DX] + NodeMatrix[n + NODE_DX]) *\n (NodeMatrix[n + NODE_OLD_DX] + NodeMatrix[n + NODE_DX]) +\n (NodeMatrix[n + NODE_OLD_DY] + NodeMatrix[n + NODE_DY]) *\n (NodeMatrix[n + NODE_OLD_DY] + NodeMatrix[n + NODE_DY])\n ) / 2;\n\n nodespeed =\n 0.1 * Math.log(1 + traction) / (1 + Math.sqrt(swinging));\n\n // Updating node's positon\n newX = NodeMatrix[n + NODE_X] + NodeMatrix[n + NODE_DX] *\n (nodespeed / options.slowDown);\n NodeMatrix[n + NODE_X] = newX;\n\n newY = NodeMatrix[n + NODE_Y] + NodeMatrix[n + NODE_DY] *\n (nodespeed / options.slowDown);\n NodeMatrix[n + NODE_Y] = newY;\n }\n }\n }\n else {\n\n for (n = 0; n < order; n += PPN) {\n if (!NodeMatrix[n + NODE_FIXED]) {\n\n swinging = NodeMatrix[n + NODE_MASS] *\n Math.sqrt(\n (NodeMatrix[n + NODE_OLD_DX] - NodeMatrix[n + NODE_DX]) *\n (NodeMatrix[n + NODE_OLD_DX] - NodeMatrix[n + NODE_DX]) +\n (NodeMatrix[n + NODE_OLD_DY] - NodeMatrix[n + NODE_DY]) *\n (NodeMatrix[n + NODE_OLD_DY] - NodeMatrix[n + NODE_DY])\n );\n\n traction = Math.sqrt(\n (NodeMatrix[n + NODE_OLD_DX] + NodeMatrix[n + NODE_DX]) *\n (NodeMatrix[n + NODE_OLD_DX] + NodeMatrix[n + NODE_DX]) +\n (NodeMatrix[n + NODE_OLD_DY] + NodeMatrix[n + NODE_DY]) *\n (NodeMatrix[n + NODE_OLD_DY] + NodeMatrix[n + NODE_DY])\n ) / 2;\n\n nodespeed = NodeMatrix[n + NODE_CONVERGENCE] *\n Math.log(1 + traction) / (1 + Math.sqrt(swinging));\n\n // Updating node convergence\n NodeMatrix[n + NODE_CONVERGENCE] =\n Math.min(1, Math.sqrt(\n nodespeed *\n (Math.pow(NodeMatrix[n + NODE_DX], 2) +\n Math.pow(NodeMatrix[n + NODE_DY], 2)) /\n (1 + Math.sqrt(swinging))\n ));\n\n // Updating node's positon\n newX = NodeMatrix[n + NODE_X] + NodeMatrix[n + NODE_DX] *\n (nodespeed / options.slowDown);\n NodeMatrix[n + NODE_X] = newX;\n\n newY = NodeMatrix[n + NODE_Y] + NodeMatrix[n + NODE_DY] *\n (nodespeed / options.slowDown);\n NodeMatrix[n + NODE_Y] = newY;\n }\n }\n }\n\n // We return the information about the layout (no need to return the matrices)\n return {};\n};\n\n\n/***/ })\n/******/ ]);", null);
};

@@ -758,0 +758,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc