diff --git a/.gitignore b/.gitignore index b68a348..5ee0875 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ Docs* *.jar *.zip *.*~ +web diff --git a/AUTHORS b/AUTHORS index 726d7ea..50f1d82 100644 --- a/AUTHORS +++ b/AUTHORS @@ -14,3 +14,8 @@ E: quuxbaz@gmail.com W: http://quuxbaz.com.ar/ D: Mostly Icicle code. +N: Vanesa Graíño Pazos +E: nessa.gp@hotmail.com +W: http://es.linkedin.com/in/nessiagp/ +D: Rounded-corners rectangle nodes. + diff --git a/Jit/jit-yc.js b/Jit/jit-yc.js index cef84b0..9a7a5bb 100644 --- a/Jit/jit-yc.js +++ b/Jit/jit-yc.js @@ -21,3 +21,4 @@ THE SOFTWARE. */ +(function(){this.$jit=function(F){F=F||window;for(var G in $jit){if($jit[G].$extend){F[G]=$jit[G]}}};$jit.version="2.0.1";var e=function(F){return document.getElementById(F)};e.empty=function(){};e.extend=function(H,F){for(var G in (F||{})){H[G]=F[G]}return H};e.lambda=function(F){return(typeof F=="function")?F:function(){return F}};e.time=Date.now||function(){return +new Date};e.splat=function(G){var F=e.type(G);return F?((F!="array")?[G]:G):[]};e.type=function(G){var F=e.type.s.call(G).match(/^\[object\s(.*)\]$/)[1].toLowerCase();if(F!="object"){return F}if(G&&G.$$family){return G.$$family}if(G&&G.nodeType==9){return"htmldocument"}return(G&&G.nodeName&&G.nodeType==1)?"element":F};e.type.s=Object.prototype.toString;e.each=function(K,J){var I=e.type(K);if(I=="object"){for(var H in K){J(K[H],H)}}else{for(var G=0,F=K.length;G>16,H>>8&255,H&255]}};e.destroy=function(F){e.clean(F);if(F.parentNode){F.parentNode.removeChild(F)}if(F.clearAttributes){F.clearAttributes()}};e.clean=function(I){for(var H=I.childNodes,G=0,F=H.length;G-1};e.addClass=function(G,F){if(!e.hasClass(G,F)){G.className=(G.className+" "+F)}};e.removeClass=function(G,F){G.className=G.className.replace(new RegExp("(^|\\s)"+F+"(?:\\s|$)"),"$1")};e.getPos=function(H){var K=J(H);var F=I(H);return{x:K.x-F.x,y:K.y-F.y};function J(M){var L={x:0,y:0};while(M&&!G(M)){L.x+=M.offsetLeft;L.y+=M.offsetTop;M=M.offsetParent}return L}function I(M){var L={x:0,y:0};while(M&&!G(M)){L.x+=M.scrollLeft;L.y+=M.scrollTop;M=M.parentNode}return L}function G(L){return(/^(?:body|html)$/i).test(L.tagName)}};e.getDir=function(H){var G=document.getElementById(H)||document.body;if(G.currentStyle){var F=G.currentStyle.direction}else{if(window.getComputedStyle){var F=document.defaultView.getComputedStyle(G,null).getPropertyValue("direction")}}return F};e.event={get:function(G,F){F=F||window;return G||F.event},getWheel:function(F){return F.wheelDelta?F.wheelDelta/120:-(F.detail||0)/3},isRightClick:function(F){return(F.which==3||F.button==2)},getPos:function(I,H){H=H||window;I=I||H.event;var G=H.document;G=G.documentElement||G.body;if(I.touches&&I.touches.length){I=I.touches[0]}var F={x:I.pageX||(I.clientX+G.scrollLeft),y:I.pageY||(I.clientY+G.scrollTop)};return F},stop:function(F){if(F.stopPropagation){F.stopPropagation()}F.cancelBubble=true;if(F.preventDefault){F.preventDefault()}else{F.returnValue=false}}};$jit.util=$jit.id=e;var v=function(G){G=G||{};var F=function(){for(var J in this){if(typeof this[J]!="function"){this[J]=e.unlink(this[J])}}this.constructor=F;if(v.prototyping){return this}var I=this.initialize?this.initialize.apply(this,arguments):this;this.$$family="class";return I};for(var H in v.Mutators){if(!G[H]){continue}G=v.Mutators[H](G,G[H]);delete G[H]}e.extend(F,this);F.constructor=v;F.prototype=G;return F};v.Mutators={Implements:function(F,G){e.each(e.splat(G),function(I){v.prototyping=I;var H=(typeof I=="function")?new I:I;for(var J in H){if(!(J in F)){F[J]=H[J]}}delete v.prototyping});return F}};e.extend(v,{inherit:function(F,I){for(var H in I){var G=I[H];var K=F[H];var J=e.type(G);if(K&&J=="function"){if(G!=K){v.override(F,H,G)}}else{if(J=="object"){F[H]=e.merge(K,G)}else{F[H]=G}}}return F},override:function(G,F,J){var I=v.prototyping;if(I&&G[F]!=I[F]){I=null}var H=function(){var K=this.parent;this.parent=I?I[F]:G[F];var L=J.apply(this,arguments);this.parent=K;return L};G[F]=H}});v.prototype.implement=function(){var F=this.prototype;e.each(Array.prototype.slice.call(arguments||[]),function(G){v.inherit(F,G)});return this};$jit.Class=v;$jit.json={prune:function(G,F){this.each(G,function(I,H){if(H==F&&I.children){delete I.children;I.children=[]}})},getParent:function(F,J){if(F.id==J){return false}var I=F.children;if(I&&I.length>0){for(var H=0;H=(7-4*Q)/11){R=P*P-Math.pow((11-6*Q-11*S)/4,2);break}}return R},Elastic:function(Q,P){return Math.pow(2,10*--Q)*Math.cos(20*Q*Math.PI*(P[0]||1)/3)}};for(var N in O){L[N]=M(O[N])}["Quad","Cubic","Quart","Quint"].forEach(function(Q,P){L[Q]=M(function(R){return Math.pow(R,[P+2])})})})();var H=self||window,F=function(){var P=I;I=[];if(P.length){for(var N=0,M=P.length,O;NK.height+K.y)?(J.y-H.height-I):J.y+I)+"px";F.left=((J.x+H.width+L>K.width+K.x)?(J.x-H.width-L):J.x+L)+"px"},hide:function(F){this.tip.style.display="none";F&&this.config.onHide()}});t.Classes.NodeStyles=new v({Implements:[C,j],initializePost:function(){this.fx=this.viz.fx;this.types=this.viz.fx.nodeTypes;this.nStyles=this.config;this.nodeStylesOnHover=this.nStyles.stylesHover;this.nodeStylesOnClick=this.nStyles.stylesClick;this.hoveredNode=false;this.fx.nodeFxAnimation=new D();this.down=false;this.move=false},onMouseOut:function(H,G){this.down=this.move=false;if(!this.hoveredNode){return}if(this.dom&&this.isLabel(H,G,true)){this.toggleStylesOnHover(this.hoveredNode,false)}var F=H.relatedTarget,I=this.canvas.getElement();while(F&&F.parentNode){if(I==F.parentNode){return}F=F.parentNode}this.toggleStylesOnHover(this.hoveredNode,false);this.hoveredNode=false},onMouseOver:function(I,H){var F;if(this.dom&&(F=this.isLabel(I,H,true))){var G=this.viz.graph.getNode(F.id);if(G.selected){return}this.hoveredNode=G;this.toggleStylesOnHover(this.hoveredNode,true)}},onMouseDown:function(J,I,G,H){if(H){return}var F;if(this.dom&&(F=this.isLabel(J,I))){this.down=this.viz.graph.getNode(F.id)}else{if(!this.dom){this.down=G.getNode()}}this.move=false},onMouseUp:function(I,H,F,G){if(G){return}if(!this.move){this.onClick(F.getNode())}this.down=this.move=false},getRestoredStyles:function(G,F){var I={},H=this["nodeStylesOn"+F];for(var J in H){I[J]=G.styles["$"+J]}return I},toggleStylesOnHover:function(F,G){if(this.nodeStylesOnHover){this.toggleStylesOn("Hover",F,G)}},toggleStylesOnClick:function(F,G){if(this.nodeStylesOnClick){this.toggleStylesOn("Click",F,G)}},toggleStylesOn:function(J,F,L){var M=this.viz;var K=this.nStyles;if(L){var I=this;if(!F.styles){F.styles=e.merge(F.data,{})}for(var N in this["nodeStylesOn"+J]){var G="$"+N;if(!(G in F.styles)){F.styles[G]=F.getData(N)}}M.fx.nodeFx(e.extend({elements:{id:F.id,properties:I["nodeStylesOn"+J]},transition:Trans.Quart.easeOut,duration:300,fps:40},this.config))}else{var H=this.getRestoredStyles(F,J);M.fx.nodeFx(e.extend({elements:{id:F.id,properties:H},transition:Trans.Quart.easeOut,duration:300,fps:40},this.config))}},onClick:function(F){if(!F){return}var G=this.nodeStylesOnClick;if(!G){return}if(F.selected){this.toggleStylesOnClick(F,false);delete F.selected}else{this.viz.graph.eachNode(function(I){if(I.selected){for(var H in G){I.setData(H,I.styles["$"+H],"end")}delete I.selected}});this.toggleStylesOnClick(F,true);F.selected=true;delete F.hovered;this.hoveredNode=false}},onMouseMove:function(L,K,I){if(this.down){this.move=true}if(this.dom&&this.isLabel(L,K)){return}var J=this.nodeStylesOnHover;if(!J){return}if(!this.dom){if(this.hoveredNode){var G=this.types[this.hoveredNode.getData("type")];var F=G&&G.contains&&G.contains.call(this.fx,this.hoveredNode,I.getPos());if(F){return}}var H=I.getNode();if(!this.hoveredNode&&!H){return}if(H.hovered){return}if(H&&!H.selected){this.fx.nodeFxAnimation.stopTimer();this.viz.graph.eachNode(function(N){if(N.hovered&&!N.selected){for(var M in J){N.setData(M,N.styles["$"+M],"end")}delete N.hovered}});H.hovered=true;this.hoveredNode=H;this.toggleStylesOnHover(H,true)}else{if(this.hoveredNode&&!this.hoveredNode.selected){this.fx.nodeFxAnimation.stopTimer();this.toggleStylesOnHover(this.hoveredNode,false);delete this.hoveredNode.hovered;this.hoveredNode=false}}}}});t.Classes.Navigation=new v({Implements:[C,j],initializePost:function(){this.pos=false;this.pressed=false},onMouseWheel:function(I,H,F){if(!this.config.enable||!this.config.zooming){return}e.event.stop(e.event.get(I,H));var J=this.config.zooming/1000,G=1+F*J;this.canvas.scale(G,G)},onMouseDown:function(K,J,I){if(!this.config.enable||!this.config.panning){return}K.preventDefault?K.preventDefault():K.returnValue=false;e.addClass(this.canvas.getElement(),"grabbing");if(this.config.panning=="avoid nodes"&&(this.dom?this.isLabel(K,J):(I.getNode()||I.getEdge()))){return}this.pressed=true;this.pos=I.getPos();var H=this.canvas,G=H.translateOffsetX,F=H.translateOffsetY,M=H.scaleOffsetX,L=H.scaleOffsetY;this.pos.x*=M;this.pos.x+=G;this.pos.y*=L;this.pos.y+=F},onMouseMove:function(K,J,M){if(!this.config.enable||!this.config.panning){return}if(!this.pressed){return}if(this.config.panning=="avoid nodes"&&(this.dom?this.isLabel(K,J):M.getNode())){return}var I=this.pos,L=M.getPos(),G=this.canvas,H=G.translateOffsetX,F=G.translateOffsetY,Q=G.scaleOffsetX,O=G.scaleOffsetY;L.x*=Q;L.y*=O;L.x+=H;L.y+=F;var P=L.x-I.x,N=L.y-I.y;this.pos=L;this.canvas.translate(P*1/Q,N*1/O)},onMouseUp:function(I,H,G,F){if(!this.config.panning){return}e.removeClass(this.canvas.getElement(),"grabbing");this.pressed=false}});var p;(function(){var F=typeof HTMLCanvasElement,H=(F=="object"||F=="function");function G(I,J){var K=document.createElement(I);for(var L in J){if(typeof J[L]=="object"){e.extend(K[L],J[L])}else{K[L]=J[L]}}if(I=="canvas"&&!H&&G_vmlCanvasManager){K=G_vmlCanvasManager.initElement(document.body.appendChild(K))}return K}$jit.Canvas=p=new v({canvases:[],pos:false,element:false,labelContainer:false,translateOffsetX:0,translateOffsetY:0,scaleOffsetX:1,scaleOffsetY:1,initialize:function(U,N){this.viz=U;this.opt=this.config=N;var K=e.type(N.injectInto)=="string"?N.injectInto:N.injectInto.id,T=N.type,L=K+"-label",I=e(K),M=N.width||I.offsetWidth,V=N.height||I.offsetHeight;this.id=K;var O={injectInto:K,width:M,height:V};this.element=G("div",{id:K+"-canvaswidget",style:{position:"relative",width:M+"px",height:V+"px"}});this.labelContainer=this.createLabelContainer(N.Label.type,L,O);this.canvases.push(new p.Base[T]({config:e.extend({idSuffix:"-canvas"},O),plot:function(W){U.fx.plot()},resize:function(){U.refresh()}}));var P=N.background;if(P){var S=new p.Background[P.type](U,e.extend(P,O));this.canvases.push(new p.Base[T](S))}var R=this.canvases.length;while(R--){this.element.appendChild(this.canvases[R].canvas);if(R>0){this.canvases[R].plot()}}this.element.appendChild(this.labelContainer);I.appendChild(this.element);var J=null,Q=this;e.addEvent(window,"scroll",function(){clearTimeout(J);J=setTimeout(function(){Q.getPos(true)},500)})},getCtx:function(I){return this.canvases[I||0].getCtx()},getConfig:function(){return this.opt},getElement:function(){return this.element},getSize:function(I){return this.canvases[I||0].getSize()},resize:function(M,I){this.getPos(true);this.translateOffsetX=this.translateOffsetY=0;this.scaleOffsetX=this.scaleOffsetY=1;for(var K=0,J=this.canvases.length;KN){J=G((N+((K-L)-N)*O))}else{J=G((N-L+(K-(N))*O))}}else{if(M>=I){if(K>N){J=G((N+((K-L)-N)*O))}else{J=G((N-L+(K-(N-L))*O))}}else{J=G((N+(K-N)*O))}}var F=(this.rho-H.rho)*O+H.rho;return{theta:J,rho:F}}};var m=function(G,F){return new d(G,F)};d.KER=m(0,0);var u=function(F,G){this.x=F||0;this.y=G||0};$jit.Complex=u;u.prototype={getc:function(){return this},getp:function(F){return this.toPolar(F)},set:function(F){F=F.getc(true);this.x=F.x;this.y=F.y},setc:function(F,G){this.x=F;this.y=G},setp:function(G,F){this.x=Math.cos(G)*F;this.y=Math.sin(G)*F},clone:function(){return new u(this.x,this.y)},toPolar:function(H){var F=this.norm();var G=Math.atan2(this.y,this.x);if(G<0){G+=Math.PI*2}if(H){return{theta:G,rho:F}}return new d(G,F)},norm:function(){return Math.sqrt(this.squaredNorm())},squaredNorm:function(){return this.x*this.x+this.y*this.y},add:function(F){return new u(this.x+F.x,this.y+F.y)},prod:function(F){return new u(this.x*F.x-this.y*F.y,this.y*F.x+this.x*F.y)},conjugate:function(){return new u(this.x,-this.y)},scale:function(F){return new u(this.x*F,this.y*F)},equals:function(F){return this.x==F.x&&this.y==F.y},$add:function(F){this.x+=F.x;this.y+=F.y;return this},$prod:function(H){var F=this.x,G=this.y;this.x=F*H.x-G*H.y;this.y=G*H.x+F*H.y;return this},$conjugate:function(){this.y=-this.y;return this},$scale:function(F){this.x*=F;this.y*=F;return this},$div:function(I){var F=this.x,H=this.y;var G=I.squaredNorm();this.x=F*I.x+H*I.y;this.y=H*I.x-F*I.y;return this.$scale(1/G)},isZero:function(){var G=0.0001,F=Math.abs;return F(this.x)=P&&T<=Q&&F(S)){R=K(S,T)}if(typeof R!=="undefined"){M=R}if(M&&TT){H(V,P,Q)}})}})(J,O+N,G+N)},eachSubgraph:function(G,H,F){this.eachLevel(G,0,false,H,F)},eachSubnode:function(G,H,F){this.eachLevel(G,1,1,H,F)},anySubnode:function(I,H,G){var F=false;H=H||e.lambda(true);var J=e.type(H)=="string"?function(K){return K[H]}:H;this.eachSubnode(I,function(K){if(J(K)){F=true}},G);return F},getSubnodes:function(K,L,F){var H=[],J=this;L=L||0;var I,G;if(e.type(L)=="array"){I=L[0];G=L[1]}else{I=L;G=Number.MAX_VALUE-K._depth}this.eachLevel(K,I,G,function(M){H.push(M)},F);return H},getParents:function(G){var F=[];this.eachAdjacency(G,function(H){var I=H.nodeTo;if(I._depth-1)){Q.endData[S]=P[S]}else{Q.data[S]=P[S]}}}});K.graph.eachNode(function(P){if(P.ignore){return}P.eachAdjacency(function(Q){if(Q.nodeFrom.ignore||Q.nodeTo.ignore){return}var R=L.getNode(Q.nodeFrom.id);var S=L.getNode(Q.nodeTo.id);if(!R.adjacentTo(S)){var Q=K.graph.getAdjacence(R.id,S.id);F=true;Q.setData("alpha",1);Q.setData("alpha",1,"start");Q.setData("alpha",0,"end");Q._hiding=true}else{if(Q.data.$direction&&Q.data.$direction[0]===R.id){if(!R.adjacentWithDirectionTo(S)){Q._reversing=true}}}})});var F=this.preprocessSum(L);var H=!F?["node-property:alpha"]:["node-property:alpha","edge-property:alpha"];H[0]=H[0]+(("node-property" in I)?(":"+e.splat(I["node-property"]).join(":")):"");H[1]=(H[1]||"edge-property:alpha")+(("edge-property" in I)?(":"+e.splat(I["edge-property"]).join(":")):"");if("label-property" in I){H.push("label-property:"+e.splat(I["label-property"]).join(":"))}if(K.reposition){K.reposition()}else{K.compute("end")}this._updateDirectedEdges();K.graph.eachNode(function(P){if(P.id!=J&&P.pos.getp().equals(d.KER)){P.pos.set(P.endPos);P.startPos.set(P.endPos)}});K.fx.animate(e.merge(O,{modes:[I.position||"polar"].concat(H),onComplete:function(){K.graph.eachNode(function(P){if(P.ignore){K.graph.removeNode(P.id)}});K.graph.eachNode(function(P){P.eachAdjacency(function(Q){if(Q.ignore){K.graph.removeAdjacence(Q.nodeFrom.id,Q.nodeTo.id)}})});O.onComplete()}}));break;default:}},_updateDirectedEdges:function(){var F=this.viz.graph;F.eachNode(function(G){G.eachAdjacency(function(J){var K=J.data.$direction;if(K&&J.nodeFrom.id!==J.data.$direction[0]){return}if(J._hiding){F.removeAdjacence(J.nodeFrom.id,J.nodeTo.id)}if(J._reversing){var M=J.nodeFrom.id;var L=J.nodeTo.id;var I=F.edges[M][L];var H=F.edges[L][M];I.data.$direction=[L,M];H.data.$direction=[L,M];J._reversing=undefined}})})},contract:function(H,G){var F=this.viz;if(H.collapsed||!H.anySubnode(e.lambda(true))){return}G=e.merge(this.options,F.config,G||{},{modes:["node-property:alpha:span","linear"]});H.collapsed=true;(function I(J){J.eachSubnode(function(K){K.ignore=true;K.setData("alpha",0,G.type=="animate"?"end":"current");I(K)})})(H);if(G.type=="animate"){F.compute("end");if(F.rotated){F.rotate(F.rotated,"none",{property:"end"})}(function I(J){J.eachSubnode(function(K){K.setPos(H.getPos("end"),"end");I(K)})})(H);F.fx.animate(G)}else{if(G.type=="replot"){F.refresh()}}},expand:function(H,G){if(!("collapsed" in H)){return}var F=this.viz;G=e.merge(this.options,F.config,G||{},{modes:["node-property:alpha:span","linear"]});delete H.collapsed;(function I(J){J.eachSubnode(function(K){delete K.ignore;K.setData("alpha",1,G.type=="animate"?"end":"current");I(K)})})(H);if(G.type=="animate"){F.compute("end");if(F.rotated){F.rotate(F.rotated,"none",{property:"end"})}F.fx.animate(G)}else{if(G.type=="replot"){F.refresh()}}},preprocessSum:function(G){var F=this.viz;G.eachNode(function(I){if(!F.graph.hasNode(I.id)){F.graph.addNode(I);var J=F.graph.getNode(I.id);J.setData("alpha",0);J.setData("alpha",0,"start");J.setData("alpha",1,"end")}});var H=false;G.eachNode(function(I){I.eachAdjacency(function(J){var K=F.graph.getNode(J.nodeFrom.id);var L=F.graph.getNode(J.nodeTo.id);if(!K.adjacentTo(L)){var J=F.graph.addAdjacence(K,L,J.data);if(K.startAlpha==K.endAlpha&&L.startAlpha==L.endAlpha){H=true;J.setData("alpha",0);J.setData("alpha",0,"start");J.setData("alpha",1,"end")}}})});return H}};var b={none:{render:e.empty,contains:e.lambda(false)},circle:{render:function(I,J,F,H){var G=H.getCtx();G.beginPath();G.arc(J.x,J.y,F,0,Math.PI*2,true);G.closePath();G[I]()},contains:function(K,J,F){var H=K.x-J.x,G=K.y-J.y,I=H*H+G*G;return I<=F*F}},ellipse:{render:function(L,N,F,O,G){var P=G.getCtx(),I=1,H=1,M=1,K=1,J=0;if(F>O){J=F/2;H=O/F;K=F/O}else{J=O/2;I=F/O;M=O/F}P.save();P.scale(I,H);P.beginPath();P.arc(N.x*M,N.y*K,J,0,Math.PI*2,true);P.closePath();P[L]();P.restore()},contains:function(F,M,G,O){var L=0,K=1,J=1,I=0,H=0,N=0;if(G>O){L=G/2;J=O/G}else{L=O/2;K=G/O}I=(F.x-M.x)*(1/K);H=(F.y-M.y)*(1/J);N=I*I+H*H;return N<=L*L}},square:{render:function(G,I,H,F){F.getCtx()[G+"Rect"](I.x-H,I.y-H,2*H,2*H)},contains:function(H,G,F){return Math.abs(G.x-H.x)<=F&&Math.abs(G.y-H.y)<=F}},rectangle:{render:function(I,J,H,F,G){G.getCtx()[I+"Rect"](J.x-H/2,J.y-F/2,H,F)},contains:function(I,H,G,F){return Math.abs(H.x-I.x)<=G/2&&Math.abs(H.y-I.y)<=F/2}},triangle:{render:function(L,M,I,F){var P=F.getCtx(),H=M.x,G=M.y-I,O=H-I,N=M.y+I,K=H+I,J=N;P.beginPath();P.moveTo(H,G);P.lineTo(O,N);P.lineTo(K,J);P.closePath();P[L]()},contains:function(H,G,F){return b.circle.contains(H,G,F)}},star:{render:function(J,L,K,G){var F=G.getCtx(),I=Math.PI/5;F.save();F.translate(L.x,L.y);F.beginPath();F.moveTo(K,0);for(var H=0;H<9;H++){F.rotate(I);if(H%2==0){F.lineTo((K/0.525731)*0.200811,0)}else{F.lineTo(K,0)}}F.closePath();F[J]();F.restore()},contains:function(H,G,F){return b.circle.contains(H,G,F)}},roundedRectangle:{render:function(I,K,M,H,F,G){var N=G.getCtx(),L=K.x,J=K.y;N.save();N.translate(-M/2,-H/2);if(M<2*F){F=M/2}if(H<2*F){F=H/2}N.beginPath();N.moveTo(L+F,J);N.arcTo(L+M,J,L+M,J+H,F);N.arcTo(L+M,J+H,L,J+H,F);N.arcTo(L,J+H,L,J,F);N.arcTo(L,J,L+M,J,F);N.closePath();N[I]();N.restore()},contains:function(J,I,H,G,F){return b.rectangle.contains(J,I,H,G)}}};var r={line:{render:function(I,H,G){var F=G.getCtx();F.beginPath();F.moveTo(I.x,I.y);F.lineTo(H.x,H.y);F.stroke()},contains:function(P,H,K,N){var I=Math.min,L=Math.max,G=I(P.x,H.x)-N,O=L(P.x,H.x)+N,F=I(P.y,H.y)-N,M=L(P.y,H.y)+N;if(K.x>=G&&K.x<=O&&K.y>=F&&K.y<=M){if(Math.abs(H.x-P.x)<=N){return true}var J=(H.y-P.y)/(H.x-P.x)*(K.x-P.x)+P.y;return Math.abs(J-K.y)<=N}return false}},arrow:{render:function(R,S,J,G,F,H){var T=F.getCtx();if(G){var I=R;R=S;S=I}var M=new u(S.x-R.x,S.y-R.y);M.$scale(J/M.norm());var P;switch(H){case"end":P=M;break;case"center":P=new u((S.x-R.x)/2,(S.y-R.y)/2);break}var K=new u(S.x-P.x,S.y-P.y),L=new u(-M.y/2,M.x/2),N=K.add(M),Q=K.add(L),O=K.$add(L.$scale(-1));T.beginPath();T.moveTo(R.x,R.y);T.lineTo(S.x,S.y);T.stroke();T.beginPath();T.moveTo(Q.x,Q.y);T.moveTo(Q.x,Q.y);T.lineTo(O.x,O.y);T.lineTo(N.x,N.y);T.closePath();T.fill()},contains:function(G,F,I,H){return r.line.contains(G,F,I,H)}},hyperline:{render:function(M,N,F,H){var O=H.getCtx();var I=J(M,N);if(I.a>1000||I.b>1000||I.ratio<0){O.beginPath();O.moveTo(M.x*F,M.y*F);O.lineTo(N.x*F,N.y*F);O.stroke()}else{var L=Math.atan2(N.y-I.y,N.x-I.x);var K=Math.atan2(M.y-I.y,M.x-I.x);var G=G(L,K);O.beginPath();O.arc(I.x*F,I.y*F,I.ratio*F,L,K,G);O.stroke()}function J(ab,aa){var T=(ab.x*aa.y-ab.y*aa.x),P=T;var S=ab.squaredNorm(),R=aa.squaredNorm();if(T==0){return{x:0,y:0,ratio:-1}}var Z=(ab.y*R-aa.y*S+ab.y-aa.y)/T;var X=(aa.x*S-ab.x*R+aa.x-ab.x)/P;var Y=-Z/2;var W=-X/2;var V=(Z*Z+X*X)/4-1;if(V<0){return{x:0,y:0,ratio:-1}}var U=Math.sqrt(V);var Q={x:Y,y:W,ratio:U>1000?-1:U,a:Z,b:X};return Q}function G(P,Q){return(PQ)?false:true):((Q+Math.PI>P)?true:false)}},contains:e.lambda(false)}};g.Plot={initialize:function(G,F){this.viz=G;this.config=G.config;this.node=G.config.Node;this.edge=G.config.Edge;this.animation=new D;this.nodeTypes=new F.Plot.NodeTypes;this.edgeTypes=new F.Plot.EdgeTypes;this.labels=G.labels},nodeHelper:b,edgeHelper:r,Interpolator:{map:{border:"color",color:"color",width:"number",height:"number",dim:"number",alpha:"number",lineWidth:"number",angularWidth:"number",span:"number",valueArray:"array-number",dimArray:"array-number",vertices:"polygon"},canvas:{globalAlpha:"number",fillStyle:"color",strokeStyle:"color",lineWidth:"number",shadowBlur:"number",shadowColor:"color",shadowOffsetX:"number",shadowOffsetY:"number",miterLimit:"number"},label:{size:"number",color:"color"},compute:function(H,G,F){return H+(G-H)*F},moebius:function(K,J,M,G){var I=G.scale(-M);if(I.norm()<1){var F=I.x,L=I.y;var H=K.startPos.getc().moebiusTransformation(I);K.pos.setc(H.x,H.y);I.x=F;I.y=L}},linear:function(G,F,J){var I=G.startPos.getc(true);var H=G.endPos.getc(true);G.pos.setc(this.compute(I.x,H.x,J),this.compute(I.y,H.y,J))},polar:function(H,G,K){var J=H.startPos.getp(true);var I=H.endPos.getp();var F=I.interpolate(J,K);H.pos.setp(F.theta,F.rho)},number:function(G,L,K,F,J){var I=G[F](L,"start");var H=G[F](L,"end");G[J](L,this.compute(I,H,K))},color:function(H,F,N,K,I){var L=e.hexToRgb(H[K](F,"start"));var M=e.hexToRgb(H[K](F,"end"));var J=this.compute;var G=e.rgbToHex([parseInt(J(L[0],M[0],N)),parseInt(J(L[1],M[1],N)),parseInt(J(L[2],M[2],N))]);H[I](F,G)},"array-number":function(I,H,S,P,K){var Q=I[P](H,"start"),R=I[P](H,"end"),T=[];for(var N=0,J=Q.length;NR.length){R.push(R[0]||new $jit.Complex(0,0))}if(Q.length==0){return}var J=Q.length;var P=1e+300;for(var L=0;L=0.95){L.labels.plotLabel(H,R,G)}else{L.labels.hideLabel(R,false)}}R.visited=!I})},plotTree:function(J,G,N){var K=this,L=this.viz,H=L.canvas,I=this.config,M=H.getCtx();var F=J.getData("alpha");J.eachSubnode(function(P){if(G.plotSubtree(J,P)&&P.exist&&P.drawn){var O=J.getAdjacency(P.id);G.onBeforePlotLine(O,N);K.plotLine(O,H,N);G.onAfterPlotLine(O,N);K.plotTree(P,G,N)}});if(J.drawn){G.onBeforePlotNode(J,N);this.plotNode(J,H,N);G.onAfterPlotNode(J,N);if(!G.hideLabels&&G.withLabels&&F>=0.95){this.labels.plotLabel(H,J,G)}else{this.labels.hideLabel(J,false)}}else{this.labels.hideLabel(J,true)}},plotNode:function(H,G,O){var L=H.getData("type"),K=this.node.CanvasStyles;if(L!="none"){var F=H.getData("lineWidth"),J=H.getData("color"),I=H.getData("alpha"),M=G.getCtx();M.save();M.lineWidth=F;M.fillStyle=M.strokeStyle=J;M.globalAlpha=I;for(var N in K){M[N]=H.getCanvasStyle(N)}this.nodeTypes[L].render.call(this,H,G,O);M.restore()}},plotLine:function(L,G,P){var K=L.getData("type"),I=this.edge.CanvasStyles;if(K!="none"){var F=L.getData("lineWidth"),H=L.getData("color"),N=G.getCtx(),J=L.nodeFrom,M=L.nodeTo;N.save();N.lineWidth=F;N.fillStyle=N.strokeStyle=H;N.globalAlpha=Math.min(J.getData("alpha"),M.getData("alpha"),L.getData("alpha"));for(var O in I){N[O]=L.getCanvasStyle(O)}this.edgeTypes[K].render.call(this,L,G,P);N.restore()}}};g.Plot3D=e.merge(g.Plot,{Interpolator:{linear:function(G,F,J){var I=G.startPos.getc(true);var H=G.endPos.getc(true);G.pos.setc(this.compute(I.x,H.x,J),this.compute(I.y,H.y,J),this.compute(I.z,H.z,J))}},plotNode:function(G,F){if(G.getData("type")=="none"){return}this.plotElement(G,F,{getAlpha:function(){return G.getData("alpha")}})},plotLine:function(F,G){if(F.getData("type")=="none"){return}this.plotElement(F,G,{getAlpha:function(){return Math.min(F.nodeFrom.getData("alpha"),F.nodeTo.getData("alpha"),F.getData("alpha"))}})},plotElement:function(ah,N,I){var ae=N.getCtx(),O=new Matrix4,G=N.config.Scene.Lighting,ai=N.canvases[0],T=ai.program,ag=ai.camera;if(!ah.geometry){ah.geometry=new O3D[ah.getData("type")]}ah.geometry.update(ah);if(!ah.webGLVertexBuffer){var S=[],K=[],Y=[],W=0,ab=ah.geometry;for(var af=0,ad=ab.vertices,Q=ab.faces,P=Q.length;af=G.width||H.x<-H.w||H.y>=G.height||H.y<-H.h){return false}}else{if(H.x>=G.width||H.x<0||H.y>=G.height||H.y<0){return false}}return true}});g.Label.HTML=new v({Implements:g.Label.DOM,plotLabel:function(I,J,H){var K=J.id,F=this.getLabel(K);if(!F&&!(F=document.getElementById(K))){F=document.createElement("div");var G=this.getLabelContainer();F.id=K;F.className="node";F.style.position="absolute";H.onCreateLabel(F,J);G.appendChild(F);this.labels[J.id]=F}this.placeLabel(F,J,H)}});g.Label.SVG=new v({Implements:g.Label.DOM,plotLabel:function(I,K,H){var M=K.id,F=this.getLabel(M);if(!F&&!(F=document.getElementById(M))){var J="http://www.w3.org/2000/svg";F=document.createElementNS(J,"svg:text");var L=document.createElementNS(J,"svg:tspan");F.appendChild(L);var G=this.getLabelContainer();F.setAttribute("id",M);F.setAttribute("class","node");G.appendChild(F);H.onCreateLabel(F,K);this.labels[K.id]=F}this.placeLabel(F,K,H)}});g.Geom=new v({initialize:function(F){this.viz=F;this.config=F.config;this.node=F.config.Node;this.edge=F.config.Edge},translate:function(G,F){F=e.splat(F);this.viz.graph.eachNode(function(H){e.each(F,function(I){H.getPos(I).$add(G)})})},setRightLevelToShow:function(I,F,K){var J=this.getRightLevelToShow(I,F),H=this.viz.labels,G=e.merge({execShow:true,execHide:true,onHide:e.empty,onShow:e.empty},K||{});I.eachLevel(0,this.config.levelsToShow,function(M){var L=M._depth-I._depth;if(L>J){G.onHide(M);if(G.execHide){M.drawn=false;M.exist=false;H.hideLabel(M,false)}}else{G.onShow(M);if(G.execShow){M.exist=true}}});I.drawn=true},getRightLevelToShow:function(I,G){var F=this.config;var J=F.levelsToShow;var H=F.constrained;if(!H){return J}while(!this.treeFitsInCanvas(I,G,J)&&J>1){J--}return J}});var f={construct:function(G){var H=(e.type(G)=="array");var F=new g(this.graphOptions,this.config.Node,this.config.Edge,this.config.Label);if(!H){(function(I,K){I.addNode(K);if(K.children){for(var J=0,L=K.children;JL?O:L;M.setData("width",N);M.setData("height",N);M.setData("dim",N)}}})},initializeLabel:function(F){if(!this.label){this.label=document.createElement("div");document.body.appendChild(this.label)}this.setLabelStyles(F)},setLabelStyles:function(F){e.extend(this.label.style,{visibility:"hidden",position:"absolute",width:"auto",height:"auto"});this.label.className="jit-autoadjust-label"}};i.Tree=(function(){var O=Array.prototype.slice;function M(Y,T,Q,W,R){var V=T.Node;var S=T.multitree;if(V.overridable){var X=-1,U=-1;Y.eachNode(function(ab){if(ab._depth==Q&&(!S||("$orn" in ab.data)&&ab.data.$orn==W)){var Z=ab.getData("width",R);var aa=ab.getData("height",R);X=(X0)?N[0]:null;M(N)}for(var I=0,J=[L.id].concat(G);I=M._depth)});for(var K=0;K0&&S.drawn){S.drawn=false;G[J.id].push(S)}else{if((!N||!M)&&S.drawn){S.drawn=false;G[J.id].push(S)}}});J.drawn=true}if(F.length>0){O.fx.plot()}for(K in G){e.each(G[K],function(S){S.drawn=true})}for(K=0;KF?H:F)+this.config.subtreeOffset},getEdge:function(K,J,I){var G=function(O,N){return function(){return K.pos.add(new u(O,N))}};var L=this.node;var M=K.getData("align")||L.align;var F=K.getData("width");var H=K.getData("height");if(J=="begin"){if(M=="center"){return this.dispatch(I,G(0,H/2),G(-F/2,0),G(0,-H/2),G(F/2,0))}else{if(M=="left"){return this.dispatch(I,G(0,H),G(0,0),G(0,0),G(F,0))}else{if(M=="right"){return this.dispatch(I,G(0,0),G(-F,0),G(0,-H),G(0,0))}else{throw"align: not implemented"}}}}else{if(J=="end"){if(M=="center"){return this.dispatch(I,G(0,-H/2),G(F/2,0),G(0,H/2),G(-F/2,0))}else{if(M=="left"){return this.dispatch(I,G(0,0),G(F,0),G(0,H),G(0,0))}else{if(M=="right"){return this.dispatch(I,G(0,-H),G(0,0),G(0,0),G(-F,0))}else{throw"align: not implemented"}}}}}},getScaledTreePosition:function(J,L){var K=this.node;var M=J.getData("align")||K.align;var F=J.getData("width");var I=J.getData("height");var H=(this.config.multitree&&("$orn" in J.data)&&J.data.$orn)||this.config.orientation;var G=function(O,N){return function(){return J.pos.add(new u(O,N)).$scale(1-L)}};if(M=="left"){return this.dispatch(H,G(0,I),G(0,0),G(0,0),G(F,0))}else{if(M=="center"){return this.dispatch(H,G(0,I/2),G(-F/2,0),G(0,-I/2),G(F/2,0))}else{if(M=="right"){return this.dispatch(H,G(0,0),G(-F,0),G(0,-I),G(0,0))}else{throw"align: not implemented"}}}},treeFitsInCanvas:function(K,F,L){var H=F.getSize();var I=(this.config.multitree&&("$orn" in K.data)&&K.data.$orn)||this.config.orientation;var G=this.dispatch(I,H.width,H.height);var J=this.getTreeBaseSize(K,L,function(N,M){return N===0||!M.anySubnode()});return(J=0){I.drawn=false;var M=G.getCtx();var K=L.geom.getScaledTreePosition(I,J);M.translate(K.x,K.y);M.scale(J,J)}this.plotTree(I,e.merge(F,{withLabels:true,hideLabels:!!J,plotSubtree:function(R,P){var O=H.multitree&&!("$orn" in I.data);var Q=O&&I.getData("orns");return !O||Q.indexOf(I.getData("orn"))>-1}}),N);if(J>=0){I.drawn=true}},getAlignedPos:function(K,I,F){var H=this.node;var J,G;if(H.align=="center"){J={x:K.x-I/2,y:K.y-F/2}}else{if(H.align=="left"){G=this.config.orientation;if(G=="bottom"||G=="top"){J={x:K.x-I/2,y:K.y}}else{J={x:K.x,y:K.y-F/2}}}else{if(H.align=="right"){G=this.config.orientation;if(G=="bottom"||G=="top"){J={x:K.x-I/2,y:K.y-F}}else{J={x:K.x-I,y:K.y-F/2}}}else{throw"align: not implemented"}}}return J},getOrientation:function(F){var H=this.config;var G=H.orientation;if(H.multitree){var I=F.nodeFrom;var J=F.nodeTo;G=(("$orn" in I.data)&&I.data.$orn)||(("$orn" in J.data)&&J.data.$orn)}return G}});$jit.ST.Label={};$jit.ST.Label.Native=new v({Implements:g.Label.Native,renderLabel:function(I,K,H){var G=I.getCtx(),M=K.pos.getc(true),J=K.getData("width"),F=K.getData("height"),L=this.viz.fx.getAlignedPos(M,J,F);G.fillText(K.name,L.x+J/2,L.y+F/2)}});$jit.ST.Label.DOM=new v({Implements:g.Label.DOM,placeLabel:function(Y,R,N){var J=R.pos.getc(true),X=this.viz.config,T=X.Node,S=R.getData("align")||T.align,F=this.viz.canvas,K=R.getData("width"),V=R.getData("height"),G=F.getSize(),O,W;var I=F.translateOffsetX,H=F.translateOffsetY,M=F.scaleOffsetX,L=F.scaleOffsetY,Q=J.x*M+I,P=J.y*L+H;if(S=="center"){O={x:Math.round(Q-K/2+G.width/2),y:Math.round(P-V/2+G.height/2)}}else{if(S=="left"){W=X.orientation;if(W=="bottom"||W=="top"){O={x:Math.round(Q-K/2+G.width/2),y:Math.round(P+G.height/2)}}else{O={x:Math.round(Q+G.width/2),y:Math.round(P-V/2+G.height/2)}}}else{if(S=="right"){W=X.orientation;if(W=="bottom"||W=="top"){O={x:Math.round(Q-K/2+G.width/2),y:Math.round(P-V+G.height/2)}}else{O={x:Math.round(Q-K+G.width/2),y:Math.round(P-V/2+G.height/2)}}}else{throw"align: not implemented"}}}O.w=K;O.h=V;var U=Y.style;U.left=O.x+"px";U.top=O.y+"px";U.display=this.fitsInCanvas(O,F)?"":"none";N.onPlaceLabel(Y,R)}});$jit.ST.Label.SVG=new v({Implements:[$jit.ST.Label.DOM,g.Label.SVG],initialize:function(F){this.viz=F}});$jit.ST.Label.HTML=new v({Implements:[$jit.ST.Label.DOM,g.Label.HTML],initialize:function(F){this.viz=F}});$jit.ST.Plot.NodeTypes=new v({none:{render:e.empty,contains:e.lambda(false)},circle:{render:function(G,F){var I=G.getData("dim"),J=this.getAlignedPos(G.pos.getc(true),I,I),H=I/2;this.nodeHelper.circle.render("fill",{x:J.x+H,y:J.y+H},H,F)},contains:function(F,J){var H=F.getData("dim"),I=this.getAlignedPos(F.pos.getc(true),H,H),G=H/2;return this.nodeHelper.circle.contains({x:I.x+G,y:I.y+G},J,G)}},square:{render:function(G,F){var I=G.getData("dim"),H=I/2,J=this.getAlignedPos(G.pos.getc(true),I,I);this.nodeHelper.square.render("fill",{x:J.x+H,y:J.y+H},H,F)},contains:function(F,J){var H=F.getData("dim"),I=this.getAlignedPos(F.pos.getc(true),H,H),G=H/2;return this.nodeHelper.square.contains({x:I.x+G,y:I.y+G},J,G)}},ellipse:{render:function(I,G){var H=I.getData("width"),F=I.getData("height"),J=this.getAlignedPos(I.pos.getc(true),H,F);this.nodeHelper.ellipse.render("fill",{x:J.x+H/2,y:J.y+F/2},H,F,G)},contains:function(H,J){var G=H.getData("width"),F=H.getData("height"),I=this.getAlignedPos(H.pos.getc(true),G,F);return this.nodeHelper.ellipse.contains({x:I.x+G/2,y:I.y+F/2},J,G,F)}},rectangle:{render:function(I,G){var H=I.getData("width"),F=I.getData("height"),J=this.getAlignedPos(I.pos.getc(true),H,F);this.nodeHelper.rectangle.render("fill",{x:J.x+H/2,y:J.y+F/2},H,F,G)},contains:function(H,J){var G=H.getData("width"),F=H.getData("height"),I=this.getAlignedPos(H.pos.getc(true),G,F);return this.nodeHelper.rectangle.contains({x:I.x+G/2,y:I.y+F/2},J,G,F)}},roundedRectangle:{render:function(J,H){var I=J.getData("width"),G=J.getData("height"),F=J.getData("radius"),K=this.getAlignedPos(J.pos.getc(true),I,G);this.nodeHelper.roundedRectangle.render("fill",{x:K.x+I/2,y:K.y+G/2},I,G,F,H)},contains:function(I,K){var H=I.getData("width"),G=I.getData("height"),F=I.getData("radius"),J=this.getAlignedPos(I.pos.getc(true),H,G);this.nodeHelper.rectangle.contains({x:J.x+H/2,y:J.y+G/2},K,H,G,F)}}});$jit.ST.Plot.EdgeTypes=new v({none:e.empty,line:{render:function(G,I){var H=this.getOrientation(G),J=G.nodeFrom,K=G.nodeTo,F=J._depth1&&M[0]!=H.id);this.edgeHelper.arrow.render(O,N,J,I,G)},contains:function(G,M){var H=this.getOrientation(G),I=G.nodeFrom,J=G.nodeTo,F=I._depth0||M[ap][1]>0)){var Y=R+M[ap][0],W=L+M[ap][1],ao=Math.atan((W-Y)/F),ag=55;var ac=T.createLinearGradient(ai+F/2,ah-(Y+W)/2,ai+F/2+ag*Math.sin(ao),ah-(Y+W)/2+ag*Math.cos(ao));var X=e.rgbToHex(e.map(e.hexToRgb(P[ap%J].slice(1)),function(ar){return(ar*0.85)>>0}));ac.addColorStop(0,P[ap%J]);ac.addColorStop(1,X);T.fillStyle=ac}T.beginPath();T.moveTo(ai,ah-R);T.lineTo(ai+F,ah-L);T.lineTo(ai+F,ah-L-M[ap][1]);T.lineTo(ai,ah-R-M[ap][0]);T.lineTo(ai,ah-R);T.fill();T.restore();if(O){var Z=O.name==S[ap];var G=Z?0.7:0.8;var X=e.rgbToHex(e.map(e.hexToRgb(P[ap%J].slice(1)),function(ar){return(ar*G)>>0}));T.strokeStyle=X;T.lineWidth=Z?4:1;T.save();T.beginPath();if(O.index===0){T.moveTo(ai,ah-R);T.lineTo(ai,ah-R-M[ap][0])}else{T.moveTo(ai+F,ah-L);T.lineTo(ai+F,ah-L-M[ap][1])}T.stroke();T.restore()}R+=(M[ap][0]||0);L+=(M[ap][1]||0);if(M[ap][0]>0){ae+=(I[ap][0]||0)}}if(aa&&am.type=="Native"){T.save();T.beginPath();T.fillStyle=T.strokeStyle=am.color;T.font=am.style+" "+am.size+"px "+am.family;T.textAlign="center";T.textBaseline="middle";var V=U(ad.name,ak,aj,ad,ae);if(V!==false){T.fillText(V!==true?V:ae,ai,ah-R-af.labelOffset-am.size/2,F)}var al=aq(ad.name,ak,aj,ad);if(al!==false){T.fillText(al!==true?al:ad.name,ai,ah+am.size/2+af.labelOffset)}T.restore()}}},contains:function(J,L){var Q=J.pos.getc(true),G=J.getData("width"),U=J.getData("height"),T=this.getAlignedPos(Q,G,U),S=T.x,R=T.y,V=J.getData("dimArray"),F=L.x-S;if(L.xS+G||L.y>R||L.y=N){var O=+(F>G/2);return{name:J.getData("stringArray")[M],color:J.getData("colorArray")[M],value:J.getData("valueArray")[M][O],index:O}}}return false}}});$jit.AreaChart=new v({st:null,colors:["#416D9C","#70A35E","#EBB056","#C74243","#83548B","#909291","#557EAA"],selected:{},busy:false,initialize:function(H){this.controller=this.config=e.merge(q("Canvas","Margin","Label","AreaChart"),{Label:{type:"Native"}},H);var I=this.config.showLabels,G=e.type(I),J=this.config.showAggregates,F=e.type(J);this.config.showLabels=G=="function"?I:e.lambda(I);this.config.showAggregates=F=="function"?J:e.lambda(J);this.initializeViz()},initializeViz:function(){var G=this.config,K=this,F=G.type.split(":")[0],J={};var I=new $jit.ST({injectInto:G.injectInto,width:G.width,height:G.height,orientation:"bottom",levelDistance:0,siblingOffset:0,subtreeOffset:0,withLabels:G.Label.type!="Native",useCanvas:G.useCanvas,Label:{type:G.Label.type},Node:{overridable:true,type:"areachart-"+F,align:"left",width:1,height:1},Edge:{type:"none"},Tips:{enable:G.Tips.enable,type:"Native",force:true,onShow:function(P,O,M){var N=M;G.Tips.onShow(P,N,O)}},Events:{enable:true,type:"Native",onClick:function(O,P,M){if(!G.filterOnClick&&!G.Events.enable){return}var N=P.getContains();if(N){G.filterOnClick&&K.filter(N.name)}G.Events.enable&&G.Events.onClick(N,P,M)},onRightClick:function(N,O,M){if(!G.restoreOnRightClick){return}K.restore()},onMouseMove:function(O,P,M){if(!G.selectOnHover){return}if(O){var N=P.getContains();K.select(O.id,N.name,N.index)}else{K.select(false,false,false)}}},onCreateLabel:function(S,P){var Y=G.Label,X=P.getData("valueArray"),Q=e.reduce(X,function(Z,aa){return Z+aa[0]},0),V=e.reduce(X,function(Z,aa){return Z+aa[1]},0);if(P.getData("prev")){var U={wrapper:document.createElement("div"),aggregate:document.createElement("div"),label:document.createElement("div")};var M=U.wrapper,W=U.label,N=U.aggregate,O=M.style,T=W.style,R=N.style;J[P.id]=U;M.appendChild(W);M.appendChild(N);if(!G.showLabels(P.name,Q,V,P)){W.style.display="none"}if(!G.showAggregates(P.name,Q,V,P)){N.style.display="none"}O.position="relative";O.overflow="visible";O.fontSize=Y.size+"px";O.fontFamily=Y.family;O.color=Y.color;O.textAlign="center";R.position=T.position="absolute";S.style.width=P.getData("width")+"px";S.style.height=P.getData("height")+"px";W.innerHTML=P.name;S.appendChild(M)}},onPlaceLabel:function(ae,Y){if(!Y.getData("prev")){return}var ac=J[Y.id],N=ac.wrapper.style,M=ac.label.style,X=ac.aggregate.style,V=Y.getData("width"),T=Y.getData("height"),S=Y.getData("dimArray"),P=Y.getData("valueArray"),U=e.reduce(P,function(af,ag){return af+ag[0]},0),Q=e.reduce(P,function(af,ag){return af+ag[1]},0),R=parseInt(N.fontSize,10),W=ae.style;if(S&&P){if(G.showLabels(Y.name,U,Q,Y)){M.display=""}else{M.display="none"}var O=G.showAggregates(Y.name,U,Q,Y);if(O!==false){X.display=""}else{X.display="none"}N.width=X.width=M.width=ae.style.width=V+"px";X.left=M.left=-V/2+"px";for(var ab=0,Z=P.length,aa=0,ad=0;ab0){aa+=P[ab][0];ad+=S[ab][0]}}X.top=(-R-G.labelOffset)+"px";M.top=(G.labelOffset+ad)+"px";ae.style.top=parseInt(ae.style.top,10)-ad+"px";ae.style.height=N.height=ad+"px";ac.aggregate.innerHTML=O!==true?O:aa}}});var H=I.canvas.getSize(),L=G.Margin;I.config.offsetY=-H.height/2+L.bottom+(G.showLabels&&(G.labelOffset+G.Label.size));I.config.offsetX=(L.right-L.left)/2;this.delegate=I;this.canvas=this.delegate.canvas},loadJSON:function(W){var S=e.time(),K=[],V=this.delegate,Z=e.splat(W.label),R=e.splat(W.color||this.colors),X=this.config,G=!!X.type.split(":")[1],I=X.animate;for(var T=0,H=W.values,Q=H.length;T-1)?P:[0,0]}),"end")});this.delegate.fx.animate({modes:["node-property:dimArray"],duration:1500,onComplete:function(){H.busy=false;J&&J.onComplete()}})},restore:function(G){if(this.busy){return}this.busy=true;if(this.config.Tips.enable){this.delegate.tips.hide()}this.select(false,false,false);this.normalizeDims();var F=this;this.delegate.fx.animate({modes:["node-property:height:dimArray"],duration:1500,onComplete:function(){F.busy=false;G&&G.onComplete()}})},select:function(K,G,F){if(!this.config.selectOnHover){return}var H=this.selected;if(H.id!=K||H.name!=G||H.index!=F){H.id=K;H.name=G;H.index=F;this.delegate.graph.eachNode(function(L){L.setData("border",false)});if(K){var J=this.delegate.graph.getNode(K);J.setData("border",H);var I=F===0?"prev":"next";I=J.getData(I);if(I){J=this.delegate.graph.getByName(I);if(J){J.setData("border",{name:G,index:1-F})}}}this.delegate.plot()}},getLegend:function(){var H={};var I;this.delegate.graph.getNode(this.delegate.root).eachAdjacency(function(J){I=J.nodeTo});var G=I.getData("colorArray"),F=G.length;e.each(I.getData("stringArray"),function(K,J){H[K]=G[J%F]});return H},getMaxValue:function(){var F=0;this.delegate.graph.eachNode(function(K){var H=K.getData("valueArray"),G=0,J=0;e.each(H,function(L){G+=+L[0];J+=+L[1]});var I=J>G?J:G;F=F>I?F:I});return F},normalizeDims:function(){var L=this.delegate.graph.getNode(this.delegate.root),I=0;L.eachAdjacency(function(){I++});var K=this.getMaxValue()||1,O=this.delegate.canvas.getSize(),H=this.config,J=H.Margin,M=H.labelOffset+H.Label.size,F=(O.width-(J.left+J.right))/I,G=H.animate,N=O.height-(J.top+J.bottom)-(H.showAggregates&&M)-(H.showLabels&&M);this.delegate.graph.eachNode(function(U){var R=0,T=0,P=[];e.each(U.getData("valueArray"),function(V){R+=+V[0];T+=+V[1];P.push([0,0])});var S=T>R?T:R;U.setData("width",F);if(G){U.setData("height",S*N/K,"end");U.setData("dimArray",e.map(U.getData("valueArray"),function(V){return[V[0]*N/K,V[1]*N/K]}),"end");var Q=U.getData("dimArray");if(!Q){U.setData("dimArray",P)}}else{U.setData("height",S*N/K);U.setData("dimArray",e.map(U.getData("valueArray"),function(V){return[V[0]*N/K,V[1]*N/K]}))}})}});q.BarChart={$extend:true,animate:true,type:"stacked",labelOffset:3,barsOffset:0,hoveredColor:"#9fd4ff",orientation:"horizontal",showAggregates:true,showLabels:true,Tips:{enable:false,onShow:e.empty,onHide:e.empty},Events:{enable:false,onClick:e.empty}};$jit.ST.Plot.NodeTypes.implement({"barchart-stacked":{render:function(Y,J){var O=Y.pos.getc(true),X=Y.getData("width"),V=Y.getData("height"),T=this.getAlignedPos(O,X,V),S=T.x,R=T.y,U=Y.getData("dimArray"),M=Y.getData("valueArray"),L=Y.getData("colorArray"),I=L.length,af=Y.getData("stringArray");var aa=J.getCtx(),F={},ab=Y.getData("border"),G=Y.getData("gradient"),ah=Y.getData("config"),H=ah.orientation=="horizontal",K=ah.showAggregates,W=ah.showLabels,Q=ah.Label;if(L&&U&&af){for(var ae=0,Z=U.length,ad=0,N=0;ae>0}));ag.addColorStop(0,ac);ag.addColorStop(0.5,L[ae%I]);ag.addColorStop(1,ac);aa.fillStyle=ag}if(H){aa.fillRect(S+ad,R,U[ae],V)}else{aa.fillRect(S,R-ad-U[ae],X,U[ae])}if(ab&&ab.name==af[ae]){F.acum=ad;F.dimValue=U[ae]}ad+=(U[ae]||0);N+=(M[ae]||0)}if(ab){aa.save();aa.lineWidth=2;aa.strokeStyle=ab.color;if(H){aa.strokeRect(S+F.acum+1,R+1,F.dimValue-2,V-2)}else{aa.strokeRect(S+1,R-F.acum-F.dimValue+1,X-2,F.dimValue-2)}aa.restore()}if(Q.type=="Native"){aa.save();aa.fillStyle=aa.strokeStyle=Q.color;aa.font=Q.style+" "+Q.size+"px "+Q.family;aa.textBaseline="middle";var P=K(Y.name,N,Y);if(P!==false){P=P!==true?P:N;if(H){aa.textAlign="right";aa.fillText(P,S+ad-ah.labelOffset,R+V/2)}else{aa.textAlign="center";aa.fillText(P,S+X/2,R-V-Q.size/2-ah.labelOffset)}}if(W(Y.name,N,Y)){if(H){aa.textAlign="center";aa.translate(S-ah.labelOffset-Q.size/2,R+V/2);aa.rotate(Math.PI/2);aa.fillText(Y.name,0,0)}else{aa.textAlign="center";aa.fillText(Y.name,S+X/2,R+Q.size/2+ah.labelOffset)}}aa.restore()}}},contains:function(K,M){var P=K.pos.getc(true),H=K.getData("width"),U=K.getData("height"),T=this.getAlignedPos(P,H,U),S=T.x,Q=T.y,V=K.getData("dimArray"),I=K.getData("config"),G=M.x-S,F=I.orientation=="horizontal";if(F){if(M.xS+H||M.y>Q+U||M.yS+H||M.y>Q||M.y=O){return{name:K.getData("stringArray")[N],color:K.getData("colorArray")[N],value:K.getData("valueArray")[N],label:K.name}}}}return false}},"barchart-grouped":{render:function(aa,J){var P=aa.pos.getc(true),Z=aa.getData("width"),X=aa.getData("height"),U=this.getAlignedPos(P,Z,X),T=U.x,S=U.y,W=aa.getData("dimArray"),N=aa.getData("valueArray"),ag=N.length,M=aa.getData("colorArray"),I=M.length,ai=aa.getData("stringArray");var ac=J.getCtx(),F={},ad=aa.getData("border"),G=aa.getData("gradient"),ak=aa.getData("config"),H=ak.orientation=="horizontal",L=ak.showAggregates,Y=ak.showLabels,R=ak.Label,K=(H?X:Z)/ag;if(M&&W&&ai){for(var ah=0,ab=ag,af=0,O=0;ah>0}));aj.addColorStop(0,ae);aj.addColorStop(0.5,M[ah%I]);aj.addColorStop(1,ae);ac.fillStyle=aj}if(H){ac.fillRect(T,S+K*ah,W[ah],K)}else{ac.fillRect(T+K*ah,S-W[ah],K,W[ah])}if(ad&&ad.name==ai[ah]){F.acum=K*ah;F.dimValue=W[ah]}af+=(W[ah]||0);O+=(N[ah]||0)}if(ad){ac.save();ac.lineWidth=2;ac.strokeStyle=ad.color;if(H){ac.strokeRect(T+1,S+F.acum+1,F.dimValue-2,K-2)}else{ac.strokeRect(T+F.acum+1,S-F.dimValue+1,K-2,F.dimValue-2)}ac.restore()}if(R.type=="Native"){ac.save();ac.fillStyle=ac.strokeStyle=R.color;ac.font=R.style+" "+R.size+"px "+R.family;ac.textBaseline="middle";var Q=L(aa.name,O,aa);if(Q!==false){Q=Q!==true?Q:O;if(H){ac.textAlign="right";ac.fillText(Q,T+Math.max.apply(null,W)-ak.labelOffset,S+X/2)}else{ac.textAlign="center";ac.fillText(Q,T+Z/2,S-Math.max.apply(null,W)-R.size/2-ak.labelOffset)}}var V=Y(aa.name,O,aa);if(V!==false){V=V!==true?V:aa.name;if(H){ac.textAlign="center";ac.translate(T-ak.labelOffset-R.size/2,S+X/2);ac.rotate(Math.PI/2);ac.fillText(V,0,0)}else{ac.textAlign="center";ac.fillText(V,T+Z/2,S+R.size/2+ak.labelOffset)}}ac.restore()}}},contains:function(Q,M){var I=Q.pos.getc(true),P=Q.getData("width"),O=Q.getData("height"),L=this.getAlignedPos(I,P,O),K=L.x,J=L.y,N=Q.getData("dimArray"),T=N.length,W=Q.getData("config"),H=M.x-K,F=W.orientation=="horizontal",G=(F?O:P)/T;if(F){if(M.xK+P||M.y>J+O||M.yK+P||M.y>J||M.y=U&&M.y<=U+G){return{name:Q.getData("stringArray")[S],color:Q.getData("colorArray")[S],value:Q.getData("valueArray")[S],label:Q.name}}}else{var U=K+G*S;if(M.x>=U&&M.x<=U+G&&M.y>=J-V){return{name:Q.getData("stringArray")[S],color:Q.getData("colorArray")[S],value:Q.getData("valueArray")[S],label:Q.name}}}}return false}}});$jit.BarChart=new v({st:null,colors:["#416D9C","#70A35E","#EBB056","#C74243","#83548B","#909291","#557EAA"],selected:{},busy:false,initialize:function(H){this.controller=this.config=e.merge(q("Canvas","Margin","Label","BarChart"),{Label:{type:"Native"}},H);var I=this.config.showLabels,G=e.type(I),J=this.config.showAggregates,F=e.type(J);this.config.showLabels=G=="function"?I:e.lambda(I);this.config.showAggregates=F=="function"?J:e.lambda(J);this.initializeViz()},initializeViz:function(){var G=this.config,K=this;var F=G.type.split(":")[0],M=G.orientation=="horizontal",J={};var I=new $jit.ST({injectInto:G.injectInto,width:G.width,height:G.height,orientation:M?"left":"bottom",levelDistance:0,siblingOffset:G.barsOffset,subtreeOffset:0,withLabels:G.Label.type!="Native",useCanvas:G.useCanvas,Label:{type:G.Label.type},Node:{overridable:true,type:"barchart-"+F,align:"left",width:1,height:1},Edge:{type:"none"},Tips:{enable:G.Tips.enable,type:"Native",force:true,onShow:function(Q,P,N){var O=N;G.Tips.onShow(Q,O,P)}},Events:{enable:true,type:"Native",onClick:function(P,Q,N){if(!G.Events.enable){return}var O=Q.getContains();G.Events.onClick(O,Q,N)},onMouseMove:function(P,Q,N){if(!G.hoveredColor){return}if(P){var O=Q.getContains();K.select(P.id,O.name,O.index)}else{K.select(false,false,false)}}},onCreateLabel:function(S,Q){var Y=G.Label,W=Q.getData("valueArray"),V=e.reduce(W,function(Z,aa){return Z+aa},0);var U={wrapper:document.createElement("div"),aggregate:document.createElement("div"),label:document.createElement("div")};var N=U.wrapper,X=U.label,O=U.aggregate,P=N.style,T=X.style,R=O.style;J[Q.id]=U;N.appendChild(X);N.appendChild(O);if(!G.showLabels(Q.name,V,Q)){T.display="none"}if(!G.showAggregates(Q.name,V,Q)){R.display="none"}P.position="relative";P.overflow="visible";P.fontSize=Y.size+"px";P.fontFamily=Y.family;P.color=Y.color;P.textAlign="center";R.position=T.position="absolute";S.style.width=Q.getData("width")+"px";S.style.height=Q.getData("height")+"px";R.left=T.left="0px";X.innerHTML=Q.name;S.appendChild(N)},onPlaceLabel:function(ad,Y){if(!J[Y.id]){return}var ac=J[Y.id],P=ac.wrapper.style,N=ac.label.style,X=ac.aggregate.style,ae=G.type.split(":")[0]=="grouped",O=G.orientation=="horizontal",T=Y.getData("dimArray"),R=Y.getData("valueArray"),V=(ae&&O)?Math.max.apply(null,T):Y.getData("width"),U=(ae&&!O)?Math.max.apply(null,T):Y.getData("height"),S=parseInt(P.fontSize,10),W=ad.style;if(T&&R){P.width=X.width=N.width=ad.style.width=V+"px";for(var ab=0,Z=R.length,aa=0;ab0){aa+=R[ab]}}if(G.showLabels(Y.name,aa,Y)){N.display=""}else{N.display="none"}var Q=G.showAggregates(Y.name,aa,Y);if(Q!==false){X.display=""}else{X.display="none"}if(G.orientation=="horizontal"){X.textAlign="right";N.textAlign="left";N.textIndex=X.textIndent=G.labelOffset+"px";X.top=N.top=(U-S)/2+"px";ad.style.height=P.height=U+"px"}else{X.top=(-S-G.labelOffset)+"px";N.top=(G.labelOffset+U)+"px";ad.style.top=parseInt(ad.style.top,10)-U+"px";ad.style.height=P.height=U+"px"}ac.aggregate.innerHTML=Q!==true?Q:aa}}});var H=I.canvas.getSize(),L=G.Margin;if(M){I.config.offsetX=H.width/2-L.left-(G.showLabels&&(G.labelOffset+G.Label.size));I.config.offsetY=(L.bottom-L.top)/2}else{I.config.offsetY=-H.height/2+L.bottom+(G.showLabels&&(G.labelOffset+G.Label.size));I.config.offsetX=(L.right-L.left)/2}this.delegate=I;this.canvas=this.delegate.canvas},loadJSON:function(T){if(this.busy){return}this.busy=true;var Q=e.time(),L=[],S=this.delegate,W=e.splat(T.label),P=e.splat(T.color||this.colors),U=this.config,F=!!U.type.split(":")[1],I=U.animate,H=U.orientation=="horizontal",J=this;for(var R=0,G=T.values,N=G.length;RI?G:I});return G},setBarType:function(F){this.config.type=F;this.delegate.config.Node.type="barchart-"+F.split(":")[0]},normalizeDims:function(){var P=this.delegate.graph.getNode(this.delegate.root),K=0;P.eachAdjacency(function(){K++});var M=this.getMaxValue()||1,S=this.delegate.canvas.getSize(),I=this.config,L=I.Margin,Q=L.left+L.right,J=L.top+L.bottom,G=I.orientation=="horizontal",F=(S[G?"height":"width"]-(G?J:Q)-(K-1)*I.barsOffset)/K,H=I.animate,R=S[G?"width":"height"]-(G?Q:J)-(!G&&I.showAggregates&&(I.Label.size+I.labelOffset))-(I.showLabels&&(I.Label.size+I.labelOffset)),O=G?"height":"width",N=G?"width":"height";this.delegate.graph.eachNode(function(W){var V=0,T=[];e.each(W.getData("valueArray"),function(X){V+=+X;T.push(0)});W.setData(O,F);if(H){W.setData(N,V*R/M,"end");W.setData("dimArray",e.map(W.getData("valueArray"),function(X){return X*R/M}),"end");var U=W.getData("dimArray");if(!U){W.setData("dimArray",T)}}else{W.setData(N,V*R/M);W.setData("dimArray",e.map(W.getData("valueArray"),function(X){return X*R/M}))}})}});q.PieChart={$extend:true,animate:true,offset:25,sliceOffset:0,labelOffset:3,type:"stacked",hoveredColor:"#9fd4ff",Events:{enable:false,onClick:e.empty},Tips:{enable:false,onShow:e.empty,onHide:e.empty},showLabels:true,resizeLabels:false,updateHeights:false};i.Radial=new v({compute:function(G){var H=e.splat(G||["current","start","end"]);h.compute(this.graph,H,this.config);this.graph.computeLevels(this.root,0,"ignore");var F=this.createLevelDistanceFunc();this.computeAngularWidths(H);this.computePositions(H,F)},computePositions:function(M,J){var O=M;var N=this.graph;var K=N.getNode(this.root);var L=this.parent;var F=this.config;for(var H=0,G=O.length;HS[ai]?ah:S[ai]):ah}P.push(af)},"ignore");if(L&&L.id==T.id&&P.length>0&&P[0].dist){P.sort(function(af,ae){return(af.dist>=ae.dist)-(af.dist<=ae.dist)})}for(var V=0,X=P.length;VM/2&&I.theta<3*M/2);var S=P?I.theta+M:I.theta;if(P){T-=Math.abs(Math.cos(I.theta)*H.width);R+=Math.sin(I.theta)*H.width}else{if(L.id==this.viz.root){T-=H.width/2}}}V.save();V.translate(T,R);V.rotate(S);V.fillText(L.name,0,0);V.restore()}});F.Label.SVG=new v({Implements:g.Label.SVG,initialize:function(G){this.viz=G},placeLabel:function(U,J,L){var Q=J.pos.getc(true),T=this.viz,H=this.viz.canvas;var M=H.getSize();var I={x:Math.round(Q.x+M.width/2),y:Math.round(Q.y+M.height/2)};U.setAttribute("x",I.x);U.setAttribute("y",I.y);var N=U.getBBox();if(N){var S=U.getAttribute("x");var P=U.getAttribute("y");var G=J.pos.getp(true);var K=Math.PI;var O=(G.theta>K/2&&G.theta<3*K/2);if(O){U.setAttribute("x",S-N.width);U.setAttribute("y",P-N.height)}else{if(J.id==T.root){U.setAttribute("x",S-N.width/2)}}var R=O?G.theta+K:G.theta;if(J._depth){U.setAttribute("transform","rotate("+R*360/(2*K)+" "+S+" "+P+")")}}L.onPlaceLabel(U,J)}});F.Label.HTML=new v({Implements:g.Label.HTML,initialize:function(G){this.viz=G},placeLabel:function(P,J,L){var N=J.pos.clone(),H=this.viz.canvas,O=J.getData("height"),K=((O||J._depth==0)?O:this.viz.config.levelDistance)/2,M=H.getSize();N.rho+=K;N=N.getc(true);var I={x:Math.round(N.x+M.width/2),y:Math.round(N.y+M.height/2)};var G=P.style;G.left=I.x+"px";G.top=I.y+"px";G.display=this.fitsInCanvas(I,H)?"":"none";L.onPlaceLabel(P,J)}});F.Plot.NodeTypes=new v({none:{render:e.empty,contains:e.lambda(false),anglecontains:function(K,M){var J=K.getData("span")/2,H=K.pos.theta;var I=H-J,G=H+J;if(I<0){I+=Math.PI*2}var L=Math.atan2(M.y,M.x);if(L<0){L+=Math.PI*2}if(I>G){return(L>I&&L<=Math.PI*2)||LI&&L=I*L)&&(H<=(I*L+K))}return false}},"gradient-multipie":{render:function(J,G){var O=G.getCtx();var N=J.getData("height");var K=N?N:this.config.levelDistance;var H=O.createRadialGradient(0,0,J.getPos().rho,0,0,J.getPos().rho+K);var M=e.hexToRgb(J.getData("color")),L=[];e.each(M,function(P){L.push(parseInt(P*0.5,10))});var I=e.rgbToHex(L);H.addColorStop(0,I);H.addColorStop(1,J.getData("color"));O.fillStyle=H;this.nodeTypes.multipie.render.call(this,J,G)},contains:function(G,H){return this.nodeTypes.multipie.contains.call(this,G,H)}},"gradient-pie":{render:function(L,I){var G=I.getCtx();var M=G.createRadialGradient(0,0,0,0,0,L.getPos().rho);var K=e.hexToRgb(L.getData("color")),H=[];e.each(K,function(N){H.push(parseInt(N*0.5,10))});var J=e.rgbToHex(H);M.addColorStop(1,J);M.addColorStop(0,L.getData("color"));G.fillStyle=M;this.nodeTypes.pie.render.call(this,L,I)},contains:function(G,H){return this.nodeTypes.pie.contains.call(this,G,H)}}});F.Plot.EdgeTypes=new v({none:e.empty,line:{render:function(G,H){var J=G.nodeFrom.pos.getc(true),I=G.nodeTo.pos.getc(true);this.edgeHelper.line.render(J,I,H)},contains:function(G,J){var I=G.nodeFrom.pos.getc(true),H=G.nodeTo.pos.getc(true);return this.edgeHelper.line.contains(I,H,J,this.edge.epsilon)}},arrow:{render:function(H,I){var M=H.nodeFrom.pos.getc(true),L=H.nodeTo.pos.getc(true),K=H.getData("dim"),J=H.data.$direction,G=(J&&J.length>1&&J[0]!=H.nodeFrom.id);this.edgeHelper.arrow.render(M,L,K,G,I)},contains:function(G,J){var I=G.nodeFrom.pos.getc(true),H=G.nodeTo.pos.getc(true);return this.edgeHelper.arrow.contains(I,H,J,this.edge.epsilon)}},hyperline:{render:function(G,H){var K=G.nodeFrom.pos.getc(),J=G.nodeTo.pos.getc(),I=Math.max(K.norm(),J.norm());this.edgeHelper.hyperline.render(K.$scale(1/I),J.$scale(1/I),I,H)},contains:e.lambda(false)}})})($jit.Sunburst);$jit.Sunburst.Plot.NodeTypes.implement({"piechart-stacked":{render:function(ad,J){var ac=ad.pos.getp(true),L=ad.getData("dimArray"),ab=ad.getData("valueArray"),P=ad.getData("colorArray"),I=P.length,V=ad.getData("stringArray"),Y=ad.getData("span")/2,T=ad.pos.theta,O=T-Y,S=T+Y,aa=new d;var W=J.getCtx(),U={},R=ad.getData("gradient"),M=ad.getData("border"),ai=ad.getData("config"),ar=ai.showLabels,ah=ai.resizeLabels,ak=ai.Label;var an=ai.sliceOffset*Math.cos((O+S)/2);var N=ai.sliceOffset*Math.sin((O+S)/2);if(P&&L&&V){for(var ao=0,al=L.length,F=0,ag=0;ao>0}),H=e.rgbToHex(af);am.addColorStop(0,ap);am.addColorStop(0.5,ap);am.addColorStop(1,H);W.fillStyle=am}aa.rho=F+ai.sliceOffset;aa.theta=O;var aq=aa.getc(true);aa.theta=S;var X=aa.getc(true);aa.rho+=K;var at=aa.getc(true);aa.theta=O;var Z=aa.getc(true);W.beginPath();W.arc(an,N,F+0.01,O,S,false);W.arc(an,N,F+K+0.01,S,O,true);W.fill();if(M&&M.name==V[ao]){U.acum=F;U.dimValue=L[ao];U.begin=O;U.end=S}F+=(K||0);ag+=(ab[ao]||0)}if(M){W.save();W.globalCompositeOperation="source-over";W.lineWidth=2;W.strokeStyle=M.color;var aj=O>0;Q=Q<+ah?+ah:Q;W.font=ak.style+" "+Q+"px "+ak.family;W.textBaseline="middle";W.textAlign="center";aa.rho=F+ai.labelOffset+ai.sliceOffset;aa.theta=ad.pos.theta;var au=aa.getc(true);W.fillText(ad.name,au.x,au.y);W.restore()}}},contains:function(I,M){if(this.nodeTypes.none.anglecontains.call(this,I,M)){var O=Math.sqrt(M.x*M.x+M.y*M.y);var F=this.config.levelDistance,L=I._depth;var G=I.getData("config");if(O<=F*L+G.sliceOffset){var P=I.getData("dimArray");for(var K=0,J=P.length,N=G.sliceOffset;K=N&&O<=N+H){return{name:I.getData("stringArray")[K],color:I.getData("colorArray")[K],value:I.getData("valueArray")[K],label:I.name}}N+=H}}return false}return false}}});$jit.PieChart=new v({sb:null,colors:["#416D9C","#70A35E","#EBB056","#C74243","#83548B","#909291","#557EAA"],selected:{},busy:false,initialize:function(F){this.controller=this.config=e.merge(q("Canvas","PieChart","Label"),{Label:{type:"Native"}},F);this.initializeViz()},initializeViz:function(){var G=this.config,K=this;var F=G.type.split(":")[0];var J=new $jit.Sunburst({injectInto:G.injectInto,width:G.width,height:G.height,useCanvas:G.useCanvas,withLabels:G.Label.type!="Native",Label:{type:G.Label.type},Node:{overridable:true,type:"piechart-"+F,width:1,height:1},Edge:{type:"none"},Tips:{enable:G.Tips.enable,type:"Native",force:true,onShow:function(O,N,L){var M=L;G.Tips.onShow(O,M,N)}},Events:{enable:true,type:"Native",onClick:function(N,O,L){if(!G.Events.enable){return}var M=O.getContains();G.Events.onClick(M,O,L)},onMouseMove:function(N,O,L){if(!G.hoveredColor){return}if(N){var M=O.getContains();K.select(N.id,M.name,M.index)}else{K.select(false,false,false)}}},onCreateLabel:function(O,N){var L=G.Label;if(G.showLabels){var M=O.style;M.fontSize=L.size+"px";M.fontFamily=L.family;M.color=L.color;M.textAlign="center";O.innerHTML=N.name}},onPlaceLabel:function(ab,V){if(!G.showLabels){return}var P=V.pos.getp(true),S=V.getData("dimArray"),Y=V.getData("span")/2,Q=V.pos.theta,aa=Q-Y,M=Q+Y,ad=new d;var U=G.showLabels,O=G.resizeLabels,R=G.Label;if(S){for(var Z=0,W=S.length,X=0;Z>0;L=L<+O?+O:L;ab.style.fontSize=L+"px";ad.rho=X+G.labelOffset+G.sliceOffset;ad.theta=(aa+M)/2;var P=ad.getc(true);var N=K.canvas.getSize();var T={x:Math.round(P.x+N.width/2),y:Math.round(P.y+N.height/2)};ab.style.left=T.x+"px";ab.style.top=T.y+"px"}}});var I=J.canvas.getSize(),H=Math.min;J.config.levelDistance=H(I.width,I.height)/2-G.offset-G.sliceOffset;this.delegate=J;this.canvas=this.delegate.canvas;this.canvas.getCtx().globalCompositeOperation="lighter"},loadJSON:function(T){var Q=e.time(),K=[],S=this.delegate,W=e.splat(T.label),M=W.length,P=e.splat(T.color||this.colors),H=P.length,U=this.config,F=!!U.type.split(":")[1],I=U.animate,O=M==1;for(var R=0,G=T.values,N=G.length;RH?F:H});return F},normalizeDims:function(){var G=this.delegate.graph.getNode(this.delegate.root),F=0;G.eachAdjacency(function(){F++});var K=this.getMaxValue()||1,J=this.config,H=J.animate,I=this.delegate.config.levelDistance;this.delegate.graph.eachNode(function(P){var O=0,L=[];e.each(P.getData("valueArray"),function(Q){O+=+Q;L.push(1)});var N=(L.length==1)&&!J.updateHeights;if(H){P.setData("dimArray",e.map(P.getData("valueArray"),function(Q){return N?I:(Q*I/K)}),"end");var M=P.getData("dimArray");if(!M){P.setData("dimArray",L)}}else{P.setData("dimArray",e.map(P.getData("valueArray"),function(Q){return N?I:(Q*I/K)}))}P.setData("normalizedDim",O/K)})}});i.TM={};i.TM.SliceAndDice=new v({compute:function(K){var G=this.graph.getNode(this.clickedNode&&this.clickedNode.id||this.root);this.controller.onBeforeCompute(G);var I=this.canvas.getSize(),H=this.config,J=I.width,F=I.height;this.graph.computeLevels(this.root,0,"ignore");G.getPos(K).setc(-J/2,-F/2);G.setData("width",J,K);G.setData("height",F+H.titleHeight,K);this.computePositions(G,G,this.layout.orientation,K);this.controller.onAfterCompute(G)},computePositions:function(P,N,Y,H){var W=0;P.eachSubnode(function(aa){W+=aa.getData("area",H)},"ignore");var Z=this.config,K=Z.offset,T=P.getData("width",H),R=Math.max(P.getData("height",H)-Z.titleHeight,0),G=P==N?1:(N.getData("area",H)/W);var S,Q,V,L,J,O,M;var X=(Y=="h");if(X){Y="v";S=R;Q=T*G;V="height";L="y";J="x";O=Z.titleHeight;M=0}else{Y="h";S=R*G;Q=T;V="width";L="x";J="y";O=0;M=Z.titleHeight}var F=N.getPos(H);N.setData("width",Q,H);N.setData("height",S,H);var U=0,I=this;N.eachSubnode(function(ab){var aa=ab.getPos(H);aa[L]=U+F[L]+O;aa[J]=F[J]+M;I.computePositions(N,ab,Y,H);U+=ab.getData(V,H)},"ignore")}});i.TM.Area={compute:function(F){F=F||"current";var L=this.graph.getNode(this.clickedNode&&this.clickedNode.id||this.root);this.controller.onBeforeCompute(L);var H=this.config,O=this.canvas.getSize(),G=O.width,N=O.height,M=H.offset,I=G-M,K=N-M;this.graph.computeLevels(this.root,0,"ignore");L.getPos(F).setc(-G/2,-N/2);L.setData("width",G,F);L.setData("height",N,F);var J={top:-N/2+H.titleHeight+M/2,left:-G/2+M/2,width:I,height:K-H.titleHeight};this.computePositions(L,J,F);this.controller.onAfterCompute(L)},computeDim:function(J,K,M,I,H,F){if(J.length+K.length==1){var G=(J.length==1)?J:K;this.layoutLast(G,M,I,F);return}if(J.length>=2&&K.length==0){K=[J.shift()]}if(J.length==0){if(K.length>0){this.layoutRow(K,M,I,F)}return}var L=J[0];if(H(K,M)>=H([L].concat(K),M)){this.computeDim(J.slice(1),K.concat([L]),M,I,H,F)}else{var N=this.layoutRow(K,M,I,F);this.computeDim(J,[],N.dim,N,H,F)}},worstAspectRatio:function(F,N){if(!F||F.length==0){return Number.MAX_VALUE}var G=0,O=0,J=Number.MAX_VALUE;for(var L=0,K=F.length;LH?O:H}var M=N*N,I=G*G;return Math.max(M*O/I,I/(M*J))},avgAspectRatio:function(J,G){if(!J||J.length==0){return Number.MAX_VALUE}var L=0;for(var H=0,F=J.length;HI?G/I:I/G}return L/F},layoutLast:function(G,F,J,I){var H=G[0];H.getPos(I).setc(J.left,J.top);H.setData("width",J.width,I);H.setData("height",J.height,I)}};i.TM.Squarified=new v({Implements:i.TM.Area,computePositions:function(J,M,G){var I=this.config,O=Math.max;if(M.width>=M.height){this.layout.orientation="h"}else{this.layout.orientation="v"}var F=J.getSubnodes([1,1],"ignore");if(F.length>0){this.processChildrenLayout(J,F,M,G);for(var L=0,K=F.length;L0){this.processChildrenLayout(J,F,M,G);for(var L=0,K=F.length;L0){if(!K[0].histoPos||!K[0].histoPos[G+1]){M=$jit.util.map(K,function(Q){var R=Geometry.randPointInPolygon(J);if(Q.data&&Q.data.$area){R.area=Q.data.$area}return R});M=O[O.config.centroidType](M,J);$jit.util.each(M,function(R,Q){if(!K[Q].histoPos){K[Q].histoPos=[]}K[Q].histoPos[G+1]=R})}M=$jit.util.map(K,function(Q){return Q.histoPos[G+1]});P=Geometry.voronoi(M,J);$jit.util.each(K,function(T,S){var R=P[S];var Q=R.slice(0);if(Geometry.area(R)<0){R.reverse()}if(L){Q=Geometry.offsetConvex(R,-L*2);R=Geometry.offsetConvex(R,-L*0.5);T.offset=L}T.setData("vertices",R,F);O.computePositions(T,Q,F,G+1)})}},centroid:function(I,H){var G=2,F;while(G>0.001){F=Geometry.voronoi(I,H);G=0;I=F.map(function(K,J){var L=Geometry.centroid(K);G+=Geometry.dist2(L,I[J]);return L})}return I},doLayoutPressure:function(){var G=this,F=G.graph.getNode(G.clickedNode&&G.clickedNode.id||G.root);F.eachNode(function(){})},weightedCentroid:function(I,G){var O=[];var H=2,J,M=Geometry.area(G),F=0,L;e.each(I,function(P,Q){F+=P.area});L=M/F;J=Geometry.voronoi(I,G);e.each(J,function(Q,P){O[P]=I[P].area*L/Geometry.area(Q)});var N=0,K=0;e.each(O,function(Q,P){N+=Q;K+=Q*Q});console.log("from "+(K-N*N/O.length)/O.length);while(H>0.001){J=Geometry.voronoi(I,G);e.each(J,function(Q,P){O[P]=I[P].area*L/Geometry.area(Q)});H=0;I=J.map(function(Q,P){var S=x(0,0),R=0;e.each(Q,function(U,W){var X=[I[P],U,Q[W+1]||Q[0]],V=(U.attached)?O[U.attached[0]]:1,T=Geometry.area(X)*Math.exp((O[P]-V)*2);R+=T;S.$add(U.add(X[2]).scale(0.5*T))});S.$scale(1/R);S.area=I[P].area;H+=Geometry.dist(S,I[P]);return S})}var N=0,K=0;e.each(O,function(Q,P){N+=Q;K+=Q*Q});console.log("to "+(K-N*N/O.length)/O.length);return I},byArea:function(L,J){L=this.centroid(L,J);var H=0,G=0,F,K,F;$jit.util.each(L,function(M){H+=M.area});H=Geometry.area(J)/H;for(;G<100;G++){F=Geometry.voronoi(L,J);for(var I=0;IO){O=R}});var H=this.graph.getNode(this.clickedNode&&this.clickedNode.id||M.id);var G=Math.min(O,L-1);var K=H._depth;if(this.layout.horizontal()){this.computeSubtree(H,-F/2,-P/2,F/(G+1),P,K,G,N)}else{this.computeSubtree(H,-F/2,-P/2,F,P/(G+1),K,G,N)}},computeSubtree:function(N,P,M,F,S,L,H,O){N.getPos(O).setc(P,M);N.setData("width",F,O);N.setData("height",S,O);var J,R=0,Q=0;var G=g.Util.getSubnodes(N,[1,1],"ignore");if(!G.length){return}e.each(G,function(T){Q+=T.getData("dim")});for(var K=0,I=G.length;K>0}));R.addColorStop(0,J);R.addColorStop(1,N);S.fillStyle=R}if(K){S.strokeStyle=K;S.lineWidth=3}S.fillRect(O,M,Math.max(0,F-L),Math.max(0,Q-L));K&&S.strokeRect(P.x,P.y,F,Q)},contains:function(H,J){if(this.viz.clickedNode&&!$jit.Graph.Util.isDescendantOf(H,this.viz.clickedNode.id)){return false}var I=H.pos.getc(true),G=H.getData("width"),F=H.getData("height");return this.nodeHelper.rectangle.contains({x:I.x+G/2,y:I.y+F/2},J,G,F)}}});$jit.Icicle.Plot.EdgeTypes=new v({none:e.empty});var A=new v({com:[0,0],children:[null,null,null,null],hasChildren:false,mass:null,fItem:null});var n=new v({maxNodes:50000,nodes:null,setup:function(){this.nodes=new Array()},getQuadTreeNode:function(){if(this.nodes.length>0){return this.nodes.pop()}else{return new A()}},reclaim:function(F){F.mass=0;F.com[0]=0;F.com[1]=0;F.fItem=null;F.hasChildren=false;F.children=[null,null,null,null];if(this.nodes.length=L?1:0)+(M>=K?2:0);if(I.children[J]==null){I.children[J]=this.factory.getQuadTreeNode();I.hasChildren=true}if(J==1||J==3){H=L}else{F=L}if(J>1){O=K}else{N=K}this.insert(G,I.children[J],H,O,F,N)},isSameLocation:function(I,H){var G=Math.abs(I.location[0]-H.location[0]);var F=Math.abs(I.location[1]-H.location[1]);return(G<0.01&&F<0.01)},insert:function(K,L,H,J,G,I){if(L.hasChildren){this.insertHelper(K,L,H,J,G,I)}else{if(L.fItem!=null){if(this.isSameLocation(L.fItem,K)){this.insertHelper(K,L,H,J,G,I)}else{var F=L.fItem;L.fItem=null;this.insertHelper(F,L,H,J,G,I);this.insertHelper(K,L,H,J,G,I)}}else{L.fItem=K}}},calcMass:function(I){var H=0;var F=0;I.mass=0;if(I.hasChildren){for(var G=0;GF){F=M}if(J>K){K=J}}var O=F-G;var N=K-L;if(O>N){K=L+O}else{F=G+N}this.setBounds(G,L,F,K);for(var I=0;I0&&F>this.params[this.MIN_DISTANCE];if((!I.hasChildren&&I.fItem!=R)||(!N&&(G-H)/F1?K:O),(J==1||J==3?G:L),(J>1?M:K))}}if(P){return}if(I.fItem!=null&&I.fItem!=R){var Q=this.params[this.GRAVITATIONAL_CONST]*R.mass*I.fItem.mass/(F*F*F);R.force[0]+=Q*T;R.force[1]+=Q*S}}}}});var o=new v({pnames:["SpringCoefficient","DefaultSpringLength"],DEFAULT_SPRING_COEFF:0.0001,DEFAULT_MAX_SPRING_COEFF:0.001,DEFAULT_MIN_SPRING_COEFF:0.00001,DEFAULT_SPRING_LENGTH:50,DEFAULT_MIN_SPRING_LENGTH:0,DEFAULT_MAX_SPRING_LENGTH:200,SPRING_COEFF:0,SPRING_LENGTH:1,params:null,minValues:null,maxValues:null,setup:function(){this.params=[this.DEFAULT_SPRING_COEFF,this.DEFAULT_SPRING_LENGTH];this.minValues=[this.DEFAULT_MIN_SPRING_COEFF,this.DEFAULT_MIN_SPRING_LENGTH];this.maxValues=[this.DEFAULT_MAX_SPRING_COEFF,this.DEFAULT_MAX_SPRING_LENGTH]},getForce:function(R){var L=R.item1;var K=R.item2;var I=(R.length<0?this.params[this.SPRING_LENGTH]:R.length);var H=L.location[0];var O=L.location[1];var G=K.location[0];var N=K.location[1];var Q=G-H;var P=N-O;var F=Math.sqrt(Q*Q+P*P);if(F==0){Q=(Math.random()-0.5)/50;P=(Math.random()-0.5)/50;F=Math.sqrt(Q*Q+P*P)}var M=F-I;var J=(R.coeff<0?this.params[this.SPRING_COEFF]:R.coeff)*M/F;L.force[0]+=J*Q;L.force[1]+=J*P;K.force[0]+=-J*Q;K.force[1]+=-J*P},init:function(){}});var w=new v({pnames:["DragCoefficient"],DEFAULT_DRAG_COEFF:0.01,DEFAULT_MIN_DRAG_COEFF:0,DEFAULT_MAX_DRAG_COEFF:0.1,DRAG_COEFF:0,params:null,minValues:null,maxValues:null,setup:function(){this.params=[this.DEFAULT_DRAG_COEFF];this.minValues=[this.DEFAULT_MIN_DRAG_COEFF];this.maxValues=[this.DEFAULT_MAX_DRAG_COEFF]},getForce:function(F){F.force[0]-=this.params[this.DRAG_COEFF]*F.velocity[0];F.force[1]-=this.params[this.DRAG_COEFF]*F.velocity[1]},init:function(){}});var y=new v({integrate:function(O,G){var H=O.speedLimit;var N,M,P,L;var J,I;for(var K=0;KH){N=H*N/P;M=H*M/P}J[1][0]=G*N;J[1][1]=G*M;I[1][0]=L*Q.force[0];I[1][1]=L*Q.force[1];Q.location[0]=Q.plocation[0]+0.5*J[1][0];Q.location[1]=Q.plocation[1]+0.5*J[1][1]}O.accumulate();for(var K=0;KH){N=H*N/P;M=H*M/P}J[2][0]=G*N;J[2][1]=G*M;I[2][0]=L*Q.force[0];I[2][1]=L*Q.force[1];Q.location[0]=Q.plocation[0]+0.5*J[2][0];Q.location[1]=Q.plocation[1]+0.5*J[2][1]}O.accumulate();for(var K=0;KH){N=H*N/P;M=H*M/P}J[3][0]=G*N;J[3][1]=G*M;I[3][0]=L*Q.force[0];I[3][1]=L*Q.force[1];Q.location[0]=F[0]+(J[0][0]+J[3][0])/6+(J[1][0]+J[2][0])/3;Q.location[1]=F[1]+(J[0][1]+J[3][1])/6+(J[1][1]+J[2][1])/3;N=(I[0][0]+I[3][0])/6+(I[1][0]+I[2][0])/3;M=(I[0][1]+I[3][1])/6+(I[1][1]+I[2][1])/3;P=Math.sqrt(N*N+M*M);if(P>H){N=H*N/P;M=H*M/P}Q.velocity[0]+=N;Q.velocity[1]+=M}}});var a=new v({speedLimit:1,iflen:0,sflen:0,integrator:null,items:null,springs:null,iforces:null,sforces:null,setup:function(){this.items=new Array();this.springs=new Array();this.iforces=new Array();this.sforces=new Array();this.integrator=new y()},accumulate:function(){for(var G=0;G=F){var Z=0;var ah=0;var Y=I.width/2;var ag=I.height/2;U.eachNode(function(aj){e.each(G,function(ap){var al=aj.forceItem.location[0];var ar=aj.forceItem.location[1];var ak=aj.getData("dim")*2;var ao=aj.getData("dim")*2;var am=aj.disp[ap];var an=am.norm()||1;var aq=aj.getPos(ap);aq.x=al;aq.y=ar})});M.onComplete();var X=-Number.MAX_VALUE;var ad=Number.MAX_VALUE;var W=-Number.MAX_VALUE;var ac=Number.MAX_VALUE;U.eachNode(function(aj){e.each(G,function(al){var ak=aj.getPos(al);if(ak.x>X){X=ak.x}if(ak.xW){W=ak.y}if(ak.y=0){ab=Math.ceil(X-ad)}else{ab=Math.ceil(X+Math.abs(ad))}}if(W<0){ai=Math.ceil(Math.floor(Math.abs(ac))-Math.floor(Math.abs(W)))}else{if(ac>=0){ai=Math.ceil(W-ac)}else{ai=Math.ceil(W+Math.abs(ac))}}var Y=I.width/2;var ag=I.height/2;U.eachNode(function(aj){e.each(G,function(am){var ak=aj.getPos(am);var al=aj.getData("dim");if(ad<0){ak.x=((ak.x+Math.abs(ad))*(I.width/ab))-(I.width/2)}else{ak.x=((ak.x-ad)*(I.width/ab))-(I.width/2)}if(ak.x<=-Y+al){ak.x=-Y+(al*2)}if(ak.x>=Y-al){ak.x=Y-(al*2)}if(ac<0){ak.y=((ak.y+Math.abs(ac))*(I.height/ai))-(I.height/2)}else{ak.y=((ak.y-ac)*(I.height/ai))-(I.height/2)}if(ak.y<=-ag+al){ak.y=-ag+(al*2)}if(ak.y>=ag-al){ak.y=ag-(al*2)}})});return}}M.onStep(Math.round(K/(F-1)*100));setTimeout(N,1)})()}});$jit.ForceDirected=new v({Implements:[f,t,i.ForceDirected],initialize:function(G){var F=$jit.ForceDirected;var H={iterations:50,levelDistance:50};this.controller=this.config=e.merge(q("Canvas","Node","Edge","Fx","Tips","NodeStyles","Events","Navigation","Controller","Label"),H,G);var I=this.config;if(I.useCanvas){this.canvas=I.useCanvas;this.config.labelContainer=this.canvas.id+"-label"}else{if(I.background){I.background=e.merge({type:"Circles"},I.background)}this.canvas=new p(this,I);this.config.labelContainer=(typeof I.injectInto=="string"?I.injectInto:I.injectInto.id)+"-label"}this.graphOptions={klass:u,Node:{selected:false,exist:true,drawn:true}};this.graph=new g(this.graphOptions,this.config.Node,this.config.Edge);this.labels=new F.Label[I.Label.type](this);this.fx=new F.Plot(this,F);this.op=new F.Op(this);this.json=null;this.busy=false;this.initializeExtras()},refresh:function(){this.compute();this.plot()},reposition:function(){this.compute("end")},computeIncremental:function(F){F=e.merge({iter:20,property:"end",onStep:e.empty,onComplete:e.empty},F||{});this.config.onBeforeCompute(this.graph.getNode(this.root));this.compute(F.property,F)},computePrefuse:function(F){F=e.merge({iter:20,property:"end",onStep:e.empty,onComplete:e.empty},F||{});this.config.onBeforeCompute(this.graph.getNode(this.root));this.computeFast(F.property,F)},plot:function(){this.fx.plot()},animate:function(F){this.fx.animate(e.merge({modes:["linear"]},F||{}))}});$jit.ForceDirected.$extend=true;(function(F){F.Op=new v({Implements:g.Op});F.Plot=new v({Implements:g.Plot});F.Label={};F.Label.Native=new v({Implements:g.Label.Native});F.Label.SVG=new v({Implements:g.Label.SVG,initialize:function(G){this.viz=G},placeLabel:function(Q,K,L){var O=K.pos.getc(true),H=this.viz.canvas,I=H.translateOffsetX,G=H.translateOffsetY,P=H.scaleOffsetX,N=H.scaleOffsetY,M=H.getSize();var J={x:Math.round(O.x*P+I+M.width/2),y:Math.round(O.y*N+G+M.height/2)};Q.setAttribute("x",J.x);Q.setAttribute("y",J.y);L.onPlaceLabel(Q,K)}});F.Label.HTML=new v({Implements:g.Label.HTML,initialize:function(G){this.viz=G},placeLabel:function(R,L,M){var P=L.pos.getc(true),I=this.viz.canvas,J=I.translateOffsetX,H=I.translateOffsetY,Q=I.scaleOffsetX,O=I.scaleOffsetY,N=I.getSize();var K={x:Math.round(P.x*Q+J+N.width/2),y:Math.round(P.y*O+H+N.height/2)};var G=R.style;G.left=K.x+"px";G.top=K.y+"px";G.display=this.fitsInCanvas(K,I)?"":"none";M.onPlaceLabel(R,L)}});F.Plot.NodeTypes=new v({none:{render:e.empty,contains:e.lambda(false)},circle:{render:function(H,G){var J=H.pos.getc(true),I=H.getData("dim");this.nodeHelper.circle.render("fill",J,I,G)},contains:function(G,J){var I=G.pos.getc(true),H=G.getData("dim");return this.nodeHelper.circle.contains(I,J,H)}},ellipse:{render:function(J,H){var K=J.pos.getc(true),I=J.getData("width"),G=J.getData("height");this.nodeHelper.ellipse.render("fill",K,I,G,H)},contains:function(I,K){var J=I.pos.getc(true),H=I.getData("width"),G=I.getData("height");return this.nodeHelper.ellipse.contains(J,K,H,G)}},square:{render:function(H,G){var J=H.pos.getc(true),I=H.getData("dim");this.nodeHelper.square.render("fill",J,I,G)},contains:function(G,J){var I=G.pos.getc(true),H=G.getData("dim");return this.nodeHelper.square.contains(I,J,H)}},rectangle:{render:function(J,H){var K=J.pos.getc(true),I=J.getData("width"),G=J.getData("height");this.nodeHelper.rectangle.render("fill",K,I,G,H)},contains:function(I,K){var J=I.pos.getc(true),H=I.getData("width"),G=I.getData("height");return this.nodeHelper.rectangle.contains(J,K,H,G)}},triangle:{render:function(H,G){var J=H.pos.getc(true),I=H.getData("dim");this.nodeHelper.triangle.render("fill",J,I,G)},contains:function(G,J){var I=G.pos.getc(true),H=G.getData("dim");return this.nodeHelper.triangle.contains(I,J,H)}},star:{render:function(H,G){var J=H.pos.getc(true),I=H.getData("dim");this.nodeHelper.star.render("fill",J,I,G)},contains:function(G,J){var I=G.pos.getc(true),H=G.getData("dim");return this.nodeHelper.star.contains(I,J,H)}},roundedRectangle:{render:function(K,I){var L=K.pos.getc(true),J=K.getData("width"),H=K.getData("height"),G=K.getData("radius");this.nodeHelper.roundedRectangle.render("fill",L,J,H,G,I)},contains:function(J,L){var K=J.pos.getc(true),I=J.getData("width"),H=J.getData("height"),G=J.getData("radius");return this.nodeHelper.roundedRectangle.contains(K,L,I,H,G)}}});F.Plot.EdgeTypes=new v({none:e.empty,line:{render:function(G,H){var J=G.nodeFrom.pos.getc(true),I=G.nodeTo.pos.getc(true);this.edgeHelper.line.render(J,I,H)},contains:function(G,J){var I=G.nodeFrom.pos.getc(true),H=G.nodeTo.pos.getc(true);return this.edgeHelper.line.contains(I,H,J,this.edge.epsilon)}},arrow:{render:function(H,I){var M=H.nodeFrom.pos.getc(true),L=H.nodeTo.pos.getc(true),K=H.getData("dim"),J=H.data.$direction,G=(J&&J.length>1&&J[0]!=H.nodeFrom.id);this.edgeHelper.arrow.render(M,L,K,G,I)},contains:function(G,J){var I=G.nodeFrom.pos.getc(true),H=G.nodeTo.pos.getc(true);return this.edgeHelper.arrow.contains(I,H,J,this.edge.epsilon)}}})})($jit.ForceDirected);$jit.TM={};var E=$jit.TM;$jit.TM.$extend=true;E.Base={layout:{orientation:"h",vertical:function(){return this.orientation=="v"},horizontal:function(){return this.orientation=="h"},change:function(){this.orientation=this.vertical()?"h":"v"}},initialize:function(F){var G={orientation:"h",titleHeight:13,offset:2,levelsToShow:0,labelsToShow:[0,-1],constrained:false,animate:false,Node:{type:"rectangle",overridable:true,width:3,height:3,color:"#444",props:"node-property:width:height"},Label:{textAlign:"center",textBaseline:"top"},Edge:{type:"none"},duration:700,fps:45};this.controller=this.config=e.merge(q("Canvas","Node","Edge","Fx","Controller","Tips","NodeStyles","Events","Navigation","Label"),G,F);this.layout.orientation=this.config.orientation;var H=this.config;if(H.useCanvas){this.canvas=H.useCanvas;this.config.labelContainer=this.canvas.id+"-label"}else{if(H.background){H.background=e.merge({type:"Circles"},H.background)}this.canvas=new p(this,H);this.config.labelContainer=(typeof H.injectInto=="string"?H.injectInto:H.injectInto.id)+"-label"}this.graphOptions={klass:u,Node:{selected:false,exist:true,drawn:true}};this.graph=new g(this.graphOptions,this.config.Node,this.config.Edge);this.labels=new E.Label[H.Label.type](this);this.fx=new E.Plot(this);this.op=new E.Op(this);this.group=new E.Group(this);this.geom=new E.Geom(this);this.clickedNode=null;this.busy=false;this.initializeExtras()},refresh:function(){if(this.busy){return}this.busy=true;var G=this;if(this.config.animate){this.compute("end");this.geom.setRightLevelToShow(this.graph.getNode(this.clickedNode&&this.clickedNode.id||this.root));this.fx.animate(e.merge(this.config,{modes:["linear",this.config.Node.props],onComplete:function(){G.busy=false}}))}else{var F=this.config.Label.type;if(F!="Native"){this.graph.eachNode(function(H){G.labels.hideLabel(H,false)})}this.busy=false;this.compute();this.geom.setRightLevelToShow(this.graph.getNode(this.clickedNode&&this.clickedNode.id||this.root));this.plot()}},plot:function(){this.fx.plot()},leaf:function(F){return F.getSubnodes([1,1],"ignore").length==0},enter:function(L){if(this.busy){return}this.busy=true;var H=this,G=this.config,J=this.graph,F=L,I=this.clickedNode;var K={onComplete:function(){H.geom.setRightLevelToShow(L);if(G.request){H.compute()}if(G.animate){J.nodeList.setData("alpha",0,"end");L.eachSubgraph(function(M){M.setData("alpha",1,"end");M.selected=false},"ignore");F.selected=true;H.fx.animate({duration:H.config.duration/3,modes:["node-property:alpha"],onComplete:function(){H.clickedNode=F;H.compute("end");H.clickedNode=I;H.fx.animate({duration:2*H.config.duration/3,modes:["linear",H.config.Node.props],onComplete:function(){H.busy=false;H.clickedNode=F;H.geom.setRightLevelToShow(F)}})}})}else{H.busy=false;H.clickedNode=L;H.refresh()}}};this.geom.setRightLevelToShow(L);if(G.request){this.requestNodes(F,K)}else{K.onComplete()}},out:function(){if(this.busy){return}this.busy=true;this.events.hoveredNode=false;var J=this,H=this.config,L=this.graph,G=L.getNode(this.clickedNode&&this.clickedNode.id||this.root).getParents(),I=G[0],F=I,K=this.clickedNode;if(!I){this.busy=false;return}I.selected=true;var M={onComplete:function(){K.selected=false;J.clickedNode=I;if(H.request){J.requestNodes(I,{onComplete:function(){J.compute();J.plot();J.busy=false}})}else{J.compute();J.plot();J.busy=false}J.geom.setRightLevelToShow(I);J.plot()}};this.geom.setRightLevelToShow(I);if(H.animate){this.clickedNode=F;this.compute("end");this.clickedNode=K;this.fx.animate({duration:2*this.config.duration/3,modes:["linear",this.config.Node.props],onComplete:function(){J.clickedNode=F;F.eachSubgraph(function(N){N.setDataset(["current","end"],{alpha:[0,1]})},"ignore");K.eachSubgraph(function(N){N.setData("alpha",1)},"ignore");J.geom.setRightLevelToShow(I);J.fx.animate({duration:J.config.duration/3,modes:["node-property:alpha"],onComplete:function(){M.onComplete()}})}})}else{M.onComplete()}},requestNodes:function(H,I){var G=e.merge(this.controller,I),F=this.config.levelsToShow;if(G.request){var K=[],J=H._depth;H.eachLevel(0,F,function(M){var L=F-(M._depth-J);if(M.drawn&&!M.anySubnode()&&L>0){K.push(M);M._level=L}});this.group.requestNodes(K,G)}else{G.onComplete()}},reposition:function(){this.compute("end")}};E.Op=new v({Implements:g.Op,initialize:function(F){this.viz=F}});E.Geom=new v({Implements:g.Geom,getRightLevelToShow:function(){return this.viz.config.levelsToShow},setRightLevelToShow:function(G){var J=this.getRightLevelToShow(),I=this.viz.config.labelsToShow,F=this.viz.labels;var H={};G.eachLevel(0,false,function(L){var K=L._depth-G._depth;L._hideLabel=I[0]>=0&&K=0&&K>I[1];if(J>0&&K>J){L.drawn=false;L.exist=false;L.ignore=true;F.hideLabel(L,false)}else{L.drawn=true;L.exist=true;delete L.ignore}H[L.name]=L._hideLabel});G.drawn=true;delete G.ignore}});E.Group=new v({initialize:function(F){this.viz=F;this.canvas=F.canvas;this.config=F.config},requestNodes:function(K,J){var I=0,G=K.length,M={};var H=function(){J.onComplete()};var F=this.viz;if(G==0){H()}for(var L=0;L>0}));T.addColorStop(0,J);T.addColorStop(1,O);U.fillStyle=T}U.fillRect(P,N,F-R,S-R);if(K){U.save();U.strokeStyle=K;U.strokeRect(P,N,F-R,S-R);U.restore()}}else{if(L>0){U.fillRect(Q.x+R/2,Q.y+R/2,F-R,L-R);if(K){U.save();U.strokeStyle=K;U.strokeRect(Q.x+R/2,Q.y+R/2,F-R,S-R);U.restore()}}}},contains:function(I,K){if(this.viz.clickedNode&&!I.isDescendantOf(this.viz.clickedNode.id)||I.ignore){return false}var J=I.pos.getc(true),H=I.getData("width"),G=this.viz.leaf(I),F=G?I.getData("height"):this.config.titleHeight;return this.nodeHelper.rectangle.contains({x:J.x+H/2,y:J.y+F/2},K,H,F)}}});E.Plot.EdgeTypes=new v({none:e.empty});E.SliceAndDice=new v({Implements:[f,t,E.Base,i.TM.SliceAndDice]});E.Squarified=new v({Implements:[f,t,E.Base,i.TM.Squarified]});E.Strip=new v({Implements:[f,t,E.Base,i.TM.Strip]});$jit.RGraph=new v({Implements:[f,t,i.Radial],initialize:function(F){var G=$jit.RGraph;var H={interpolation:"linear",levelDistance:100};this.controller=this.config=e.merge(q("Canvas","Node","Edge","Fx","Controller","Tips","NodeStyles","Events","Navigation","Label"),H,F);var I=this.config;if(I.useCanvas){this.canvas=I.useCanvas;this.config.labelContainer=this.canvas.id+"-label"}else{if(I.background){I.background=e.merge({type:"Circles"},I.background)}this.canvas=new p(this,I);this.config.labelContainer=(typeof I.injectInto=="string"?I.injectInto:I.injectInto.id)+"-label"}this.graphOptions={klass:d,Node:{selected:false,exist:true,drawn:true}};this.graph=new g(this.graphOptions,this.config.Node,this.config.Edge);this.labels=new G.Label[I.Label.type](this);this.fx=new G.Plot(this,G);this.op=new G.Op(this);this.json=null;this.root=null;this.busy=false;this.parent=false;this.initializeExtras()},createLevelDistanceFunc:function(){var F=this.config.levelDistance;return function(G){return(G._depth+1)*F}},refresh:function(){this.compute();this.plot()},reposition:function(){this.compute("end")},plot:function(){this.fx.plot()},getNodeAndParentAngle:function(M){var H=false;var L=this.graph.getNode(M);var J=L.getParents();var I=(J.length>0)?J[0]:false;if(I){var F=I.pos.getc(),K=L.pos.getc();var G=F.add(K.scale(-1));H=Math.atan2(G.y,G.x);if(H<0){H+=2*Math.PI}}return{parent:I,theta:H}},tagChildren:function(J,L){if(J.angleSpan){var K=[];J.eachAdjacency(function(M){K.push(M.nodeTo)},"ignore");var F=K.length;for(var I=0;IM/2&&I.theta<3*M/2);var S=P?I.theta+M:I.theta;if(P){T-=Math.abs(Math.cos(I.theta)*H.width);R+=Math.sin(I.theta)*H.width}else{if(L.id==this.viz.root){T-=H.width/2}}}V.save();V.translate(T,R);V.rotate(S);V.fillText(L.name,0,0);V.restore()}});F.Label.SVG=new v({Implements:g.Label.SVG,initialize:function(G){this.viz=G},placeLabel:function(Q,K,L){var O=K.pos.getc(true),H=this.viz.canvas,I=H.translateOffsetX,G=H.translateOffsetY,P=H.scaleOffsetX,N=H.scaleOffsetY,M=H.getSize();var J={x:Math.round(O.x*P+I+M.width/2),y:Math.round(O.y*N+G+M.height/2)};Q.setAttribute("x",J.x);Q.setAttribute("y",J.y);L.onPlaceLabel(Q,K)}});F.Label.HTML=new v({Implements:g.Label.HTML,initialize:function(G){this.viz=G},placeLabel:function(R,L,M){var P=L.pos.getc(true),I=this.viz.canvas,J=I.translateOffsetX,H=I.translateOffsetY,Q=I.scaleOffsetX,O=I.scaleOffsetY,N=I.getSize();var K={x:Math.round(P.x*Q+J+N.width/2),y:Math.round(P.y*O+H+N.height/2)};var G=R.style;G.left=K.x+"px";G.top=K.y+"px";G.display=this.fitsInCanvas(K,I)?"":"none";M.onPlaceLabel(R,L)}});F.Plot.NodeTypes=new v({none:{render:e.empty,contains:e.lambda(false)},circle:{render:function(H,G){var J=H.pos.getc(true),I=H.getData("dim");this.nodeHelper.circle.render("fill",J,I,G)},contains:function(G,J){var I=G.pos.getc(true),H=G.getData("dim");return this.nodeHelper.circle.contains(I,J,H)}},ellipse:{render:function(J,H){var K=J.pos.getc(true),I=J.getData("width"),G=J.getData("height");this.nodeHelper.ellipse.render("fill",K,I,G,H)},contains:function(I,K){var J=I.pos.getc(true),H=I.getData("width"),G=I.getData("height");return this.nodeHelper.ellipse.contains(J,K,H,G)}},square:{render:function(H,G){var J=H.pos.getc(true),I=H.getData("dim");this.nodeHelper.square.render("fill",J,I,G)},contains:function(G,J){var I=G.pos.getc(true),H=G.getData("dim");return this.nodeHelper.square.contains(I,J,H)}},rectangle:{render:function(J,H){var K=J.pos.getc(true),I=J.getData("width"),G=J.getData("height");this.nodeHelper.rectangle.render("fill",K,I,G,H)},contains:function(I,K){var J=I.pos.getc(true),H=I.getData("width"),G=I.getData("height");return this.nodeHelper.rectangle.contains(J,K,H,G)}},triangle:{render:function(H,G){var J=H.pos.getc(true),I=H.getData("dim");this.nodeHelper.triangle.render("fill",J,I,G)},contains:function(G,J){var I=G.pos.getc(true),H=G.getData("dim");return this.nodeHelper.triangle.contains(I,J,H)}},star:{render:function(H,G){var J=H.pos.getc(true),I=H.getData("dim");this.nodeHelper.star.render("fill",J,I,G)},contains:function(G,J){var I=G.pos.getc(true),H=G.getData("dim");return this.nodeHelper.star.contains(I,J,H)}},roundedRectangle:{render:function(K,I){var L=K.pos.getc(true),J=K.getData("width"),H=K.getData("height"),G=K.getData("radius");this.nodeHelper.roundedRectangle.render("fill",L,J,H,G,I)},contains:function(J,L){var K=J.pos.getc(true),I=J.getData("width"),H=J.getData("height"),G=J.getData("radius");return this.nodeHelper.roundedRectangle.contains(K,L,I,H,G)}}});F.Plot.EdgeTypes=new v({none:e.empty,line:{render:function(G,H){var J=G.nodeFrom.pos.getc(true),I=G.nodeTo.pos.getc(true);this.edgeHelper.line.render(J,I,H)},contains:function(G,J){var I=G.nodeFrom.pos.getc(true),H=G.nodeTo.pos.getc(true);return this.edgeHelper.line.contains(I,H,J,this.edge.epsilon)}},arrow:{render:function(H,I){var N=H.nodeFrom.pos.getc(true),M=H.nodeTo.pos.getc(true),L=H.getData("dim"),K=H.data.$direction,G=(K&&K.length>1&&K[0]!=H.nodeFrom.id),J=this.edge.arrowPosition||"end";this.edgeHelper.arrow.render(N,M,L,G,I,J)},contains:function(G,J){var I=G.nodeFrom.pos.getc(true),H=G.nodeTo.pos.getc(true);return this.edgeHelper.arrow.contains(I,H,J,this.edge.epsilon)}}})})($jit.RGraph);u.prototype.moebiusTransformation=function(H){var F=this.add(H);var G=H.$conjugate().$prod(this);G.x++;return F.$div(G)};g.Util.moebiusTransformation=function(H,J,I,G,F){this.eachNode(H,function(L){for(var K=0;K=2){return K(I-0.01)}}return K(0.75)},getRadius:function(){var F=this.config.radius;if(F!=="auto"){return F}var G=this.canvas.getSize();return Math.min(G.width,G.height)/2},refresh:function(F){if(F){this.reposition();this.graph.eachNode(function(G){G.startPos.rho=G.pos.rho=G.endPos.rho;G.startPos.theta=G.pos.theta=G.endPos.theta})}else{this.compute()}this.plot()},reposition:function(){this.compute("end");var F=this.graph.getNode(this.root).pos.getc().scale(-1);g.Util.moebiusTransformation(this.graph,[F],["end"],"end","ignore");this.graph.eachNode(function(G){if(G.ignore){G.endPos.rho=G.pos.rho;G.endPos.theta=G.pos.theta}})},plot:function(){this.fx.plot()},onClick:function(H,F){var G=this.graph.getNode(H).pos.getc(true);this.move(G,F)},move:function(J,H){var G=x(J.x,J.y);if(this.busy===false&&G.norm()<1){this.busy=true;var F=this.graph.getClosestNodeToPos(G),I=this;this.graph.computeLevels(F.id,0);this.controller.onBeforeCompute(F);H=e.merge({onComplete:e.empty},H||{});this.fx.animate(e.merge({modes:["moebius"],hideLabels:true},H,{onComplete:function(){I.busy=false;H.onComplete()}}),G)}}});$jit.Hypertree.$extend=true;(function(F){F.Op=new v({Implements:g.Op});F.Plot=new v({Implements:g.Plot});F.Label={};F.Label.Native=new v({Implements:g.Label.Native,initialize:function(G){this.viz=G},renderLabel:function(I,K,H){var G=I.getCtx();var L=K.pos.getc(true);var J=this.viz.getRadius();G.fillText(K.name,L.x*J,L.y*J)}});F.Label.SVG=new v({Implements:g.Label.SVG,initialize:function(G){this.viz=G},placeLabel:function(R,L,M){var P=L.pos.getc(true),I=this.viz.canvas,J=I.translateOffsetX,H=I.translateOffsetY,Q=I.scaleOffsetX,O=I.scaleOffsetY,N=I.getSize(),G=this.viz.getRadius();var K={x:Math.round((P.x*Q)*G+J+N.width/2),y:Math.round((P.y*O)*G+H+N.height/2)};R.setAttribute("x",K.x);R.setAttribute("y",K.y);M.onPlaceLabel(R,L)}});F.Label.HTML=new v({Implements:g.Label.HTML,initialize:function(G){this.viz=G},placeLabel:function(S,M,N){var Q=M.pos.getc(true),J=this.viz.canvas,K=J.translateOffsetX,I=J.translateOffsetY,R=J.scaleOffsetX,P=J.scaleOffsetY,O=J.getSize(),G=this.viz.getRadius();var L={x:Math.round((Q.x*R)*G+K+O.width/2),y:Math.round((Q.y*P)*G+I+O.height/2)};var H=S.style;H.left=L.x+"px";H.top=L.y+"px";H.display=this.fitsInCanvas(L,J)?"":"none";N.onPlaceLabel(S,M)}});F.Plot.NodeTypes=new v({none:{render:e.empty,contains:e.lambda(false)},circle:{render:function(I,G){var H=this.node,K=I.getData("dim"),J=I.pos.getc();K=H.transform?K*(1-J.squaredNorm()):K;J.$scale(I.scale);if(K>0.2){this.nodeHelper.circle.render("fill",J,K,G)}},contains:function(G,J){var H=G.getData("dim"),I=G.pos.getc().$scale(G.scale);return this.nodeHelper.circle.contains(I,J,H)}},ellipse:{render:function(J,H){var K=J.pos.getc().$scale(J.scale),I=J.getData("width"),G=J.getData("height");this.nodeHelper.ellipse.render("fill",K,I,G,H)},contains:function(I,K){var H=I.getData("width"),G=I.getData("height"),J=I.pos.getc().$scale(I.scale);return this.nodeHelper.circle.contains(J,K,H,G)}},square:{render:function(I,G){var H=this.node,K=I.getData("dim"),J=I.pos.getc();K=H.transform?K*(1-J.squaredNorm()):K;J.$scale(I.scale);if(K>0.2){this.nodeHelper.square.render("fill",J,K,G)}},contains:function(G,J){var H=G.getData("dim"),I=G.pos.getc().$scale(G.scale);return this.nodeHelper.square.contains(I,J,H)}},rectangle:{render:function(K,H){var J=this.node,I=K.getData("width"),G=K.getData("height"),L=K.pos.getc();I=J.transform?I*(1-L.squaredNorm()):I;G=J.transform?G*(1-L.squaredNorm()):G;L.$scale(K.scale);if(I>0.2&&G>0.2){this.nodeHelper.rectangle.render("fill",L,I,G,H)}},contains:function(I,K){var H=I.getData("width"),G=I.getData("height"),J=I.pos.getc().$scale(I.scale);return this.nodeHelper.rectangle.contains(J,K,H,G)}},triangle:{render:function(I,G){var H=this.node,K=I.getData("dim"),J=I.pos.getc();K=H.transform?K*(1-J.squaredNorm()):K;J.$scale(I.scale);if(K>0.2){this.nodeHelper.triangle.render("fill",J,K,G)}},contains:function(G,J){var H=G.getData("dim"),I=G.pos.getc().$scale(G.scale);return this.nodeHelper.triangle.contains(I,J,H)}},star:{render:function(I,G){var H=this.node,K=I.getData("dim"),J=I.pos.getc();K=H.transform?K*(1-J.squaredNorm()):K;J.$scale(I.scale);if(K>0.2){this.nodeHelper.star.render("fill",J,K,G)}},contains:function(G,J){var H=G.getData("dim"),I=G.pos.getc().$scale(G.scale);return this.nodeHelper.star.contains(I,J,H)}},roundedRectangle:{render:function(L,I){var K=this.node,J=L.getData("width"),H=L.getData("height"),G=L.getData("radius"),M=L.pos.getc();J=K.transform?J*(1-M.squaredNorm()):J;H=K.transform?H*(1-M.squaredNorm()):H;M.$scale(L.scale);if(J>0.2&&H>0.2){this.nodeHelper.roundedRectangle.render("fill",M,J,H,G,I)}},contains:function(J,L){var I=J.getData("width"),H=J.getData("height"),G=J.getData("radius"),K=J.pos.getc().$scale(J.scale);return this.nodeHelper.roundedRectangle.contains(K,L,I,H,G)}}});F.Plot.EdgeTypes=new v({none:e.empty,line:{render:function(G,H){var K=G.nodeFrom.pos.getc(true),J=G.nodeTo.pos.getc(true),I=G.nodeFrom.scale;this.edgeHelper.line.render({x:K.x*I,y:K.y*I},{x:J.x*I,y:J.y*I},H)},contains:function(G,K){var J=G.nodeFrom.pos.getc(true),I=G.nodeTo.pos.getc(true),H=G.nodeFrom.scale;return this.edgeHelper.line.contains({x:J.x*H,y:J.y*H},{x:I.x*H,y:I.y*H},K,this.edge.epsilon)}},arrow:{render:function(H,I){var N=H.nodeFrom.pos.getc(true),M=H.nodeTo.pos.getc(true),J=H.nodeFrom.scale,L=H.getData("dim"),K=H.data.$direction,G=(K&&K.length>1&&K[0]!=H.nodeFrom.id);this.edgeHelper.arrow.render({x:N.x*J,y:N.y*J},{x:M.x*J,y:M.y*J},L,G,I)},contains:function(G,K){var J=G.nodeFrom.pos.getc(true),I=G.nodeTo.pos.getc(true),H=G.nodeFrom.scale;return this.edgeHelper.arrow.contains({x:J.x*H,y:J.y*H},{x:I.x*H,y:I.y*H},K,this.edge.epsilon)}},hyperline:{render:function(G,H){var K=G.nodeFrom.pos.getc(),J=G.nodeTo.pos.getc(),I=this.viz.getRadius();this.edgeHelper.hyperline.render(K,J,I,H)},contains:e.lambda(false)}})})($jit.Hypertree)})(); \ No newline at end of file diff --git a/Jit/jit.js b/Jit/jit.js index 9ea1c61..13372a1 100644 --- a/Jit/jit.js +++ b/Jit/jit.js @@ -723,188 +723,300 @@ $jit.json = { }; -/* - An object containing multiple type of transformations. -*/ +var Animation; +(function() { -$jit.Trans = { - $extend: true, - - linear: function(p){ - return p; + //Utility functions + function $(d) { + return document.getElementById(d); } -}; -var Trans = $jit.Trans; + $.empty = function() {}; -(function(){ + $.time = Date.now; - var makeTrans = function(transition, params){ - params = $.splat(params); - return $.extend(transition, { - easeIn: function(pos){ - return transition(pos, params); - }, - easeOut: function(pos){ - return 1 - transition(1 - pos, params); - }, - easeInOut: function(pos){ - return (pos <= 0.5)? transition(2 * pos, params) / 2 : (2 - transition( - 2 * (1 - pos), params)) / 2; + $.uid = (function() { + var t = $.time(); + + return function() { + return t++; + }; + })(); + + $.extend = function(to, from) { + for (var p in from) { + to[p] = from[p]; + } + return to; + }; + + $.type = (function() { + var oString = Object.prototype.toString, + type = function(e) { + var t = oString.call(e); + return t.substr(8, t.length - 9).toLowerCase(); + }; + + return function(elem) { + var elemType = type(elem); + if (elemType != 'object') { + return elemType; } - }); + if (elem.$$family) return elem.$$family; + return (elem && elem.nodeName && elem.nodeType == 1) ? 'element' : elemType; + }; + })(); + + (function() { + function detach(elem) { + var type = $.type(elem), ans; + if (type == 'object') { + ans = {}; + for (var p in elem) { + ans[p] = detach(elem[p]); + } + return ans; + } else if (type == 'array') { + ans = []; + for (var i = 0, l = elem.length; i < l; i++) { + ans[i] = detach(elem[i]); + } + return ans; + } else { + return elem; + } + } + + $.merge = function() { + var mix = {}; + for (var i = 0, l = arguments.length; i < l; i++){ + var object = arguments[i]; + if ($.type(object) != 'object') continue; + for (var key in object){ + var op = object[key], mp = mix[key]; + if (mp && $.type(op) == 'object' && $.type(mp) == 'object') { + mix[key] = $.merge(mp, op); + } else{ + mix[key] = detach(op); + } + } + } + return mix; + }; + })(); + + $.splat = (function() { + var isArray = Array.isArray; + return function(a) { + return isArray(a) && a || [a]; + }; + })(); + + //Timer based animation + Animation = function(options) { + this.opt = $.merge({ + delay: 0, + duration: 1000, + transition: function(x) { return x; }, + compute: $.empty, + complete: $.empty + }, options || {}); }; - var transitions = { + var Queue = Animation.Queue = []; - Pow: function(p, x){ - return Math.pow(p, x[0] || 6); - }, + Animation.prototype = { + time:null, - Expo: function(p){ - return Math.pow(2, 8 * (p - 1)); + start: function(options) { + this.opt = $.merge(this.opt, options || {}); + this.time = $.time(); + this.animating = true; + Queue.push(this); }, - Circ: function(p){ - return 1 - Math.sin(Math.acos(p)); + setOptions: function(options) { + this.opt = $.merge(this.opt, options || {}); + return this; }, - Sine: function(p){ - return 1 - Math.sin((1 - p) * Math.PI / 2); + pause: function() { + this.animating = false; }, - Back: function(p, x){ - x = x[0] || 1.618; - return Math.pow(p, 2) * ((x + 1) * p - x); + stopTimer: function() { + this.animating = false; }, - Bounce: function(p){ - var value; - for ( var a = 0, b = 1; 1; a += b, b /= 2) { - if (p >= (7 - 4 * a) / 11) { - value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2); - break; - } + //perform a step in the animation + step: function() { + //if not animating, then return + if (!this.animating) return; + var currentTime = $.time(), + time = this.time, + opt = this.opt, + delay = opt.delay, + duration = opt.duration, + delta = 0; + //hold animation for the delay + if (currentTime < time + delay) { + opt.compute.call(this, delta); + return; + } + //if in our time window, then execute animation + if (currentTime < time + delay + duration) { + delta = opt.transition((currentTime - time - delay) / duration); + opt.compute.call(this, delta); + } else { + this.animating = false; + opt.compute.call(this, 1); + opt.complete.call(this); } - return value; - }, - - Elastic: function(p, x){ - return Math.pow(2, 10 * --p) - * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3); } - }; - $.each(transitions, function(val, key){ - Trans[key] = makeTrans(val); - }); + Animation.compute = function(from, to, delta) { + return from + (to - from) * delta; + }; - $.each( [ - 'Quad', 'Cubic', 'Quart', 'Quint' - ], function(elem, i){ - Trans[elem] = makeTrans(function(p){ - return Math.pow(p, [ - i + 2 - ]); - }); - }); + //Easing equations + Animation.Transition = { + linear: function(p){ + return p; + } + }; -})(); + var Trans = $jit.Trans = Animation.Transition; -/* - A Class that can perform animations for generic objects. + (function(){ - If you are looking for animation transitions please take a look at the object. + var makeTrans = function(transition, params){ + params = $.splat(params); + return $.extend(transition, { + easeIn: function(pos){ + return transition(pos, params); + }, + easeOut: function(pos){ + return 1 - transition(1 - pos, params); + }, + easeInOut: function(pos){ + return (pos <= 0.5)? transition(2 * pos, params) / 2 : (2 - transition( + 2 * (1 - pos), params)) / 2; + } + }); + }; - Used by: + var transitions = { - - - Based on: - - The Animation class is based in the MooTools Framework . Copyright (c) 2006-2009 Valerio Proietti, . MIT license . + Pow: function(p, x){ + return Math.pow(p, x[0] || 6); + }, -*/ + Expo: function(p){ + return Math.pow(2, 8 * (p - 1)); + }, -var Animation = new Class( { + Circ: function(p){ + return 1 - Math.sin(Math.acos(p)); + }, - initialize: function(options){ - this.setOptions(options); - }, + Sine: function(p){ + return 1 - Math.sin((1 - p) * Math.PI / 2); + }, - setOptions: function(options){ - var opt = { - duration: 2500, - fps: 40, - transition: Trans.Quart.easeInOut, - compute: $.empty, - complete: $.empty, - link: 'ignore' - }; - this.opt = $.merge(opt, options || {}); - return this; - }, + Back: function(p, x){ + x = x[0] || 1.618; + return Math.pow(p, 2) * ((x + 1) * p - x); + }, - step: function(){ - var time = $.time(), opt = this.opt; - if (time < this.time + opt.duration) { - var delta = opt.transition((time - this.time) / opt.duration); - opt.compute(delta); - } else { - this.timer = clearInterval(this.timer); - opt.compute(1); - opt.complete(); - } - }, + Bounce: function(p){ + var value; + for ( var a = 0, b = 1; 1; a += b, b /= 2) { + if (p >= (7 - 4 * a) / 11) { + value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2); + break; + } + } + return value; + }, - start: function(){ - if (!this.check()) - return this; - this.time = 0; - this.startTimer(); - return this; - }, + Elastic: function(p, x){ + return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3); + } - startTimer: function(){ - var that = this, fps = this.opt.fps; - if (this.timer) - return false; - this.time = $.time() - this.time; - this.timer = setInterval((function(){ - that.step(); - }), Math.round(1000 / fps)); - return true; - }, + }; - pause: function(){ - this.stopTimer(); - return this; - }, + for (var t in transitions) { + Trans[t] = makeTrans(transitions[t]); + } - resume: function(){ - this.startTimer(); - return this; - }, + ['Quad', 'Cubic', 'Quart', 'Quint'].forEach(function(elem, i){ + Trans[elem] = makeTrans(function(p){ + return Math.pow(p, [ + i + 2 + ]); + }); + }); - stopTimer: function(){ - if (!this.timer) - return false; - this.time = $.time() - this.time; - this.timer = clearInterval(this.timer); - return true; - }, + })(); + + //animationTime - function branching + var global = self || window, + checkFxQueue = function() { + var oldQueue = Queue; + Queue = []; + if (oldQueue.length) { + for (var i = 0, l = oldQueue.length, fx; i < l; i++) { + fx = oldQueue[i]; + fx.step(); + if (fx.animating) { + Queue.push(fx); + } + } + Animation.Queue = Queue; + } + }; - check: function(){ - if (!this.timer) - return true; - if (this.opt.link == 'cancel') { - this.stopTimer(); - return true; + if (global) { + var found = false; + ['webkitAnimationTime', 'mozAnimationTime', 'animationTime', + 'webkitAnimationStartTime', 'mozAnimationStartTime', 'animationStartTime'].forEach(function(impl) { + if (impl in global) { + Animation.animationTime = function() { + return global[impl]; + }; + found = true; + } + }); + if (!found) { + Animation.animationTime = $.time; + } + //requestAnimationFrame - function branching + found = false; + ['webkitRequestAnimationFrame', 'mozRequestAnimationFrame', 'requestAnimationFrame'].forEach(function(impl) { + if (impl in global) { + Animation.requestAnimationFrame = function(callback) { + global[impl](function() { + checkFxQueue(); + callback(); + }); + }; + found = true; + } + }); + if (!found) { + Animation.requestAnimationFrame = function(callback) { + setTimeout(function() { + checkFxQueue(); + callback(); + }, 1000 / 60); + }; } - return false; } -}); + + (function loop() { Animation.requestAnimationFrame(loop); }()); + +}()); var Options = function() { @@ -2656,7 +2768,7 @@ Extras.Classes.Navigation = new Class({ }, onMouseWheel: function(e, win, scroll) { - if(!this.config.zooming) return; + if(!this.config.enable || !this.config.zooming) return; $.event.stop($.event.get(e, win)); var val = this.config.zooming / 1000, ans = 1 + scroll * val; @@ -2664,7 +2776,7 @@ Extras.Classes.Navigation = new Class({ }, onMouseDown: function(e, win, eventInfo) { - if(!this.config.panning) return; + if(!this.config.enable || !this.config.panning) return; e.preventDefault ? e.preventDefault() : e.returnValue = false; $.addClass(this.canvas.getElement(), 'grabbing'); if(this.config.panning == 'avoid nodes' && (this.dom? this.isLabel(e, win) : (eventInfo.getNode() || eventInfo.getEdge()))) return; @@ -2682,7 +2794,7 @@ Extras.Classes.Navigation = new Class({ }, onMouseMove: function(e, win, eventInfo) { - if(!this.config.panning) return; + if(!this.config.enable || !this.config.panning) return; if(!this.pressed) return; if(this.config.panning == 'avoid nodes' && (this.dom? this.isLabel(e, win) : eventInfo.getNode())) return; var thispos = this.pos, @@ -4095,11 +4207,20 @@ $jit.Graph = new Class({ (end code) */ getByName: function(name) { + var res = []; for(var id in this.nodes) { var n = this.nodes[id]; - if(n.name == name) return n; + if(n.name == name) { + res.push(n); + } } - return false; + if (res.length == 1) { + return res[0]; + } + if (res.length == 0) { + return false; + } + return res; }, /* @@ -5386,6 +5507,7 @@ $.each(['eachAdjacency', 'eachLevel', 'eachSubgraph', 'eachSubnode', 'anySubnode }; }); + /* * File: Graph.Op.js * @@ -6477,7 +6599,73 @@ var NodeHelper = { 'contains': function(npos, pos, dim) { return NodeHelper.circle.contains(npos, pos, dim); } - } + }, + 'roundedRectangle': { + /* + Method: render + + Renders a rectangle with rounded corners into the canvas. + + Parameters: + + type - (string) Possible options are 'fill' or 'stroke'. + pos - (object) An *x*, *y* object with the position of the center of the rectangle. + width - (number) The width of the rectangle. + height - (number) The height of the rectangle. + radius - (number) The radius of the corners. + canvas - (object) A instance. + + Example: + (start code js) + NodeHelper.roundedRectangle.render('fill', { x: 10, y: 30 }, 30, 40, 5, viz.canvas); + (end code) + */ + 'render': function(type, pos, w, h, r, canvas){ + var ctx = canvas.getCtx(), x=pos.x, y=pos.y ; + + ctx.save(); + ctx.translate(-w/2, -h/2); + if (w < 2 * r) r = w / 2; + if (h < 2 * r) r = h / 2; + ctx.beginPath(); + ctx.moveTo(x+r, y); + ctx.arcTo(x+w, y, x+w, y+h, r); + ctx.arcTo(x+w, y+h, x, y+h, r); + ctx.arcTo(x, y+h, x, y, r); + ctx.arcTo(x, y, x+w, y, r); + ctx.closePath(); + ctx[type](); + /*if(typeof type === 'string') { + ctx[type](); + }else{ //type is an array + for(var t in type){ + ctx[type[t]](); + } + }*/ + ctx.restore(); + }, + /* + Method: contains + + Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise. + + Parameters: + + npos - (object) An *x*, *y* object with the position. + pos - (object) An *x*, *y* object with the position to check. + width - (number) The width of the rendered rectangle. + height - (number) The height of the rendered rectangle. + radius - (number) The radius of the corners. + + Example: + (start code js) + NodeHelper.roundedRectangle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30, 40, 5); + (end code) + */ + 'contains': function(npos, pos, width, height, radius){ + return NodeHelper.rectangle.contains(npos, pos, width, height); + } + } }; /* @@ -7328,15 +7516,15 @@ Graph.Plot = { node.eachAdjacency(function(adj) { var nodeTo = adj.nodeTo; if(!!nodeTo.visited === T && node.drawn && nodeTo.drawn) { - !animating && opt.onBeforePlotLine(adj); + opt.onBeforePlotLine(adj, animating); that.plotLine(adj, canvas, animating); - !animating && opt.onAfterPlotLine(adj); + opt.onAfterPlotLine(adj, animating); } }); if(node.drawn) { - !animating && opt.onBeforePlotNode(node); + opt.onBeforePlotNode(node, animating); that.plotNode(node, canvas, animating); - !animating && opt.onAfterPlotNode(node); + opt.onAfterPlotNode(node, animating); } if(!that.labelsHidden && opt.withLabels) { if(node.drawn && nodeAlpha >= 0.95) { @@ -7362,16 +7550,16 @@ Graph.Plot = { node.eachSubnode(function(elem) { if(opt.plotSubtree(node, elem) && elem.exist && elem.drawn) { var adj = node.getAdjacency(elem.id); - !animating && opt.onBeforePlotLine(adj); + opt.onBeforePlotLine(adj, animating); that.plotLine(adj, canvas, animating); - !animating && opt.onAfterPlotLine(adj); + opt.onAfterPlotLine(adj, animating); that.plotTree(elem, opt, animating); } }); if(node.drawn) { - !animating && opt.onBeforePlotNode(node); + opt.onBeforePlotNode(node, animating); this.plotNode(node, canvas, animating); - !animating && opt.onAfterPlotNode(node); + opt.onAfterPlotNode(node, animating); if(!opt.hideLabels && opt.withLabels && nodeAlpha >= 0.95) this.labels.plotLabel(canvas, node, opt); else @@ -8379,6 +8567,13 @@ var NodeDim = { style.width = autoWidth? 'auto' : width + 'px'; style.height = autoHeight? 'auto' : height + 'px'; + //font styles + if (n.getData('label-size')) { + style.fontSize = n.getData('label-size') + 'px'; + } else { + style.fontSize = ''; + } + //TODO(nico) should let the user choose what to insert here. label.innerHTML = n.name; @@ -8563,7 +8758,7 @@ Layouts.Tree = (function() { var siblingOffset = config.siblingOffset; var subtreeOffset = config.subtreeOffset; - var align = config.align; + var align = config.align; //this should be the tree alignment, not the node alignment. function $design(node, maxsize, acum) { var sval = node.getData(s, prop); @@ -8614,7 +8809,6 @@ Layouts.Tree = (function() { $design(node, false, 0); } - return new Class({ /* Method: compute @@ -8641,7 +8835,7 @@ Layouts.Tree = (function() { computePositions : function(node, prop) { var config = this.config; var multitree = config.multitree; - var align = config.align; + var align = node.getData('align') || config.align; var indent = align !== 'center' && config.indent; var orn = config.orientation; var orns = multitree ? [ 'top', 'right', 'bottom', 'left' ] : [ orn ]; @@ -9674,41 +9868,43 @@ $jit.ST.Geom = new Class({ }; }; var dim = this.node; + var align = node.getData('align') || dim.align; var w = node.getData('width'); var h = node.getData('height'); if(type == 'begin') { - if(dim.align == "center") { + if(align == "center") { return this.dispatch(s, $C(0, h/2), $C(-w/2, 0), $C(0, -h/2),$C(w/2, 0)); - } else if(dim.align == "left") { + } else if(align == "left") { return this.dispatch(s, $C(0, h), $C(0, 0), $C(0, 0), $C(w, 0)); - } else if(dim.align == "right") { + } else if(align == "right") { return this.dispatch(s, $C(0, 0), $C(-w, 0), $C(0, -h),$C(0, 0)); } else throw "align: not implemented"; } else if(type == 'end') { - if(dim.align == "center") { + if(align == "center") { return this.dispatch(s, $C(0, -h/2), $C(w/2, 0), $C(0, h/2), $C(-w/2, 0)); - } else if(dim.align == "left") { + } else if(align == "left") { return this.dispatch(s, $C(0, 0), $C(w, 0), $C(0, h), $C(0, 0)); - } else if(dim.align == "right") { + } else if(align == "right") { return this.dispatch(s, $C(0, -h),$C(0, 0), $C(0, 0), $C(-w, 0)); } else throw "align: not implemented"; } }, - + /* Adjusts the tree position due to canvas scaling or translation. */ getScaledTreePosition: function(node, scale) { var dim = this.node; + var align = node.getData('align') || dim.align; var w = node.getData('width'); var h = node.getData('height'); var s = (this.config.multitree @@ -9720,13 +9916,13 @@ $jit.ST.Geom = new Class({ return node.pos.add(new Complex(a, b)).$scale(1 - scale); }; }; - if(dim.align == "left") { + if(align == "left") { return this.dispatch(s, $C(0, h), $C(0, 0), $C(0, 0), $C(w, 0)); - } else if(dim.align == "center") { + } else if(align == "center") { return this.dispatch(s, $C(0, h / 2), $C(-w / 2, 0), $C(0, -h / 2),$C(w / 2, 0)); - } else if(dim.align == "right") { + } else if(align == "right") { return this.dispatch(s, $C(0, 0), $C(-w, 0), $C(0, -h),$C(0, 0)); } else throw "align: not implemented"; @@ -9929,6 +10125,7 @@ $jit.ST.Label.DOM = new Class({ var pos = node.pos.getc(true), config = this.viz.config, dim = config.Node, + align = node.getData('align') || dim.align, canvas = this.viz.canvas, w = node.getData('width'), h = node.getData('height'), @@ -9942,12 +10139,12 @@ $jit.ST.Label.DOM = new Class({ posx = pos.x * sx + ox, posy = pos.y * sy + oy; - if(dim.align == "center") { + if(align == "center") { labelPos= { x: Math.round(posx - w / 2 + radius.width/2), y: Math.round(posy - h / 2 + radius.height/2) }; - } else if (dim.align == "left") { + } else if (align == "left") { orn = config.orientation; if(orn == "bottom" || orn == "top") { labelPos= { @@ -9960,7 +10157,7 @@ $jit.ST.Label.DOM = new Class({ y: Math.round(posy - h / 2 + radius.height/2) }; } - } else if(dim.align == "right") { + } else if(align == "right") { orn = config.orientation; if(orn == "bottom" || orn == "top") { labelPos= { @@ -10034,7 +10231,7 @@ $jit.ST.Label.HTML = new Class({ Class: ST.Plot.NodeTypes This class contains a list of built-in types. - Node types implemented are 'none', 'circle', 'rectangle', 'ellipse' and 'square'. + Node types implemented are 'none', 'circle', 'rectangle', 'roundedRectangle', 'ellipse' and 'square'. You can add your custom node types, customizing your visualization to the extreme. @@ -10115,6 +10312,22 @@ $jit.ST.Plot.NodeTypes = new Class({ npos = this.getAlignedPos(node.pos.getc(true), width, height); return this.nodeHelper.rectangle.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height); } + }, + 'roundedRectangle': { + 'render': function(node, canvas) { + var width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'), + pos = this.getAlignedPos(node.pos.getc(true), width, height); + this.nodeHelper.roundedRectangle.render('fill', {x:pos.x+width/2, y:pos.y+height/2}, width, height, radius, canvas); + }, + 'contains': function(node, pos) { + var width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'), + npos = this.getAlignedPos(node.pos.getc(true), width, height); + this.nodeHelper.rectangle.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height, radius); + } } }); @@ -10278,7 +10491,6 @@ $jit.ST.Plot.EdgeTypes = new Class({ }); - /* * File: AreaChart.js * @@ -13328,14 +13540,14 @@ Layouts.TM.SliceAndDice = new Class({ this.computePositions(root, root, this.layout.orientation, prop); this.controller.onAfterCompute(root); }, - + computePositions: function(par, ch, orn, prop) { //compute children areas var totalArea = 0; par.eachSubnode(function(n) { totalArea += n.getData('area', prop); - }); - + }, "ignore"); + var config = this.config, offset = config.offset, width = par.getData('width', prop), @@ -13354,7 +13566,7 @@ Layouts.TM.SliceAndDice = new Class({ posth = config.titleHeight; pos2th = 0; } else { - orn = 'h'; + orn = 'h'; otherSize = height * fact; size = width; dim = 'width'; @@ -13373,11 +13585,12 @@ Layouts.TM.SliceAndDice = new Class({ p[pos2] = cpos[pos2] + pos2th; tm.computePositions(ch, n, orn, prop); offsetSize += n.getData(dim, prop); - }); + }, "ignore"); } }); + Layouts.TM.Area = { /* Method: compute @@ -16290,6 +16503,22 @@ $jit.ForceDirected.$extend = true; dim = node.getData('dim'); return this.nodeHelper.star.contains(npos, pos, dim); } + }, + 'roundedRectangle': { + 'render': function(node, canvas){ + var pos = node.pos.getc(true), + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'); + this.nodeHelper.roundedRectangle.render('fill', pos, width, height, radius, canvas); + }, + 'contains': function(node, pos){ + var npos = node.pos.getc(true), + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'); + return this.nodeHelper.roundedRectangle.contains(npos, pos, width, height, radius); + } } }); @@ -16351,7 +16580,6 @@ $jit.ForceDirected.$extend = true; })($jit.ForceDirected); - /* * File: Treemap.js * @@ -17517,9 +17745,52 @@ $jit.RGraph.$extend = true; */ - RGraph.Label.Native = new Class( { - Implements: Graph.Label.Native - }); + RGraph.Label.Native = new Class( { + Implements: Graph.Label.Native, + + initialize: function(viz) { + this.viz = viz; + this.label = viz.config.Label; + this.config = viz.config; + }, + + renderLabel: function(canvas, node, controller) { + var span = node.getData('span'); + if(span < Math.PI /2 && Math.tan(span) * + this.config.levelDistance * node._depth < 10) { + return; + } + var ctx = canvas.getCtx(); + var measure = ctx.measureText(node.name); + if (node.id == this.viz.root) { + var x = -measure.width / 2, y = 0, thetap = 0; + var ld = 0; + } else { + var indent = 5; + var ld = controller.levelDistance - indent; + var clone = node.pos.clone(); + clone.rho += indent + (node.getData('dim') || 0); + var p = clone.getp(true); + var ct = clone.getc(true); + var x = ct.x, y = ct.y; + // get angle in degrees + var pi = Math.PI; + var cond = (p.theta > pi / 2 && p.theta < 3 * pi / 2); + var thetap = cond ? p.theta + pi : p.theta; + if (cond) { + x -= Math.abs(Math.cos(p.theta) * measure.width); + y += Math.sin(p.theta) * measure.width; + } else if (node.id == this.viz.root) { + x -= measure.width / 2; + } + } + ctx.save(); + ctx.translate(x, y); + ctx.rotate(thetap); + ctx.fillText(node.name, 0, 0); + ctx.restore(); + } + }); /* RGraph.Label.SVG @@ -17631,7 +17902,7 @@ $jit.RGraph.$extend = true; Class: RGraph.Plot.NodeTypes This class contains a list of built-in types. - Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'. + Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'roundedRectangle', 'star', 'ellipse' and 'square'. You can add your custom node types, customizing your visualization to the extreme. @@ -17732,6 +18003,22 @@ $jit.RGraph.$extend = true; dim = node.getData('dim'); return this.nodeHelper.star.contains(npos, pos, dim); } + }, + 'roundedRectangle': { + 'render': function(node, canvas){ + var pos = node.pos.getc(true), + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'); + this.nodeHelper.roundedRectangle.render('fill', pos, width, height, radius, canvas); + }, + 'contains': function(node, pos){ + var npos = node.pos.getc(true), + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'); + return this.nodeHelper.roundedRectangle.contains(npos, pos, width, height, radius); + } } }); @@ -17794,7 +18081,6 @@ $jit.RGraph.$extend = true; })($jit.RGraph); - /* * File: Hypertree.js * @@ -18334,7 +18620,7 @@ $jit.Hypertree.$extend = true; Class: Hypertree.Plot.NodeTypes This class contains a list of built-in types. - Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'. + Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'roundedRectangle', 'star', 'ellipse' and 'square'. You can add your custom node types, customizing your visualization to the extreme. @@ -18461,6 +18747,28 @@ $jit.Hypertree.$extend = true; npos = node.pos.getc().$scale(node.scale); return this.nodeHelper.star.contains(npos, pos, dim); } + }, + 'roundedRectangle': { + 'render': function(node, canvas) { + var nconfig = this.node, + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'), + pos = node.pos.getc(); + width = nconfig.transform? width * (1 - pos.squaredNorm()) : width; + height = nconfig.transform? height * (1 - pos.squaredNorm()) : height; + pos.$scale(node.scale); + if (width > 0.2 && height > 0.2) { + this.nodeHelper.roundedRectangle.render('fill', pos, width, height, radius, canvas); + } + }, + 'contains': function(node, pos) { + var width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'), + npos = node.pos.getc().$scale(node.scale); + return this.nodeHelper.roundedRectangle.contains(npos, pos, width, height, radius); + } } }); @@ -18502,7 +18810,7 @@ $jit.Hypertree.$extend = true; var from = adj.nodeFrom.pos.getc(true), to = adj.nodeTo.pos.getc(true), r = adj.nodeFrom.scale; - this.edgeHelper.line.contains({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, pos, this.edge.epsilon); + return this.edgeHelper.line.contains({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, pos, this.edge.epsilon); } }, 'arrow': { @@ -18519,7 +18827,7 @@ $jit.Hypertree.$extend = true; var from = adj.nodeFrom.pos.getc(true), to = adj.nodeTo.pos.getc(true), r = adj.nodeFrom.scale; - this.edgeHelper.arrow.contains({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, pos, this.edge.epsilon); + return this.edgeHelper.arrow.contains({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, pos, this.edge.epsilon); } }, 'hyperline': { @@ -18537,5 +18845,4 @@ $jit.Hypertree.$extend = true; - })(); \ No newline at end of file diff --git a/Source/Graph/Helpers.js b/Source/Graph/Helpers.js index aa8e51f..a88203e 100644 --- a/Source/Graph/Helpers.js +++ b/Source/Graph/Helpers.js @@ -392,7 +392,73 @@ var NodeHelper = { 'contains': function(npos, pos, dim) { return NodeHelper.circle.contains(npos, pos, dim); } - } + }, + 'roundedRectangle': { + /* + Method: render + + Renders a rectangle with rounded corners into the canvas. + + Parameters: + + type - (string) Possible options are 'fill' or 'stroke'. + pos - (object) An *x*, *y* object with the position of the center of the rectangle. + width - (number) The width of the rectangle. + height - (number) The height of the rectangle. + radius - (number) The radius of the corners. + canvas - (object) A instance. + + Example: + (start code js) + NodeHelper.roundedRectangle.render('fill', { x: 10, y: 30 }, 30, 40, 5, viz.canvas); + (end code) + */ + 'render': function(type, pos, w, h, r, canvas){ + var ctx = canvas.getCtx(), x=pos.x, y=pos.y ; + + ctx.save(); + ctx.translate(-w/2, -h/2); + if (w < 2 * r) r = w / 2; + if (h < 2 * r) r = h / 2; + ctx.beginPath(); + ctx.moveTo(x+r, y); + ctx.arcTo(x+w, y, x+w, y+h, r); + ctx.arcTo(x+w, y+h, x, y+h, r); + ctx.arcTo(x, y+h, x, y, r); + ctx.arcTo(x, y, x+w, y, r); + ctx.closePath(); + ctx[type](); + /*if(typeof type === 'string') { + ctx[type](); + }else{ //type is an array + for(var t in type){ + ctx[type[t]](); + } + }*/ + ctx.restore(); + }, + /* + Method: contains + + Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise. + + Parameters: + + npos - (object) An *x*, *y* object with the position. + pos - (object) An *x*, *y* object with the position to check. + width - (number) The width of the rendered rectangle. + height - (number) The height of the rendered rectangle. + radius - (number) The radius of the corners. + + Example: + (start code js) + NodeHelper.roundedRectangle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30, 40, 5); + (end code) + */ + 'contains': function(npos, pos, width, height, radius){ + return NodeHelper.rectangle.contains(npos, pos, width, height); + } + } }; /* diff --git a/Source/Visualizations/ForceDirected.js b/Source/Visualizations/ForceDirected.js index cafb79c..4c24c7f 100644 --- a/Source/Visualizations/ForceDirected.js +++ b/Source/Visualizations/ForceDirected.js @@ -520,6 +520,22 @@ $jit.ForceDirected.$extend = true; dim = node.getData('dim'); return this.nodeHelper.star.contains(npos, pos, dim); } + }, + 'roundedRectangle': { + 'render': function(node, canvas){ + var pos = node.pos.getc(true), + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'); + this.nodeHelper.roundedRectangle.render('fill', pos, width, height, radius, canvas); + }, + 'contains': function(node, pos){ + var npos = node.pos.getc(true), + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'); + return this.nodeHelper.roundedRectangle.contains(npos, pos, width, height, radius); + } } }); @@ -579,4 +595,4 @@ $jit.ForceDirected.$extend = true; } }); -})($jit.ForceDirected); +})($jit.ForceDirected); \ No newline at end of file diff --git a/Source/Visualizations/Hypertree.js b/Source/Visualizations/Hypertree.js index 039ef31..1d3fe26 100644 --- a/Source/Visualizations/Hypertree.js +++ b/Source/Visualizations/Hypertree.js @@ -537,7 +537,7 @@ $jit.Hypertree.$extend = true; Class: Hypertree.Plot.NodeTypes This class contains a list of built-in types. - Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'. + Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'roundedRectangle', 'star', 'ellipse' and 'square'. You can add your custom node types, customizing your visualization to the extreme. @@ -664,6 +664,28 @@ $jit.Hypertree.$extend = true; npos = node.pos.getc().$scale(node.scale); return this.nodeHelper.star.contains(npos, pos, dim); } + }, + 'roundedRectangle': { + 'render': function(node, canvas) { + var nconfig = this.node, + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'), + pos = node.pos.getc(); + width = nconfig.transform? width * (1 - pos.squaredNorm()) : width; + height = nconfig.transform? height * (1 - pos.squaredNorm()) : height; + pos.$scale(node.scale); + if (width > 0.2 && height > 0.2) { + this.nodeHelper.roundedRectangle.render('fill', pos, width, height, radius, canvas); + } + }, + 'contains': function(node, pos) { + var width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'), + npos = node.pos.getc().$scale(node.scale); + return this.nodeHelper.roundedRectangle.contains(npos, pos, width, height, radius); + } } }); @@ -736,4 +758,4 @@ $jit.Hypertree.$extend = true; } }); -})($jit.Hypertree); +})($jit.Hypertree); \ No newline at end of file diff --git a/Source/Visualizations/RGraph.js b/Source/Visualizations/RGraph.js index da69188..36c5ad2 100644 --- a/Source/Visualizations/RGraph.js +++ b/Source/Visualizations/RGraph.js @@ -475,7 +475,7 @@ $jit.RGraph.$extend = true; Class: RGraph.Plot.NodeTypes This class contains a list of built-in types. - Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'. + Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'roundedRectangle', 'star', 'ellipse' and 'square'. You can add your custom node types, customizing your visualization to the extreme. @@ -576,6 +576,22 @@ $jit.RGraph.$extend = true; dim = node.getData('dim'); return this.nodeHelper.star.contains(npos, pos, dim); } + }, + 'roundedRectangle': { + 'render': function(node, canvas){ + var pos = node.pos.getc(true), + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'); + this.nodeHelper.roundedRectangle.render('fill', pos, width, height, radius, canvas); + }, + 'contains': function(node, pos){ + var npos = node.pos.getc(true), + width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'); + return this.nodeHelper.roundedRectangle.contains(npos, pos, width, height, radius); + } } }); @@ -636,4 +652,4 @@ $jit.RGraph.$extend = true; } }); -})($jit.RGraph); +})($jit.RGraph); \ No newline at end of file diff --git a/Source/Visualizations/Spacetree.js b/Source/Visualizations/Spacetree.js index 32f616d..75bf694 100644 --- a/Source/Visualizations/Spacetree.js +++ b/Source/Visualizations/Spacetree.js @@ -1364,7 +1364,7 @@ $jit.ST.Label.HTML = new Class({ Class: ST.Plot.NodeTypes This class contains a list of built-in types. - Node types implemented are 'none', 'circle', 'rectangle', 'ellipse' and 'square'. + Node types implemented are 'none', 'circle', 'rectangle', 'roundedRectangle', 'ellipse' and 'square'. You can add your custom node types, customizing your visualization to the extreme. @@ -1445,6 +1445,22 @@ $jit.ST.Plot.NodeTypes = new Class({ npos = this.getAlignedPos(node.pos.getc(true), width, height); return this.nodeHelper.rectangle.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height); } + }, + 'roundedRectangle': { + 'render': function(node, canvas) { + var width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'), + pos = this.getAlignedPos(node.pos.getc(true), width, height); + this.nodeHelper.roundedRectangle.render('fill', {x:pos.x+width/2, y:pos.y+height/2}, width, height, radius, canvas); + }, + 'contains': function(node, pos) { + var width = node.getData('width'), + height = node.getData('height'), + radius = node.getData('radius'), + npos = this.getAlignedPos(node.pos.getc(true), width, height); + this.nodeHelper.rectangle.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height, radius); + } } }); @@ -1606,4 +1622,3 @@ $jit.ST.Plot.EdgeTypes = new Class({ } } }); - diff --git a/make.py b/make.py index 812a457..2a842b3 100755 --- a/make.py +++ b/make.py @@ -6,7 +6,8 @@ from serve import render from build import Build -YC = 'yuicompressor-2.4.7.jar' +YC_VER = "2.4.8" +YC = "yuicompressor-%s.jar" % YC_VER EXCLUDES = ['Source/Extras', 'Source/Layouts', 'Source/Options/Options.js', @@ -159,12 +160,20 @@ def make_build(fancy=False): f.write(license) f.write(lib) f.close() - print "Done. Compressing Library..." - f = open('Jit/jit-yc.js', 'w') - f.write(license) - f.close() - system('java -jar Extras/' + YC + ' Jit/jit.js >> Jit/jit-yc.js') - print "Done. Zipping..." + print "Done." + + if not path.exists('Extras/' + YC): + print "Library compression requires YUI compressor v.%s" % YC_VER + print "https://github.com/yui/yuicompressor/releases/download/v%s/yuicompressor-%s.jar" % (YC_VER, YC_VER) + else: + print "Compressing Library..." + f = open('Jit/jit-yc.js', 'w') + f.write(license) + f.close() + system('java -jar Extras/' + YC + ' Jit/jit.js >> Jit/jit-yc.js') + print "Done." + + print "Zipping..." system('rm Jit.zip') system('zip -r Jit.zip Jit/') print "Done, I guess." diff --git a/tutorial.txt b/tutorial.txt new file mode 100644 index 0000000..3f05578 --- /dev/null +++ b/tutorial.txt @@ -0,0 +1,14 @@ +============================================== +Little & straightforward howtos +Vanesa G. Pazos +============================================== + + +How to add a new node type +----------------------------------- +1. Modify NodeHelper. +2. Add to different graphs/charts objects: + 2.1. For instance, if you want to add it to Spacetree then add the new node type to $jit.ST.Plot.NodeTypes (class ST.Plot.NodeTypes) + + +