// // arbor.js - version 0.91 // a graph vizualization toolkit // // Copyright (c) 2011 Samizdat Drafting Co. // Physics code derived from springy.js, copyright (c) 2010 Dennis Hotson // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // (function($){ /* etc.js */ var trace=function(msg){if(typeof(window)=="undefined"||!window.console){return}var len=arguments.length;var args=[];for(var i=0;i0){return a[0]}else{return null}}; /* kernel.js */ var Kernel=function(b){var k=window.location.protocol=="file:"&&navigator.userAgent.toLowerCase().indexOf("chrome")>-1;var a=(window.Worker!==undefined&&!k);var i=null;var c=null;var f=[];f.last=new Date();var l=null;var e=null;var d=null;var h=null;var g=false;var j={system:b,tween:null,nodes:{},init:function(){if(typeof(Tween)!="undefined"){c=Tween()}else{if(typeof(arbor.Tween)!="undefined"){c=arbor.Tween()}else{c={busy:function(){return false},tick:function(){return true},to:function(){trace("Please include arbor-tween.js to enable tweens");c.to=function(){};return}}}}j.tween=c;var m=b.parameters();if(a){trace("using web workers");l=setInterval(j.screenUpdate,m.timeout);i=new Worker(arbor_path()+"arbor.js");i.onmessage=j.workerMsg;i.onerror=function(n){trace("physics:",n)};i.postMessage({type:"physics",physics:objmerge(m,{timeout:Math.ceil(m.timeout)})})}else{trace("couldn't use web workers, be careful...");i=Physics(m.dt,m.stiffness,m.repulsion,m.friction,j.system._updateGeometry);j.start()}return j},graphChanged:function(m){if(a){i.postMessage({type:"changes",changes:m})}else{i._update(m)}j.start()},particleModified:function(n,m){if(a){i.postMessage({type:"modify",id:n,mods:m})}else{i.modifyNode(n,m)}j.start()},physicsModified:function(m){if(!isNaN(m.timeout)){if(a){clearInterval(l);l=setInterval(j.screenUpdate,m.timeout)}else{clearInterval(d);d=null}}if(a){i.postMessage({type:"sys",param:m})}else{i.modifyPhysics(m)}j.start()},workerMsg:function(n){var m=n.data.type;if(m=="geometry"){j.workerUpdate(n.data)}else{trace("physics:",n.data)}},_lastPositions:null,workerUpdate:function(m){j._lastPositions=m;j._lastBounds=m.bounds},_lastFrametime:new Date().valueOf(),_lastBounds:null,_currentRenderer:null,screenUpdate:function(){var n=new Date().valueOf();var m=false;if(j._lastPositions!==null){j.system._updateGeometry(j._lastPositions);j._lastPositions=null;m=true}if(c&&c.busy()){m=true}if(j.system._updateBounds(j._lastBounds)){m=true}if(m){var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}if(c){c.tick()}o.redraw();var p=f.last;f.last=new Date();f.push(f.last-p);if(f.length>50){f.shift()}}}},physicsUpdate:function(){if(c){c.tick()}i.tick();var n=j.system._updateBounds();if(c&&c.busy()){n=true}var o=j.system.renderer;var m=new Date();var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}o.redraw({timestamp:m})}var q=f.last;f.last=m;f.push(f.last-q);if(f.length>50){f.shift()}var p=i.systemEnergy();if((p.mean+p.max)/2<0.05){if(h===null){h=new Date().valueOf()}if(new Date().valueOf()-h>1000){clearInterval(d);d=null}else{}}else{h=null}},fps:function(n){if(n!==undefined){var q=1000/Math.max(1,targetFps);j.physicsModified({timeout:q})}var r=0;for(var p=0,o=f.length;p0);if(y){$.extend(c.adjacency[D][E].data,z.data);return}else{c.edges[z._id]=z;c.adjacency[D][E].push(z);var x=(z.length!==undefined)?z.length:1;k.push({t:"addSpring",id:z._id,fm:D,to:E,l:x});h._notify()}return z},pruneEdge:function(C){k.push({t:"dropSpring",id:C._id});delete c.edges[C._id];for(var z in c.adjacency){for(var D in c.adjacency[z]){var A=c.adjacency[z][D];for(var B=A.length-1;B>=0;B--){if(c.adjacency[z][D][B]._id===C._id){c.adjacency[z][D].splice(B,1)}}}}h._notify()},getEdges:function(y,x){y=h.getNode(y);x=h.getNode(x);if(!y||!x){return[]}if(typeof(c.adjacency[y._id])!=="undefined"&&typeof(c.adjacency[y._id][x._id])!=="undefined"){return c.adjacency[y._id][x._id]}return[]},getEdgesFrom:function(x){x=h.getNode(x);if(!x){return[]}if(typeof(c.adjacency[x._id])!=="undefined"){var y=[];$.each(c.adjacency[x._id],function(A,z){y=y.concat(z)});return y}return[]},getEdgesTo:function(x){x=h.getNode(x);if(!x){return[]}var y=[];$.each(c.edges,function(A,z){if(z.target==x){y.push(z)}});return y},eachEdge:function(x){$.each(c.edges,function(B,z){var A=c.nodes[z.source._id]._p;var y=c.nodes[z.target._id]._p;if(A.x==null||y.x==null){return}A=(w!==null)?h.toScreen(A):A;y=(w!==null)?h.toScreen(y):y;if(A&&y){x.call(h,z,A,y)}})},prune:function(y){var x={dropped:{nodes:[],edges:[]}};if(y===undefined){$.each(c.nodes,function(A,z){x.dropped.nodes.push(z);h.pruneNode(z)})}else{h.eachNode(function(A){var z=y.call(h,A,{from:h.getEdgesFrom(A),to:h.getEdgesTo(A)});if(z){x.dropped.nodes.push(A);h.pruneNode(A)}})}return x},graft:function(y){var x={added:{nodes:[],edges:[]}};if(y.nodes){$.each(y.nodes,function(A,z){var B=h.getNode(A);if(B){B.data=z}else{x.added.nodes.push(h.addNode(A,z))}c.kernel.start()})}if(y.edges){$.each(y.edges,function(B,z){var A=h.getNode(B);if(!A){x.added.nodes.push(h.addNode(B,{}))}$.each(z,function(F,C){var E=h.getNode(F);if(!E){x.added.nodes.push(h.addNode(F,{}))}var D=h.getEdges(B,F);if(D.length>0){D[0].data=C}else{x.added.edges.push(h.addEdge(B,F,C))}})})}return x},merge:function(y){var x={added:{nodes:[],edges:[]},dropped:{nodes:[],edges:[]}};$.each(c.edges,function(C,B){if((y.edges[B.source.name]===undefined||y.edges[B.source.name][B.target.name]===undefined)){h.pruneEdge(B);x.dropped.edges.push(B)}});var A=h.prune(function(C,B){if(y.nodes[C.name]===undefined){x.dropped.nodes.push(C);return true}});var z=h.graft(y);x.added.nodes=x.added.nodes.concat(z.added.nodes);x.added.edges=x.added.edges.concat(z.added.edges);x.dropped.nodes=x.dropped.nodes.concat(A.dropped.nodes);x.dropped.edges=x.dropped.edges.concat(A.dropped.edges);return x},tweenNode:function(A,x,z){var y=h.getNode(A);if(y){c.tween.to(y,x,z)}},tweenEdge:function(y,x,B,A){if(A===undefined){h._tweenEdge(y,x,B)}else{var z=h.getEdges(y,x);$.each(z,function(C,D){h._tweenEdge(D,B,A)})}},_tweenEdge:function(y,x,z){if(y&&y._id!==undefined){c.tween.to(y,x,z)}},_updateGeometry:function(A){if(A!=undefined){var x=(A.epoch1||C.y*w.height>1){p=_newBounds;return true}else{return false}},energy:function(){return a},bounds:function(){var y=null;var x=null;$.each(c.nodes,function(B,A){if(!y){y=new Point(A._p);x=new Point(A._p);return}var z=A._p;if(z.x===null||z.y===null){return}if(z.x>y.x){y.x=z.x}if(z.y>y.y){y.y=z.y}if(z.x0){c.kernel.graphChanged(k);k=[];i=null}}};c.kernel=Kernel(h);c.tween=c.kernel.tween||null;var e=(window.__defineGetter__==null||window.__defineSetter__==null)?function(y,x,z){if(!y.hasOwnProperty(x)){Object.defineProperty(y,x,z)}}:function(y,x,z){if(z.get){y.__defineGetter__(x,z.get)}if(z.set){y.__defineSetter__(x,z.set)}};var n=function(x){this._n=x;this._state=c};n.prototype=new Point();e(n.prototype,"x",{get:function(){return this._n._p.x},set:function(x){this._state.kernel.particleModified(this._n._id,{x:x})}});e(n.prototype,"y",{get:function(){return this._n._p.y},set:function(x){this._state.kernel.particleModified(this._n._id,{y:x})}});e(Node.prototype,"p",{get:function(){return new n(this)},set:function(x){this._p.x=x.x;this._p.y=x.y;this._state.kernel.particleModified(this._id,{x:x.x,y:x.y})}});e(Node.prototype,"mass",{get:function(){return this._mass},set:function(x){this._mass=x;this._state.kernel.particleModified(this._id,{m:x})}});e(Node.prototype,"tempMass",{set:function(x){this._state.kernel.particleModified(this._id,{_m:x})}});e(Node.prototype,"fixed",{get:function(){return this._fixed},set:function(x){this._fixed=x;this._state.kernel.particleModified(this._id,{f:x?1:0})}});return h}; /* barnes-hut.js */ var BarnesHutTree=function(){var b=[];var a=0;var e=null;var d=0.5;var c={init:function(g,h,f){d=f;a=0;e=c._newBranch();e.origin=g;e.size=h.subtract(g)},insert:function(j){var f=e;var g=[j];while(g.length){var h=g.shift();var m=h._m||h.m;var p=c._whichQuad(h,f);if(f[p]===undefined){f[p]=h;f.mass+=m;if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}}else{if("origin" in f[p]){f.mass+=(m);if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}f=f[p];g.unshift(h)}else{var l=f.size.divide(2);var n=new Point(f.origin);if(p[0]=="s"){n.y+=l.y}if(p[1]=="e"){n.x+=l.x}var o=f[p];f[p]=c._newBranch();f[p].origin=n;f[p].size=l;f.mass=m;f.p=h.p.multiply(m);f=f[p];if(o.p.x===h.p.x&&o.p.y===h.p.y){var k=l.x*0.08;var i=l.y*0.08;o.p.x=Math.min(n.x+l.x,Math.max(n.x,o.p.x-k/2+Math.random()*k));o.p.y=Math.min(n.y+l.y,Math.max(n.y,o.p.y-i/2+Math.random()*i))}g.push(o);g.unshift(h)}}}},applyForces:function(m,g){var f=[e];while(f.length){node=f.shift();if(node===undefined){continue}if(m===node){continue}if("f" in node){var k=m.p.subtract(node.p);var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node._m||node.m)).divide(l*l))}else{var j=m.p.subtract(node.p.divide(node.mass)).magnitude();var h=Math.sqrt(node.size.x*node.size.y);if(h/j>d){f.push(node.ne);f.push(node.nw);f.push(node.se);f.push(node.sw)}else{var k=m.p.subtract(node.p.divide(node.mass));var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node.mass)).divide(l*l))}}}},_whichQuad:function(i,f){if(i.p.exploded()){return null}var h=i.p.subtract(f.origin);var g=f.size.divide(2);if(h.y-1){o.splice(p,1)}delete c.particles[r];delete l.particles[r]},modifyNode:function(r,p){if(r in c.particles){var q=c.particles[r];if("x" in p){q.p.x=p.x}if("y" in p){q.p.y=p.y}if("m" in p){q.m=p.m}if("f" in p){q.fixed=(p.f===1)}if("_m" in p){if(q._m===undefined){q._m=q.m}q.m=p._m}}},addSpring:function(t){var s=t.id;var p=t.l;var r=c.particles[t.fm];var q=c.particles[t.to];if(r!==undefined&&q!==undefined){c.springs[s]=new Spring(r,q,p,i.stiffness);k.push(c.springs[s]);r.connections++;q.connections++;delete l.particles[t.fm];delete l.particles[t.to]}},dropSpring:function(s){var r=s.id;var q=c.springs[r];q.point1.connections--;q.point2.connections--;var p=$.inArray(q,k);if(p>-1){k.splice(p,1)}delete c.springs[r]},_update:function(p){d++;$.each(p,function(q,r){if(r.t in i){i[r.t](r)}});return d},tick:function(){i.tendParticles();i.eulerIntegrator(i.dt);i.tock()},tock:function(){var p=[];$.each(c.particles,function(r,q){p.push(r);p.push(q.p.x);p.push(q.p.y)});if(h){h({geometry:p,epoch:d,energy:b,bounds:g})}},tendParticles:function(){$.each(c.particles,function(q,p){if(p._m!==undefined){if(Math.abs(p.m-p._m)<1){p.m=p._m;delete p._m}else{p.m*=0.98}}p.v.x=p.v.y=0})},eulerIntegrator:function(p){if(i.repulsion>0){if(i.theta>0){i.applyBarnesHutRepulsion()}else{i.applyBruteForceRepulsion()}}if(i.stiffness>0){i.applySprings()}i.applyCenterDrift();if(i.gravity){i.applyCenterGravity()}i.updateVelocity(p);i.updatePosition(p)},applyBruteForceRepulsion:function(){$.each(c.particles,function(q,p){$.each(c.particles,function(s,r){if(p!==r){var u=p.p.subtract(r.p);var v=Math.max(1,u.magnitude());var t=((u.magnitude()>0)?u:Point.random(1)).normalize();p.applyForce(t.multiply(i.repulsion*(r._m||r.m)*0.5).divide(v*v*0.5));r.applyForce(t.multiply(i.repulsion*(p._m||p.m)*0.5).divide(v*v*-0.5))}})})},applyBarnesHutRepulsion:function(){if(!g.topleft||!g.bottomright){return}var q=new Point(g.bottomright);var p=new Point(g.topleft);f.init(p,q,i.theta);$.each(c.particles,function(s,r){f.insert(r)});$.each(c.particles,function(s,r){f.applyForces(r,i.repulsion)})},applySprings:function(){$.each(c.springs,function(t,p){var s=p.point2.p.subtract(p.point1.p);var q=p.length-s.magnitude();var r=((s.magnitude()>0)?s:Point.random(1)).normalize();p.point1.applyForce(r.multiply(p.k*q*-0.5));p.point2.applyForce(r.multiply(p.k*q*0.5))})},applyCenterDrift:function(){var q=0;var r=new Point(0,0);$.each(c.particles,function(t,s){r.add(s.p);q++});if(q==0){return}var p=r.divide(-q);$.each(c.particles,function(t,s){s.applyForce(p)})},applyCenterGravity:function(){$.each(c.particles,function(r,p){var q=p.p.multiply(-1);p.applyForce(q.multiply(i.repulsion/100))})},updateVelocity:function(p){$.each(c.particles,function(t,q){if(q.fixed){q.v=new Point(0,0);q.f=new Point(0,0);return}var s=q.v.magnitude();q.v=q.v.add(q.f.multiply(p)).multiply(1-i.friction);q.f.x=q.f.y=0;var r=q.v.magnitude();if(r>j){q.v=q.v.divide(r*r)}})},updatePosition:function(q){var r=0,p=0,u=0;var t=null;var s=null;$.each(c.particles,function(w,v){v.p=v.p.add(v.v.multiply(q));var x=v.v.magnitude();var z=x*x;r+=z;p=Math.max(z,p);u++;if(!t){t=new Point(v.p.x,v.p.y);s=new Point(v.p.x,v.p.y);return}var y=v.p;if(y.x===null||y.y===null){return}if(y.x>t.x){t.x=y.x}if(y.y>t.y){t.y=y.y}if(y.x1000){e.stop()}else{}}else{c=null}},tock:function(h){h.type="geometry";postMessage(h)},modifyNode:function(i,h){a.modifyNode(i,h);e.go()},modifyPhysics:function(h){a.modifyPhysics(h)},update:function(h){var i=a._update(h)}};return e};var physics=PhysicsWorker();onmessage=function(a){if(!a.data.type){postMessage("¿kérnèl?");return}if(a.data.type=="physics"){var b=a.data.physics;physics.init(a.data.physics);return}switch(a.data.type){case"modify":physics.modifyNode(a.data.id,a.data.mods);break;case"changes":physics.update(a.data.changes);physics.go();break;case"start":physics.go();break;case"stop":physics.stop();break;case"sys":var b=a.data.param||{};if(!isNaN(b.timeout)){physics.timeout(b.timeout)}physics.modifyPhysics(b);physics.go();break}}; })() arbor = (typeof(arbor)!=='undefined') ? arbor : {} $.extend(arbor, { // object constructors (don't use ‘new’, just call them) ParticleSystem:ParticleSystem, Point:function(x, y){ return new Point(x, y) }, // immutable object with useful methods etc:{ trace:trace, // ƒ(msg) -> safe console logging dirname:dirname, // ƒ(path) -> leading part of path basename:basename, // ƒ(path) -> trailing part of path ordinalize:ordinalize, // ƒ(num) -> abbrev integers (and add commas) objcopy:objcopy, // ƒ(old) -> clone an object objcmp:objcmp, // ƒ(a, b, strict_ordering) -> t/f comparison objkeys:objkeys, // ƒ(obj) -> array of all keys in obj objmerge:objmerge, // ƒ(dst, src) -> like $.extend but non-destructive uniq:uniq, // ƒ(arr) -> array of unique items in arr arbor_path:arbor_path, // ƒ() -> guess the directory of the lib code } }) })(this.jQuery)