Comparing version 0.2.2 to 0.3.0
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-quadtree'), require('d3-dispatch'), require('d3-collection'), require('d3-timer')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'd3-quadtree', 'd3-dispatch', 'd3-collection', 'd3-timer'], factory) : | ||
(factory((global.d3_force = global.d3_force || {}),global.d3_quadtree,global.d3_dispatch,global.d3_collection,global.d3_timer)); | ||
}(this, function (exports,d3Quadtree,d3Dispatch,d3Collection,d3Timer) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-quadtree'), require('d3-collection'), require('d3-dispatch'), require('d3-timer')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'd3-quadtree', 'd3-collection', 'd3-dispatch', 'd3-timer'], factory) : | ||
(factory((global.d3_force = global.d3_force || {}),global.d3_quadtree,global.d3_collection,global.d3_dispatch,global.d3_timer)); | ||
}(this, function (exports,d3Quadtree,d3Collection,d3Dispatch,d3Timer) { 'use strict'; | ||
var version = "0.2.2"; | ||
var version = "0.3.0"; | ||
@@ -53,111 +53,9 @@ function center(x, y) { | ||
function x(d) { | ||
return d.x; | ||
return d.x + d.vx; | ||
} | ||
function y(d) { | ||
return d.y; | ||
return d.y + d.vy; | ||
} | ||
var initialRadius = 10; | ||
var initialAngle = Math.PI * (3 - Math.sqrt(5)); | ||
function simulation(nodes) { | ||
var simulation, | ||
iteration = 0, | ||
alphaMin = 0.0001, | ||
alphaDecay = -0.02, | ||
drag = 0.5, | ||
forces = d3Collection.map(), | ||
stepper = d3Timer.timer(step), | ||
event = d3Dispatch.dispatch("tick", "end"); | ||
if (nodes == null) nodes = []; | ||
function start() { | ||
iteration = 0; | ||
stepper.restart(step); | ||
return simulation; | ||
} | ||
function stop() { | ||
stepper.stop(); | ||
return simulation; | ||
} | ||
function step() { | ||
var stop = tick(); | ||
event.call("tick", simulation); | ||
if (stop) { | ||
stepper.stop(); | ||
event.call("end", simulation); | ||
} | ||
} | ||
function tick() { | ||
var alpha = Math.exp(++iteration * alphaDecay); | ||
forces.each(function(force) { | ||
force(alpha); | ||
}); | ||
for (var i = 0, n = nodes.length, node; i < n; ++i) { | ||
node = nodes[i]; | ||
node.x += node.vx *= drag; | ||
node.y += node.vy *= drag; | ||
} | ||
return alpha < alphaMin; | ||
} | ||
function initializeNodes() { | ||
for (var i = 0, n = nodes.length, node; i < n; ++i) { | ||
node = nodes[i], node.index = i; | ||
if (isNaN(node.x) || isNaN(node.y)) { | ||
var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle; | ||
node.x = radius * Math.cos(angle); | ||
node.y = radius * Math.sin(angle); | ||
} | ||
if (isNaN(node.vx) || isNaN(node.vy)) { | ||
node.vx = node.vy = 0; | ||
} | ||
} | ||
} | ||
function initializeForce(force) { | ||
if (force.initialize) force.initialize(nodes); | ||
return force; | ||
} | ||
initializeNodes(); | ||
return simulation = { | ||
start: start, | ||
stop: stop, | ||
tick: tick, | ||
nodes: function(_) { | ||
return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes; | ||
}, | ||
alphaMin: function(_) { | ||
return arguments.length ? (alphaMin = _, simulation) : alphaMin; | ||
}, | ||
alphaDecay: function(_) { | ||
return arguments.length ? (iteration = +_ ? Math.round(iteration * alphaDecay / -_) : 0, alphaDecay = -_, simulation) : -alphaDecay; | ||
}, | ||
drag: function(_) { | ||
return arguments.length ? (drag = 1 - _, simulation) : 1 - drag; | ||
}, | ||
force: function(name, _) { | ||
return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name); | ||
}, | ||
on: function(name, _) { | ||
return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); | ||
} | ||
}; | ||
} | ||
function collide(radius) { | ||
@@ -167,3 +65,4 @@ var nodes, | ||
radiusMax, | ||
strength = 0.7; | ||
strength = 0.7, | ||
iterations = 1; | ||
@@ -176,17 +75,21 @@ if (typeof radius !== "function") radius = constant(radius == null ? 1 : +radius); | ||
node, | ||
nx, | ||
ny, | ||
nr, | ||
vx, | ||
vy, | ||
nx0, | ||
ny0, | ||
nx1, | ||
ny1, | ||
vx, | ||
vy, | ||
nr; | ||
ny1; | ||
for (i = 0; i < n; ++i) { | ||
node = nodes[i], nr = radii[i] + radiusMax, vx = vy = 0; | ||
nx0 = node.x - nr, ny0 = node.y - nr; | ||
nx1 = node.x + nr, ny1 = node.y + nr; | ||
tree.remove(node).visit(apply); | ||
node.x += vx * strength, node.y += vy * strength; | ||
tree.add(node); | ||
for (var k = 0; k < iterations; ++k) { | ||
for (i = 0; i < n; ++i) { | ||
node = nodes[i], nr = radii[i] + radiusMax, vx = vy = 0; | ||
nx = node.x + node.vx, nx0 = nx - nr, nx1 = nx + nr; | ||
ny = node.y + node.vy, ny0 = ny - nr, ny1 = ny + nr; | ||
tree.remove(node).visit(apply); | ||
node.vx += vx * strength, node.vy += vy * strength; | ||
tree.add(node); | ||
} | ||
} | ||
@@ -197,4 +100,4 @@ | ||
if (quad.length) return; | ||
var x = node.x - quad.data.x, | ||
y = node.y - quad.data.y, | ||
var x = nx - quad.data.x - quad.data.vx, | ||
y = ny - quad.data.y - quad.data.vy, | ||
l = x * x + y * y, | ||
@@ -220,2 +123,6 @@ r = radii[i] + radii[quad.data.index]; | ||
force.iterations = function(_) { | ||
return arguments.length ? (iterations = +_, force) : iterations; | ||
}; | ||
force.strength = function(_) { | ||
@@ -296,3 +203,3 @@ return arguments.length ? (strength = +_, force) : strength; | ||
var id = index, | ||
strength = constant(0.5), | ||
strength = constant(0.7), | ||
strengths, | ||
@@ -302,3 +209,4 @@ distance = constant(30), | ||
nodes, | ||
bias; | ||
bias, | ||
iterations = 1; | ||
@@ -308,13 +216,15 @@ if (links == null) links = []; | ||
function force(alpha) { | ||
for (var i = 0, n = links.length, link, source, target, x, y, l, b; i < n; ++i) { | ||
link = links[i], source = link.source, target = link.target; | ||
x = target.x - source.x; | ||
y = target.y - source.y; | ||
if (l = x * x + y * y) l = Math.sqrt(l), l = (l - distances[i]) / l; | ||
else l = Math.random() * tau, x = Math.cos(l), y = Math.sin(l), l = distances[i]; | ||
l *= alpha * strengths[i], x *= l, y *= l; | ||
target.vx -= x * (b = bias[i]); | ||
target.vy -= y * b; | ||
source.vx += x * (b = 1 - b); | ||
source.vy += y * b; | ||
for (var k = 0, n = links.length; k < iterations; ++k) { | ||
for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { | ||
link = links[i], source = link.source, target = link.target; | ||
x = target.x + target.vx - source.x - source.vx; | ||
y = target.y + target.vy - source.y - source.vy; | ||
if (l = x * x + y * y) l = Math.sqrt(l), l = (l - distances[i]) / l; | ||
else l = Math.random() * tau, x = Math.cos(l), y = Math.sin(l), l = distances[i]; | ||
l *= alpha * strengths[i], x *= l, y *= l; | ||
target.vx -= x * (b = bias[i]); | ||
target.vy -= y * b; | ||
source.vx += x * (b = 1 - b); | ||
source.vy += y * b; | ||
} | ||
} | ||
@@ -370,2 +280,6 @@ } | ||
force.iterations = function(_) { | ||
return arguments.length ? (iterations = +_, force) : iterations; | ||
}; | ||
force.strength = function(_) { | ||
@@ -382,2 +296,112 @@ return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), strengths = null, initialize(), force) : strength; | ||
function x$1(d) { | ||
return d.x; | ||
} | ||
function y$1(d) { | ||
return d.y; | ||
} | ||
var initialRadius = 10; | ||
var initialAngle = Math.PI * (3 - Math.sqrt(5)); | ||
function simulation(nodes) { | ||
var simulation, | ||
iteration = 0, | ||
alphaMin = 0.0001, | ||
alphaDecay = -0.02, | ||
drag = 0.6, | ||
forces = d3Collection.map(), | ||
stepper = d3Timer.timer(step), | ||
event = d3Dispatch.dispatch("tick", "end"); | ||
if (nodes == null) nodes = []; | ||
function restart() { | ||
iteration = 0; | ||
stepper.restart(step); | ||
return simulation; | ||
} | ||
function stop() { | ||
stepper.stop(); | ||
return simulation; | ||
} | ||
function step() { | ||
var stop = tick(); | ||
event.call("tick", simulation); | ||
if (stop) { | ||
stepper.stop(); | ||
event.call("end", simulation); | ||
} | ||
} | ||
function tick() { | ||
var alpha = Math.exp(++iteration * alphaDecay); | ||
forces.each(function(force) { | ||
force(alpha); | ||
}); | ||
for (var i = 0, n = nodes.length, node; i < n; ++i) { | ||
node = nodes[i]; | ||
node.x += node.vx *= drag; | ||
node.y += node.vy *= drag; | ||
} | ||
return alpha < alphaMin; | ||
} | ||
function initializeNodes() { | ||
for (var i = 0, n = nodes.length, node; i < n; ++i) { | ||
node = nodes[i], node.index = i; | ||
if (isNaN(node.x) || isNaN(node.y)) { | ||
var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle; | ||
node.x = radius * Math.cos(angle); | ||
node.y = radius * Math.sin(angle); | ||
} | ||
if (isNaN(node.vx) || isNaN(node.vy)) { | ||
node.vx = node.vy = 0; | ||
} | ||
} | ||
} | ||
function initializeForce(force) { | ||
if (force.initialize) force.initialize(nodes); | ||
return force; | ||
} | ||
initializeNodes(); | ||
return simulation = { | ||
restart: restart, | ||
stop: stop, | ||
tick: tick, | ||
nodes: function(_) { | ||
return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes; | ||
}, | ||
alphaMin: function(_) { | ||
return arguments.length ? (alphaMin = _, simulation) : alphaMin; | ||
}, | ||
alphaDecay: function(_) { | ||
return arguments.length ? (iteration = +_ ? Math.round(iteration * alphaDecay / -_) : 0, alphaDecay = -_, simulation) : -alphaDecay; | ||
}, | ||
drag: function(_) { | ||
return arguments.length ? (drag = 1 - _, simulation) : 1 - drag; | ||
}, | ||
force: function(name, _) { | ||
return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name); | ||
}, | ||
on: function(name, _) { | ||
return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); | ||
} | ||
}; | ||
} | ||
var tau$1 = 2 * Math.PI; | ||
@@ -396,3 +420,3 @@ | ||
function force(_) { | ||
var i, n = nodes.length, tree = d3Quadtree.quadtree(nodes, x, y).visitAfter(accumulate); | ||
var i, n = nodes.length, tree = d3Quadtree.quadtree(nodes, x$1, y$1).visitAfter(accumulate); | ||
for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); | ||
@@ -399,0 +423,0 @@ } |
@@ -1,1 +0,1 @@ | ||
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-quadtree"),require("d3-dispatch"),require("d3-collection"),require("d3-timer")):"function"==typeof define&&define.amd?define(["exports","d3-quadtree","d3-dispatch","d3-collection","d3-timer"],t):t(n.d3_force=n.d3_force||{},n.d3_quadtree,n.d3_dispatch,n.d3_collection,n.d3_timer)}(this,function(n,t,e,r,i){"use strict";function o(n,t){function e(){var e,i,o=r.length,u=0,f=0;for(e=0;o>e;++e)i=r[e],u+=i.x,f+=i.y;for(u=u/o-n,f=f/o-t,e=0;o>e;++e)i=r[e],i.x-=u,i.y-=f}var r;return null==n&&(n=0),null==t&&(t=0),e.initialize=function(n){r=n},e.x=function(t){return arguments.length?(n=+t,e):n},e.y=function(n){return arguments.length?(t=+n,e):t},e}function u(n){return function(){return n}}function f(n){return n.x}function a(n){return n.y}function c(n){function t(){return h=0,v.restart(u),l}function o(){return v.stop(),l}function u(){var n=f();M.call("tick",l),n&&(v.stop(),M.call("end",l))}function f(){var t=Math.exp(++h*d);g.each(function(n){n(t)});for(var e,r=0,i=n.length;i>r;++r)e=n[r],e.x+=e.vx*=s,e.y+=e.vy*=s;return y>t}function a(){for(var t,e=0,r=n.length;r>e;++e){if(t=n[e],t.index=e,isNaN(t.x)||isNaN(t.y)){var i=x*Math.sqrt(e),o=e*p;t.x=i*Math.cos(o),t.y=i*Math.sin(o)}(isNaN(t.vx)||isNaN(t.vy))&&(t.vx=t.vy=0)}}function c(t){return t.initialize&&t.initialize(n),t}var l,h=0,y=1e-4,d=-.02,s=.5,g=r.map(),v=i.timer(u),M=e.dispatch("tick","end");return null==n&&(n=[]),a(),l={start:t,stop:o,tick:f,nodes:function(t){return arguments.length?(n=t,a(),g.each(c),l):n},alphaMin:function(n){return arguments.length?(y=n,l):y},alphaDecay:function(n){return arguments.length?(h=+n?Math.round(h*d/-n):0,d=-n,l):-d},drag:function(n){return arguments.length?(s=1-n,l):1-s},force:function(n,t){return arguments.length>1?(null==t?g.remove(n):g.set(n,c(t)),l):g.get(n)},on:function(n,t){return arguments.length>1?(M.on(n,t),l):M.on(n)}}}function l(n){function e(){function n(n,t,r,o,f){if(t>y||l>o||r>d||h>f)return!0;if(!n.length){var a=u.x-n.data.x,c=u.y-n.data.y,v=a*a+c*c,x=i[e]+i[n.data.index];x*x>v&&(v=(x-(v=Math.sqrt(v)))/v,s+=a*v,g+=c*v)}}var e,u,l,h,y,d,s,g,v,x=r.length,p=t.quadtree(r,f,a);for(e=0;x>e;++e)u=r[e],v=i[e]+o,s=g=0,l=u.x-v,h=u.y-v,y=u.x+v,d=u.y+v,p.remove(u).visit(n),u.x+=s*c,u.y+=g*c,p.add(u)}var r,i,o,c=.7;return"function"!=typeof n&&(n=u(null==n?1:+n)),e.initialize=function(t){var e,u,f=(r=t).length;for(i=new Array(f),o=0,e=0;f>e;++e)(i[e]=u=+n(r[e],e,r))>o&&(o=u)},e.strength=function(n){return arguments.length?(c=+n,e):c},e.radius=function(t){return arguments.length?(n="function"==typeof t?t:u(+t),e):n},e}function h(n,t,e){function r(){for(var n,t,e,r,i,u=0,l=o.length;l>u;++u)n=o[u],t=n.x-a[u],e=n.y-c[u],(r=t*t+e*e)>(i=f[u])*i&&(r=Math.sqrt(r),r=(r-i)/r,n.vx-=t*r,n.vy-=e*r)}function i(){if(o){var r,i=o.length;for(f=new Array(i),a=new Array(i),c=new Array(i),r=0;i>r;++r)f[r]=+n(o[r],r,o),a[r]=+t(o[r],r,o),c[r]=+e(o[r],r,o)}}var o,f,a,c;return"function"!=typeof n&&(n=u(null==n?100:+n)),"function"!=typeof t&&(t=u(null==t?0:+t)),"function"!=typeof e&&(e=u(null==e?0:+e)),r.initialize=function(n){o=n,i()},r.radius=function(t){return arguments.length?(n="function"==typeof t?t:u(+t),i(),r):n},r.x=function(n){return arguments.length?(t="function"==typeof n?n:u(+n),i(),r):t},r.y=function(n){return arguments.length?(e="function"==typeof n?n:u(+n),i(),r):e},r}function y(n,t){return t}function d(n){function t(t){for(var e,r,u,f,c,l,h,y=0,d=n.length;d>y;++y)e=n[y],r=e.source,u=e.target,f=u.x-r.x,c=u.y-r.y,(l=f*f+c*c)?(l=Math.sqrt(l),l=(l-o[y])/l):(l=Math.random()*M,f=Math.cos(l),c=Math.sin(l),l=o[y]),l*=t*i[y],f*=l,c*=l,u.vx-=f*(h=a[y]),u.vy-=c*h,r.vx+=f*(h=1-h),r.vy+=c*h}function e(){if(f&&n){var t,e,u=f.length,y=n.length,d=new Array(u),s=r.map(f,c);for(t=0;u>t;++t)d[t]=0;for(t=0,a=new Array(y);y>t;++t)e=n[t],e.index=t,"object"!=typeof e.source&&(e.source=s.get(e.source)),"object"!=typeof e.target&&(e.target=s.get(e.target)),++d[e.source.index],++d[e.target.index];for(t=0;y>t;++t)e=n[t],a[t]=d[e.source.index]/(d[e.source.index]+d[e.target.index]);if(!i)for(t=0,i=new Array(y);y>t;++t)i[t]=+l(n[t]);if(!o)for(t=0,o=new Array(y);y>t;++t)o[t]=+h(n[t])}}var i,o,f,a,c=y,l=u(.5),h=u(30);return null==n&&(n=[]),t.initialize=function(n){f=n,e()},t.links=function(r){return arguments.length?(n=r,i=o=null,e(),t):n},t.id=function(n){return arguments.length?(c=n,e(),t):c},t.strength=function(n){return arguments.length?(l="function"==typeof n?n:u(+n),i=null,e(),t):l},t.distance=function(n){return arguments.length?(h="function"==typeof n?n:u(+n),o=null,e(),t):h},t}function s(){function n(n){var e,u=o.length,h=t.quadtree(o,f,a).visitAfter(r);for(l=n,e=0;u>e;++e)c=o[e],h.visit(i)}function e(){if(o){var n,t=o.length;for(h=new Array(t),n=0;t>n;++n)h[n]=+y(o[n],n,o)}}function r(n){var t,e,r,i,o,u=0;if(n.length){for(r=i=o=0;4>o;++o)(t=n[o])&&(e=t.value)&&(u+=e,r+=e*t.x,i+=e*t.y);n.x=r/u,n.y=i/u}else{t=n,t.x=t.data.x,t.y=t.data.y;do u+=h[t.data.index];while(t=t.next)}n.value=u}function i(n,t,e,r){if(!n.value)return!0;var i=n.x-c.x,o=n.y-c.y,u=r-t,f=i*i+o*o;if(f>u*u/g)return s>f&&(d>f&&(f=Math.sqrt(f/d),i/=f,o/=f,f=d),f=n.value*l/f,c.vx+=i*f,c.vy+=o*f),!0;if(!(n.length||f>=s)){d>f&&(f||(f=Math.random()*q,i=Math.cos(f),o=Math.sin(f),f=1),f=Math.sqrt(f/d),i/=f,o/=f,f=d);do n.data!==c&&(u=h[n.data.index]*l/f,c.vx+=i*u,c.vy+=o*u);while(n=n.next)}}var o,c,l,h,y=u(-100),d=1,s=1/0,g=.81;return n.initialize=function(n){o=n,e()},n.strength=function(t){return arguments.length?(y="function"==typeof t?t:u(+t),e(),n):y},n.distanceMin=function(t){return arguments.length?(d=t*t,n):Math.sqrt(d)},n.distanceMax=function(t){return arguments.length?(s=t*t,n):Math.sqrt(s)},n.theta=function(t){return arguments.length?(g=t*t,n):Math.sqrt(g)},n}function g(n,t){function e(n){for(var t,e,r=0,u=i.length;u>r;++r)t=i[r],e=o[r]*n,t.vx+=(f[r]-t.x)*e,t.vy+=(a[r]-t.y)*e}function r(){if(i){var e,r=i.length;for(o=new Array(r),f=new Array(r),a=new Array(r),e=0;r>e;++e)o[e]=+c(i[e],e,i),f[e]=+n(i[e],e,i),a[e]=+t(i[e],e,i)}}var i,o,f,a,c=u(.1);return"function"!=typeof n&&(n=u(null==n?0:+n)),"function"!=typeof t&&(t=u(null==t?0:+t)),e.initialize=function(n){i=n,r()},e.strength=function(n){return arguments.length?(c="function"==typeof n?n:u(+n),r(),e):c},e.x=function(t){return arguments.length?(n="function"==typeof t?t:u(+t),r(),e):n},e.y=function(n){return arguments.length?(t="function"==typeof n?n:u(+n),r(),e):t},e}var v="0.2.2",x=10,p=Math.PI*(3-Math.sqrt(5)),M=2*Math.PI,q=2*Math.PI;n.version=v,n.forceCenter=o,n.forceCollide=l,n.forceContain=h,n.forceLink=d,n.forceManyBody=s,n.forcePosition=g,n.forceSimulation=c}); | ||
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-quadtree"),require("d3-collection"),require("d3-dispatch"),require("d3-timer")):"function"==typeof define&&define.amd?define(["exports","d3-quadtree","d3-collection","d3-dispatch","d3-timer"],t):t(n.d3_force=n.d3_force||{},n.d3_quadtree,n.d3_collection,n.d3_dispatch,n.d3_timer)}(this,function(n,t,e,r,i){"use strict";function o(n,t){function e(){var e,i,o=r.length,u=0,f=0;for(e=0;o>e;++e)i=r[e],u+=i.x,f+=i.y;for(u=u/o-n,f=f/o-t,e=0;o>e;++e)i=r[e],i.x-=u,i.y-=f}var r;return null==n&&(n=0),null==t&&(t=0),e.initialize=function(n){r=n},e.x=function(t){return arguments.length?(n=+t,e):n},e.y=function(n){return arguments.length?(t=+n,e):t},e}function u(n){return function(){return n}}function f(n){return n.x+n.vx}function a(n){return n.y+n.vy}function c(n){function e(){function n(n,t,r,o,u){if(t>p||g>o||r>M||x>u)return!0;if(!n.length){var f=h-n.data.x-n.data.vx,a=y-n.data.y-n.data.vy,c=f*f+a*a,l=i[e]+i[n.data.index];l*l>c&&(c=(l-(c=Math.sqrt(c)))/c,v+=f*c,s+=a*c)}}for(var e,u,h,y,d,v,s,g,x,p,M,q=r.length,w=t.quadtree(r,f,a),m=0;l>m;++m)for(e=0;q>e;++e)u=r[e],d=i[e]+o,v=s=0,h=u.x+u.vx,g=h-d,p=h+d,y=u.y+u.vy,x=y-d,M=y+d,w.remove(u).visit(n),u.vx+=v*c,u.vy+=s*c,w.add(u)}var r,i,o,c=.7,l=1;return"function"!=typeof n&&(n=u(null==n?1:+n)),e.initialize=function(t){var e,u,f=(r=t).length;for(i=new Array(f),o=0,e=0;f>e;++e)(i[e]=u=+n(r[e],e,r))>o&&(o=u)},e.iterations=function(n){return arguments.length?(l=+n,e):l},e.strength=function(n){return arguments.length?(c=+n,e):c},e.radius=function(t){return arguments.length?(n="function"==typeof t?t:u(+t),e):n},e}function l(n,t,e){function r(){for(var n,t,e,r,i,u=0,l=o.length;l>u;++u)n=o[u],t=n.x-a[u],e=n.y-c[u],(r=t*t+e*e)>(i=f[u])*i&&(r=Math.sqrt(r),r=(r-i)/r,n.vx-=t*r,n.vy-=e*r)}function i(){if(o){var r,i=o.length;for(f=new Array(i),a=new Array(i),c=new Array(i),r=0;i>r;++r)f[r]=+n(o[r],r,o),a[r]=+t(o[r],r,o),c[r]=+e(o[r],r,o)}}var o,f,a,c;return"function"!=typeof n&&(n=u(null==n?100:+n)),"function"!=typeof t&&(t=u(null==t?0:+t)),"function"!=typeof e&&(e=u(null==e?0:+e)),r.initialize=function(n){o=n,i()},r.radius=function(t){return arguments.length?(n="function"==typeof t?t:u(+t),i(),r):n},r.x=function(n){return arguments.length?(t="function"==typeof n?n:u(+n),i(),r):t},r.y=function(n){return arguments.length?(e="function"==typeof n?n:u(+n),i(),r):e},r}function h(n,t){return t}function y(n){function t(t){for(var e=0,r=n.length;d>e;++e)for(var u,f,c,l,h,y,v,s=0;r>s;++s)u=n[s],f=u.source,c=u.target,l=c.x+c.vx-f.x-f.vx,h=c.y+c.vy-f.y-f.vy,(y=l*l+h*h)?(y=Math.sqrt(y),y=(y-o[s])/y):(y=Math.random()*M,l=Math.cos(y),h=Math.sin(y),y=o[s]),y*=t*i[s],l*=y,h*=y,c.vx-=l*(v=a[s]),c.vy-=h*v,f.vx+=l*(v=1-v),f.vy+=h*v}function r(){if(f&&n){var t,r,u=f.length,h=n.length,d=new Array(u),v=e.map(f,c);for(t=0;u>t;++t)d[t]=0;for(t=0,a=new Array(h);h>t;++t)r=n[t],r.index=t,"object"!=typeof r.source&&(r.source=v.get(r.source)),"object"!=typeof r.target&&(r.target=v.get(r.target)),++d[r.source.index],++d[r.target.index];for(t=0;h>t;++t)r=n[t],a[t]=d[r.source.index]/(d[r.source.index]+d[r.target.index]);if(!i)for(t=0,i=new Array(h);h>t;++t)i[t]=+l(n[t]);if(!o)for(t=0,o=new Array(h);h>t;++t)o[t]=+y(n[t])}}var i,o,f,a,c=h,l=u(.7),y=u(30),d=1;return null==n&&(n=[]),t.initialize=function(n){f=n,r()},t.links=function(e){return arguments.length?(n=e,i=o=null,r(),t):n},t.id=function(n){return arguments.length?(c=n,r(),t):c},t.iterations=function(n){return arguments.length?(d=+n,t):d},t.strength=function(n){return arguments.length?(l="function"==typeof n?n:u(+n),i=null,r(),t):l},t.distance=function(n){return arguments.length?(y="function"==typeof n?n:u(+n),o=null,r(),t):y},t}function d(n){return n.x}function v(n){return n.y}function s(n){function t(){return h=0,g.restart(u),l}function o(){return g.stop(),l}function u(){var n=f();x.call("tick",l),n&&(g.stop(),x.call("end",l))}function f(){var t=Math.exp(++h*d);s.each(function(n){n(t)});for(var e,r=0,i=n.length;i>r;++r)e=n[r],e.x+=e.vx*=v,e.y+=e.vy*=v;return y>t}function a(){for(var t,e=0,r=n.length;r>e;++e){if(t=n[e],t.index=e,isNaN(t.x)||isNaN(t.y)){var i=q*Math.sqrt(e),o=e*w;t.x=i*Math.cos(o),t.y=i*Math.sin(o)}(isNaN(t.vx)||isNaN(t.vy))&&(t.vx=t.vy=0)}}function c(t){return t.initialize&&t.initialize(n),t}var l,h=0,y=1e-4,d=-.02,v=.6,s=e.map(),g=i.timer(u),x=r.dispatch("tick","end");return null==n&&(n=[]),a(),l={restart:t,stop:o,tick:f,nodes:function(t){return arguments.length?(n=t,a(),s.each(c),l):n},alphaMin:function(n){return arguments.length?(y=n,l):y},alphaDecay:function(n){return arguments.length?(h=+n?Math.round(h*d/-n):0,d=-n,l):-d},drag:function(n){return arguments.length?(v=1-n,l):1-v},force:function(n,t){return arguments.length>1?(null==t?s.remove(n):s.set(n,c(t)),l):s.get(n)},on:function(n,t){return arguments.length>1?(x.on(n,t),l):x.on(n)}}}function g(){function n(n){var e,u=o.length,c=t.quadtree(o,d,v).visitAfter(r);for(a=n,e=0;u>e;++e)f=o[e],c.visit(i)}function e(){if(o){var n,t=o.length;for(c=new Array(t),n=0;t>n;++n)c[n]=+l(o[n],n,o)}}function r(n){var t,e,r,i,o,u=0;if(n.length){for(r=i=o=0;4>o;++o)(t=n[o])&&(e=t.value)&&(u+=e,r+=e*t.x,i+=e*t.y);n.x=r/u,n.y=i/u}else{t=n,t.x=t.data.x,t.y=t.data.y;do u+=c[t.data.index];while(t=t.next)}n.value=u}function i(n,t,e,r){if(!n.value)return!0;var i=n.x-f.x,o=n.y-f.y,u=r-t,l=i*i+o*o;if(l>u*u/s)return y>l&&(h>l&&(l=Math.sqrt(l/h),i/=l,o/=l,l=h),l=n.value*a/l,f.vx+=i*l,f.vy+=o*l),!0;if(!(n.length||l>=y)){h>l&&(l||(l=Math.random()*m,i=Math.cos(l),o=Math.sin(l),l=1),l=Math.sqrt(l/h),i/=l,o/=l,l=h);do n.data!==f&&(u=c[n.data.index]*a/l,f.vx+=i*u,f.vy+=o*u);while(n=n.next)}}var o,f,a,c,l=u(-100),h=1,y=1/0,s=.81;return n.initialize=function(n){o=n,e()},n.strength=function(t){return arguments.length?(l="function"==typeof t?t:u(+t),e(),n):l},n.distanceMin=function(t){return arguments.length?(h=t*t,n):Math.sqrt(h)},n.distanceMax=function(t){return arguments.length?(y=t*t,n):Math.sqrt(y)},n.theta=function(t){return arguments.length?(s=t*t,n):Math.sqrt(s)},n}function x(n,t){function e(n){for(var t,e,r=0,u=i.length;u>r;++r)t=i[r],e=o[r]*n,t.vx+=(f[r]-t.x)*e,t.vy+=(a[r]-t.y)*e}function r(){if(i){var e,r=i.length;for(o=new Array(r),f=new Array(r),a=new Array(r),e=0;r>e;++e)o[e]=+c(i[e],e,i),f[e]=+n(i[e],e,i),a[e]=+t(i[e],e,i)}}var i,o,f,a,c=u(.1);return"function"!=typeof n&&(n=u(null==n?0:+n)),"function"!=typeof t&&(t=u(null==t?0:+t)),e.initialize=function(n){i=n,r()},e.strength=function(n){return arguments.length?(c="function"==typeof n?n:u(+n),r(),e):c},e.x=function(t){return arguments.length?(n="function"==typeof t?t:u(+t),r(),e):n},e.y=function(n){return arguments.length?(t="function"==typeof n?n:u(+n),r(),e):t},e}var p="0.3.0",M=2*Math.PI,q=10,w=Math.PI*(3-Math.sqrt(5)),m=2*Math.PI;n.version=p,n.forceCenter=o,n.forceCollide=c,n.forceContain=l,n.forceLink=y,n.forceManyBody=g,n.forcePosition=x,n.forceSimulation=s}); |
export var name = "d3-force"; | ||
export var version = "0.2.2"; | ||
export var version = "0.3.0"; | ||
export var description = "Force-directed graph layout using velocity Verlet integration."; | ||
@@ -10,4 +10,4 @@ export var keywords = ["d3","layout","network","graphc","force","verlet","infovis"]; | ||
export var repository = {"type":"git","url":"https://github.com/d3/d3-force.git"}; | ||
export var scripts = {"pretest":"rm -rf build && mkdir build && json2module package.json > build/package.js && rollup -g d3-collection:d3_collection,d3-dispatch:d3_dispatch,d3-quadtree:d3_quadtree,d3-timer:d3_timer -f umd -n d3_force -o build/d3-force.js -- index.js","test":"tape 'test/**/*-test.js' && eslint index.js src","prepublish":"npm run test && uglifyjs build/d3-force.js -c -m -o build/d3-force.min.js","postpublish":"VERSION=`node -e 'console.log(require(\"./package.json\").version)'`; git push && git push --tags && cp build/d3-force.js ../d3.github.com/d3-force.v0.2.js && cp build/d3-force.min.js ../d3.github.com/d3-force.v0.2.min.js && cd ../d3.github.com && git add d3-force.v0.2.js d3-force.v0.2.min.js && git commit -m \"d3-force ${VERSION}\" && git push && cd - && zip -j build/d3-force.zip -- LICENSE README.md build/d3-force.js build/d3-force.min.js"}; | ||
export var scripts = {"pretest":"rm -rf build && mkdir build && json2module package.json > build/package.js && rollup -g d3-collection:d3_collection,d3-dispatch:d3_dispatch,d3-quadtree:d3_quadtree,d3-timer:d3_timer -f umd -n d3_force -o build/d3-force.js -- index.js","test":"tape 'test/**/*-test.js' && eslint index.js src","prepublish":"npm run test && uglifyjs build/d3-force.js -c -m -o build/d3-force.min.js","postpublish":"VERSION=`node -e 'console.log(require(\"./package.json\").version)'`; git push && git push --tags && cp build/d3-force.js ../d3.github.com/d3-force.v0.3.js && cp build/d3-force.min.js ../d3.github.com/d3-force.v0.3.min.js && cd ../d3.github.com && git add d3-force.v0.3.js d3-force.v0.3.min.js && git commit -m \"d3-force ${VERSION}\" && git push && cd - && zip -j build/d3-force.zip -- LICENSE README.md build/d3-force.js build/d3-force.min.js"}; | ||
export var dependencies = {"d3-collection":"0.1","d3-dispatch":"0.4","d3-quadtree":"0.7","d3-timer":"0.4"}; | ||
export var devDependencies = {"json2module":"0.0","rollup":"0.26","tape":"4","uglify-js":"2"}; |
{ | ||
"name": "d3-force", | ||
"version": "0.2.2", | ||
"version": "0.3.0", | ||
"description": "Force-directed graph layout using velocity Verlet integration.", | ||
@@ -30,3 +30,3 @@ "keywords": [ | ||
"prepublish": "npm run test && uglifyjs build/d3-force.js -c -m -o build/d3-force.min.js", | ||
"postpublish": "VERSION=`node -e 'console.log(require(\"./package.json\").version)'`; git push && git push --tags && cp build/d3-force.js ../d3.github.com/d3-force.v0.2.js && cp build/d3-force.min.js ../d3.github.com/d3-force.v0.2.min.js && cd ../d3.github.com && git add d3-force.v0.2.js d3-force.v0.2.min.js && git commit -m \"d3-force ${VERSION}\" && git push && cd - && zip -j build/d3-force.zip -- LICENSE README.md build/d3-force.js build/d3-force.min.js" | ||
"postpublish": "VERSION=`node -e 'console.log(require(\"./package.json\").version)'`; git push && git push --tags && cp build/d3-force.js ../d3.github.com/d3-force.v0.3.js && cp build/d3-force.min.js ../d3.github.com/d3-force.v0.3.min.js && cd ../d3.github.com && git add d3-force.v0.3.js d3-force.v0.3.min.js && git commit -m \"d3-force ${VERSION}\" && git push && cd - && zip -j build/d3-force.zip -- LICENSE README.md build/d3-force.js build/d3-force.min.js" | ||
}, | ||
@@ -33,0 +33,0 @@ "dependencies": { |
@@ -7,3 +7,3 @@ # d3-force | ||
If you use NPM, `npm install d3-force`. Otherwise, download the [latest release](https://github.com/d3/d3-force/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-force.v0.2.min.js) or as part of [D3 4.0 alpha](https://github.com/mbostock/d3/tree/4). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3_force` global is exported: | ||
If you use NPM, `npm install d3-force`. Otherwise, download the [latest release](https://github.com/d3/d3-force/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-force.v0.3.min.js) or as part of [D3 4.0 alpha](https://github.com/mbostock/d3/tree/4). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3_force` global is exported: | ||
@@ -15,3 +15,3 @@ ```html | ||
<script src="https://d3js.org/d3-timer.v0.4.min.js"></script> | ||
<script src="https://d3js.org/d3-force.v0.2.min.js"></script> | ||
<script src="https://d3js.org/d3-force.v0.3.min.js"></script> | ||
<script> | ||
@@ -38,3 +38,3 @@ | ||
<a name="simulation_start" href="#simulation_start">#</a> <i>simulation</i>.<b>start</b>() | ||
<a name="simulation_restart" href="#simulation_restart">#</a> <i>simulation</i>.<b>restart</b>() | ||
@@ -51,2 +51,12 @@ … | ||
The exact number of iterations needed to terminate the simulation naturally is ⌈log([*alphaMin*](#simulation_alphaMin)) / -[*alphaDecay*](#simulation_alphaDecay)⌉. For example, to run the simulation manually: | ||
```js | ||
for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / -simulation.alphaDecay()); i < n; ++i) { | ||
simulation.tick(); | ||
} | ||
``` | ||
This may be useful for computing [static force-directed layouts](http://bl.ocks.org/mbostock/01ab2e85e8727d6529d20391c0fd9a16), such as in a background web worker or on the server. | ||
<a name="simulation_nodes" href="#simulation_nodes">#</a> <i>simulation</i>.<b>nodes</b>([<i>nodes</i>]) | ||
@@ -53,0 +63,0 @@ |
import constant from "./constant"; | ||
import {quadtree} from "d3-quadtree"; | ||
import {x, y} from "./simulation"; | ||
function x(d) { | ||
return d.x + d.vx; | ||
} | ||
function y(d) { | ||
return d.y + d.vy; | ||
} | ||
export default function(radius) { | ||
@@ -9,3 +16,4 @@ var nodes, | ||
radiusMax, | ||
strength = 0.7; | ||
strength = 0.7, | ||
iterations = 1; | ||
@@ -18,17 +26,21 @@ if (typeof radius !== "function") radius = constant(radius == null ? 1 : +radius); | ||
node, | ||
nx, | ||
ny, | ||
nr, | ||
vx, | ||
vy, | ||
nx0, | ||
ny0, | ||
nx1, | ||
ny1, | ||
vx, | ||
vy, | ||
nr; | ||
ny1; | ||
for (i = 0; i < n; ++i) { | ||
node = nodes[i], nr = radii[i] + radiusMax, vx = vy = 0; | ||
nx0 = node.x - nr, ny0 = node.y - nr; | ||
nx1 = node.x + nr, ny1 = node.y + nr; | ||
tree.remove(node).visit(apply); | ||
node.x += vx * strength, node.y += vy * strength; | ||
tree.add(node); | ||
for (var k = 0; k < iterations; ++k) { | ||
for (i = 0; i < n; ++i) { | ||
node = nodes[i], nr = radii[i] + radiusMax, vx = vy = 0; | ||
nx = node.x + node.vx, nx0 = nx - nr, nx1 = nx + nr; | ||
ny = node.y + node.vy, ny0 = ny - nr, ny1 = ny + nr; | ||
tree.remove(node).visit(apply); | ||
node.vx += vx * strength, node.vy += vy * strength; | ||
tree.add(node); | ||
} | ||
} | ||
@@ -39,4 +51,4 @@ | ||
if (quad.length) return; | ||
var x = node.x - quad.data.x, | ||
y = node.y - quad.data.y, | ||
var x = nx - quad.data.x - quad.data.vx, | ||
y = ny - quad.data.y - quad.data.vy, | ||
l = x * x + y * y, | ||
@@ -62,2 +74,6 @@ r = radii[i] + radii[quad.data.index]; | ||
force.iterations = function(_) { | ||
return arguments.length ? (iterations = +_, force) : iterations; | ||
}; | ||
force.strength = function(_) { | ||
@@ -64,0 +80,0 @@ return arguments.length ? (strength = +_, force) : strength; |
@@ -12,3 +12,3 @@ import {map} from "d3-collection"; | ||
var id = index, | ||
strength = constant(0.5), | ||
strength = constant(0.7), | ||
strengths, | ||
@@ -18,3 +18,4 @@ distance = constant(30), | ||
nodes, | ||
bias; | ||
bias, | ||
iterations = 1; | ||
@@ -24,13 +25,15 @@ if (links == null) links = []; | ||
function force(alpha) { | ||
for (var i = 0, n = links.length, link, source, target, x, y, l, b; i < n; ++i) { | ||
link = links[i], source = link.source, target = link.target; | ||
x = target.x - source.x; | ||
y = target.y - source.y; | ||
if (l = x * x + y * y) l = Math.sqrt(l), l = (l - distances[i]) / l; | ||
else l = Math.random() * tau, x = Math.cos(l), y = Math.sin(l), l = distances[i]; | ||
l *= alpha * strengths[i], x *= l, y *= l; | ||
target.vx -= x * (b = bias[i]); | ||
target.vy -= y * b; | ||
source.vx += x * (b = 1 - b); | ||
source.vy += y * b; | ||
for (var k = 0, n = links.length; k < iterations; ++k) { | ||
for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { | ||
link = links[i], source = link.source, target = link.target; | ||
x = target.x + target.vx - source.x - source.vx; | ||
y = target.y + target.vy - source.y - source.vy; | ||
if (l = x * x + y * y) l = Math.sqrt(l), l = (l - distances[i]) / l; | ||
else l = Math.random() * tau, x = Math.cos(l), y = Math.sin(l), l = distances[i]; | ||
l *= alpha * strengths[i], x *= l, y *= l; | ||
target.vx -= x * (b = bias[i]); | ||
target.vy -= y * b; | ||
source.vx += x * (b = 1 - b); | ||
source.vy += y * b; | ||
} | ||
} | ||
@@ -86,2 +89,6 @@ } | ||
force.iterations = function(_) { | ||
return arguments.length ? (iterations = +_, force) : iterations; | ||
}; | ||
force.strength = function(_) { | ||
@@ -88,0 +95,0 @@ return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), strengths = null, initialize(), force) : strength; |
@@ -21,3 +21,3 @@ import {dispatch} from "d3-dispatch"; | ||
alphaDecay = -0.02, | ||
drag = 0.5, | ||
drag = 0.6, | ||
forces = map(), | ||
@@ -29,3 +29,3 @@ stepper = timer(step), | ||
function start() { | ||
function restart() { | ||
iteration = 0; | ||
@@ -88,3 +88,3 @@ stepper.restart(step); | ||
return simulation = { | ||
start: start, | ||
restart: restart, | ||
stop: stop, | ||
@@ -91,0 +91,0 @@ tick: tick, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
50869
951
234