made with requirebin
-
-
Save saga/fd5425388b51023ec943 to your computer and use it in GitHub Desktop.
requirebin sketch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var graph = require('ngraph.generators').noLinks(142); | |
graph.forEachNode(assignNiceColor); | |
var clickMe = document.createElement('h1') | |
clickMe.setAttribute('style', 'font-family: Helvetica, Arial; font-weight: 200; text-align: center; margin-top: 150px;') | |
clickMe.innerHTML = 'CLICK ME' | |
document.body.appendChild(clickMe) | |
var svg = require('ngraph.vivasvg')(graph); | |
svg.nodeTemplate("<circle r='5' fill='{{node.color}}'></circle>"); | |
svg.linkTemplate("<arrow></arrow>'"); | |
function assignNiceColor(node) { | |
var niceColors = ['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78', '#2ca02c', '#98df8a', '#d62728', '#ff9896', '#9467bd', '#c5b0d5', '#8c564b', '#c49c94', '#e377c2', '#f7b6d2', '#7f7f7f', '#c7c7c7', '#bcbd22', '#dbdb8d', '#17becf', '#9edae5']; | |
node.color = niceColors[(Math.random() * niceColors.length)|0]; | |
} | |
document.addEventListener('mousedown', function() { | |
clickMe.setAttribute('style', 'display: none;') | |
svg.run() | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){module.exports=function(){var nodes={},links=[],multiEdges={},nodesCount=0,suspendEvents=0,changes=[],fireGraphChanged=function(graph){graph.fire("changed",changes)},enterModification=function(){suspendEvents+=1},exitModification=function(graph){suspendEvents-=1;if(suspendEvents===0&&changes.length>0){fireGraphChanged(graph);changes.length=0}},recordNodeChange=function(node,changeType){changes.push({node:node,changeType:changeType})},recordLinkChange=function(link,changeType){changes.push({link:link,changeType:changeType})},linkConnectionSymbol="👉 ";var graphPart={addNode:function(nodeId,data){if(typeof nodeId==="undefined"){throw new Error("Invalid node identifier")}enterModification();var node=this.getNode(nodeId);if(!node){node=new Node(nodeId);nodesCount++;recordNodeChange(node,"add")}else{recordNodeChange(node,"update")}node.data=data;nodes[nodeId]=node;exitModification(this);return node},addLink:function(fromId,toId,data){enterModification();var fromNode=this.getNode(fromId)||this.addNode(fromId);var toNode=this.getNode(toId)||this.addNode(toId);var linkId=fromId.toString()+linkConnectionSymbol+toId.toString();var isMultiEdge=multiEdges.hasOwnProperty(linkId);if(isMultiEdge||this.hasLink(fromId,toId)){if(!isMultiEdge){multiEdges[linkId]=0}linkId+="@"+ ++multiEdges[linkId]}var link=new Link(fromId,toId,data,linkId);links.push(link);fromNode.links.push(link);toNode.links.push(link);recordLinkChange(link,"add");exitModification(this);return link},removeLink:function(link){if(!link){return false}var idx=indexOfElementInArray(link,links);if(idx<0){return false}enterModification();links.splice(idx,1);var fromNode=this.getNode(link.fromId);var toNode=this.getNode(link.toId);if(fromNode){idx=indexOfElementInArray(link,fromNode.links);if(idx>=0){fromNode.links.splice(idx,1)}}if(toNode){idx=indexOfElementInArray(link,toNode.links);if(idx>=0){toNode.links.splice(idx,1)}}recordLinkChange(link,"remove");exitModification(this);return true},removeNode:function(nodeId){var node=this.getNode(nodeId);if(!node){return false}enterModification();while(node.links.length){var link=node.links[0];this.removeLink(link)}delete nodes[nodeId];nodesCount--;recordNodeChange(node,"remove");exitModification(this);return true},getNode:function(nodeId){return nodes[nodeId]},getNodesCount:function(){return nodesCount},getLinksCount:function(){return links.length},getLinks:function(nodeId){var node=this.getNode(nodeId);return node?node.links:null},forEachNode:function(callback){if(typeof callback!=="function"){return}var node;for(node in nodes){if(nodes.hasOwnProperty(node)){if(callback(nodes[node])){return}}}},forEachLinkedNode:function(nodeId,callback,oriented){var node=this.getNode(nodeId),i,link,linkedNodeId;if(node&&node.links&&typeof callback==="function"){if(oriented){for(i=0;i<node.links.length;++i){link=node.links[i];if(link.fromId===nodeId){callback(nodes[link.toId],link)}}}else{for(i=0;i<node.links.length;++i){link=node.links[i];linkedNodeId=link.fromId===nodeId?link.toId:link.fromId;callback(nodes[linkedNodeId],link)}}}},forEachLink:function(callback){var i,length;if(typeof callback==="function"){for(i=0,length=links.length;i<length;++i){callback(links[i])}}},beginUpdate:function(){enterModification()},endUpdate:function(){exitModification(this)},clear:function(){var that=this;that.beginUpdate();that.forEachNode(function(node){that.removeNode(node.id)});that.endUpdate()},hasLink:function(fromNodeId,toNodeId){var node=this.getNode(fromNodeId),i;if(!node){return null}for(i=0;i<node.links.length;++i){var link=node.links[i];if(link.fromId===fromNodeId&&link.toId===toNodeId){return link}}return null}};var eventify=require("ngraph.events");eventify(graphPart);return graphPart};function indexOfElementInArray(element,array){if(array.indexOf){return array.indexOf(element)}var len=array.length,i;for(i=0;i<len;i+=1){if(array[i]===element){return i}}return-1}function Node(id){this.id=id;this.links=[];this.data=null}function Link(fromId,toId,data,id){this.fromId=fromId;this.toId=toId;this.data=data;this.id=id}},{"ngraph.events":2}],2:[function(require,module,exports){module.exports=function(subject){validateSubject(subject);var eventsStorage=createEventsStorage(subject);subject.on=eventsStorage.on;subject.off=eventsStorage.off;subject.fire=eventsStorage.fire;return subject};function createEventsStorage(subject){var registeredEvents={};return{on:function(eventName,callback,ctx){if(typeof callback!=="function"){throw new Error("callback is expected to be a function")}if(!registeredEvents.hasOwnProperty(eventName)){registeredEvents[eventName]=[]}registeredEvents[eventName].push({callback:callback,ctx:ctx});return subject},off:function(eventName,callback){var wantToRemoveAll=typeof eventName==="undefined";if(wantToRemoveAll){registeredEvents={};return subject}if(registeredEvents.hasOwnProperty(eventName)){var deleteAllCallbacksForEvent=typeof callback!=="function";if(deleteAllCallbacksForEvent){delete registeredEvents[eventName]}else{var callbacks=registeredEvents[eventName];for(var i=0;i<callbacks.length;++i){if(callbacks[i].callback===callback){callbacks.splice(i,1)}}}}return subject},fire:function(eventName){var noEventsToFire=!registeredEvents.hasOwnProperty(eventName);if(noEventsToFire){return subject}var callbacks=registeredEvents[eventName];var fireArguments=Array.prototype.splice.call(arguments,1);for(var i=0;i<callbacks.length;++i){var callbackInfo=callbacks[i];callbackInfo.callback.apply(callbackInfo.ctx,fireArguments)}return subject}}}function validateSubject(subject){if(!subject){throw new Error("Eventify cannot use falsy object as events subject")}var reservedWords=["on","fire","off"];for(var i=0;i<reservedWords.length;++i){if(subject.hasOwnProperty(reservedWords[i])){throw new Error("Subject cannot be eventified, since it already has property '"+reservedWords[i]+"'")}}}},{}],"ngraph.generators":[function(require,module,exports){module.exports={ladder:ladder,complete:complete,completeBipartite:completeBipartite,balancedBinTree:balancedBinTree,path:path,circularLadder:circularLadder,grid:grid,grid3:grid3,noLinks:noLinks};var createGraph=require("ngraph.graph");function ladder(n){if(!n||n<0){throw new Error("Invalid number of nodes")}var g=createGraph(),i;for(i=0;i<n-1;++i){g.addLink(i,i+1);g.addLink(n+i,n+i+1);g.addLink(i,n+i)}g.addLink(n-1,2*n-1);return g}function circularLadder(n){if(!n||n<0){throw new Error("Invalid number of nodes")}var g=ladder(n);g.addLink(0,n-1);g.addLink(n,2*n-1);return g}function complete(n){if(!n||n<1){throw new Error("At least two nodes are expected for complete graph")}var g=createGraph(),i,j;for(i=0;i<n;++i){for(j=i+1;j<n;++j){if(i!==j){g.addLink(i,j);g.addLink(j,i)}}}return g}function completeBipartite(n,m){if(!n||!m||n<0||m<0){throw new Error("Graph dimensions are invalid. Number of nodes in each partition should be greate than 0")}var g=createGraph(),i,j;for(i=0;i<n;++i){for(j=n;j<n+m;++j){g.addLink(i,j)}}return g}function path(n){if(!n||n<0){throw new Error("Invalid number of nodes")}var g=createGraph(),i;g.addNode(0);for(i=1;i<n;++i){g.addLink(i-1,i)}return g}function grid(n,m){if(n<1||m<1){throw new Error("Invalid number of nodes in grid graph")}var g=createGraph(),i,j;if(n===1&&m===1){g.addNode(0);return g}for(i=0;i<n;++i){for(j=0;j<m;++j){var node=i+j*n;if(i>0){g.addLink(node,i-1+j*n)}if(j>0){g.addLink(node,i+(j-1)*n)}}}return g}function grid3(n,m,z){if(n<1||m<1||z<1){throw new Error("Invalid number of nodes in grid3 graph")}var g=createGraph(),i,j,k;if(n===1&&m===1&&z===1){g.addNode(0);return g}for(k=0;k<z;++k){for(i=0;i<n;++i){for(j=0;j<m;++j){var level=k*n*m;var node=i+j*n+level;if(i>0){g.addLink(node,i-1+j*n+level)}if(j>0){g.addLink(node,i+(j-1)*n+level)}if(k>0){g.addLink(node,i+j*n+(k-1)*n*m)}}}}return g}function balancedBinTree(n){if(n<0){throw new Error("Invalid number of nodes in balanced tree")}var g=createGraph(),count=Math.pow(2,n),level;if(n===0){g.addNode(1)}for(level=1;level<count;++level){var root=level,left=root*2,right=root*2+1;g.addLink(root,left);g.addLink(root,right)}return g}function noLinks(n){if(n<0){throw new Error("Number of nodes shoul be >= 0")}var g=createGraph(),i;for(i=0;i<n;++i){g.addNode(i)}return g}},{"ngraph.graph":1}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){var vivasvg=require("vivasvg");vivasvg.createTag("arrow",{_appendToDom:function(parentDom){this._dom=compileMarkup(this._markup,this._dataContext,this);parentDom.appendChild(this._dom)}});function compileMarkup(markup,model,arrow){var path=arrow.createElement("path");var bindingParser=vivasvg.bindingParser(model);var strokeValue=markup.getAttributeNS(null,"stroke");var sourceBinding=bindingParser.parse(strokeValue);if(sourceBinding){path.setAttributeNS(null,"stroke",sourceBinding.provide())}else if(strokeValue){path.setAttributeNS(null,"stroke",strokeValue)}var arrowId=addArrowTriangle(arrow,strokeValue);var from=bindingParser.parse(markup.getAttributeNS(null,"from"));var to=bindingParser.parse(markup.getAttributeNS(null,"to"));var fromSeg,toSeg;if(from&&to){var source=from.provide();var dest=to.provide();from.on("from",onPositionPropertyChanged);to.on("to",onPositionPropertyChanged);fromSeg=path.createSVGPathSegMovetoAbs(source.x,source.y);toSeg=path.createSVGPathSegLinetoAbs(dest.x,dest.y);path.pathSegList.appendItem(fromSeg);path.pathSegList.appendItem(toSeg)}path.setAttributeNS(null,"marker-end","url(#"+arrowId+")");var offsetValue=parseFloat(markup.getAttributeNS(null,"offset"))||0;return path;function onPositionPropertyChanged(){renderPath(from.provide(),to.provide())}function renderPath(source,dest){var dx=0,dy=0;if(offsetValue){dx=source.x-dest.x;dy=source.y-dest.y;var length=Math.sqrt(dx*dx+dy*dy);dx=offsetValue*dx/length;dy=offsetValue*dy/length}fromSeg.x=source.x-dx;fromSeg.y=source.y-dy;toSeg.x=dest.x+dx;toSeg.y=dest.y+dy}}function addArrowTriangle(arrow,color){var ownerDocument=arrow.getOwnerDocument(arrow);var id="ArrowAugmented"+color;if(ownerDocument&&!ownerDocument[id]){ownerDocument.addDef('<marker id="'+id+'" viewBox="0 0 10 10" refX="8" refY="5" markerUnits="strokeWidth" markerWidth="10" markerHeight="5" orient="auto" style="fill: '+color+'"><path d="M 0 0 L 10 5 L 0 10 z"></path></marker>');ownerDocument[id]=true}return id}},{vivasvg:23}],2:[function(require,module,exports){module.exports=function(domContainer){var events=require("ngraph.events"),domCallbacks={};emitter=events({});if(!domContainer){return emitter}var addWheelListner=require("wheel");addWheelListner(domContainer,proxyWheel);var prefix="",_addEventListener,_removeEventListener;if(window.addEventListener){_addEventListener="addEventListener";_removeEventListener="removeEventListener"}else{_addEventListener="attachEvent";_removeEventListener="detachEvent";prefix="on"}var mouseEvents=["mousedown","mousemove","mouseup"];mouseEvents.forEach(proxyEvent);emitter.dispose=function(){emitter.off();for(var eventName in domCallbacks){if(domCallbacks.hasOwnProperty(eventName)){domContainer[_removeEventListener](prefix+eventName,domCallbacks[eventName])}}domContainer[_removeEventListener]("wheel",proxyWheel)};return emitter;function proxyEvent(eventName){domCallbacks[eventName]=function(e){emitter.fire(eventName,e)};domContainer[_addEventListener](prefix+eventName,domCallbacks[eventName])}function proxyWheel(e){emitter.fire("wheel",e)}}},{"ngraph.events":5,wheel:39}],3:[function(require,module,exports){module.exports=zoomPan;var domEvents=require("./domEvents");function zoomPan(domRoot,matrix){var input=domEvents(domRoot);var isDragging=false;var prevX;var prevY;input.on("wheel",onWheel);input.on("mousemove",onMouseMove);input.on("mousedown",onMouseDown);input.on("mouseup",onMouseUp);return{zoom:zoom,pan:pan,dispose:function(){input.dispose()}};function onWheel(e){var isZoomIn=e.deltaY<0;var direction=isZoomIn?1:-1;var factor=1+direction*.1;zoom(e.clientX,e.clientY,factor)}function onMouseDown(e){isDragging=true;prevX=e.clientX;prevY=e.clientY}function onMouseMove(e){if(!isDragging)return;var offsetX=e.clientX-prevX;var offsetY=e.clientY-prevY;pan(matrix.e+offsetX,matrix.f+offsetY);prevX=e.clientX;prevY=e.clientY;e.preventDefault()}function onMouseUp(e){isDragging=false}function zoom(x,y,factor){matrix.e=x-factor*(x-matrix.e);matrix.f=y-factor*(y-matrix.f);var scale=matrix.a*factor;matrix.a=matrix.d=scale}function pan(x,y){matrix.e=x;matrix.f=y}}},{"./domEvents":2}],4:[function(require,module,exports){var vivasvg=require("vivasvg");var zoomPan=require("./input/zoomPan");module.exports=vivasvg.createTag("zoomer",{_appendToDom:function(parentDom){var g=this.createElement("g");var svgRoot=this.getOwnerDocument()._dom;var transform=svgRoot.createSVGTransform();if(this._initialTransform){transform.setTranslate(this._initialTransform.x,this._initialTransform.y);var scale=this._initialTransform.scale;transform.a=transform.d=scale}g.transform.baseVal.appendItem(transform);this._dom=g;parentDom.appendChild(this._dom);this._transform=transform.matrix;this._zoomPan=zoomPan(svgRoot,transform.matrix)},_dispose:function(){if(this._zoomPan){this._zoomPan.dispose()}if(this._children){this._children.forEach(function disposeChild(child){child._dispose()})}},moveTo:function(x,y){if(this._zoomPan){this._zoomPan.pan(x,y)}else if(this._initialTransform){this._initialTransform.x=x;this._initialTransform.y=y}else{this._initialTransform={x:x,y:y,scale:1}}},scale:function(x,y,factor){if(this._zoomPan){this._zoomPan.zoom(x,y,factor)}else if(this._initialTransform){this._initialTransform.x=x;this._initialTransform.y=y;this._initialTransform.scale=scale}else{this._initialTransform={x:x,y:y,scale:scale}}},getModelPosition:function(x,y){if(!this._transform)return;var m=this._transform;var scaleLevel=m.a;return{x:(x-m.e)/scaleLevel,y:(y-m.f)/scaleLevel}}})},{"./input/zoomPan":3,vivasvg:23}],5:[function(require,module,exports){module.exports=function(subject){validateSubject(subject);var eventsStorage=createEventsStorage(subject);subject.on=eventsStorage.on;subject.off=eventsStorage.off;subject.fire=eventsStorage.fire;return subject};function createEventsStorage(subject){var registeredEvents={};return{on:function(eventName,callback,ctx){if(typeof callback!=="function"){throw new Error("callback is expected to be a function")}if(!registeredEvents.hasOwnProperty(eventName)){registeredEvents[eventName]=[]}registeredEvents[eventName].push({callback:callback,ctx:ctx});return subject},off:function(eventName,callback){var wantToRemoveAll=typeof eventName==="undefined";if(wantToRemoveAll){registeredEvents={};return subject}if(registeredEvents.hasOwnProperty(eventName)){var deleteAllCallbacksForEvent=typeof callback!=="function";if(deleteAllCallbacksForEvent){delete registeredEvents[eventName]}else{var callbacks=registeredEvents[eventName];for(var i=0;i<callbacks.length;++i){if(callbacks[i].callback===callback){callbacks.splice(i,1)}}}}return subject},fire:function(eventName){var noEventsToFire=!registeredEvents.hasOwnProperty(eventName);if(noEventsToFire){return subject}var callbacks=registeredEvents[eventName];var fireArguments;if(arguments.length>1){fireArguments=Array.prototype.splice.call(arguments,1)}for(var i=0;i<callbacks.length;++i){var callbackInfo=callbacks[i];callbackInfo.callback.apply(callbackInfo.ctx,fireArguments)}return subject}}}function validateSubject(subject){if(!subject){throw new Error("Eventify cannot use falsy object as events subject")}var reservedWords=["on","fire","off"];for(var i=0;i<reservedWords.length;++i){if(subject.hasOwnProperty(reservedWords[i])){throw new Error("Subject cannot be eventified, since it already has property '"+reservedWords[i]+"'")}}}},{}],6:[function(require,module,exports){module.exports=createLayout;var MAX_MOVEMENT=.001;function createLayout(graph,physicsSimulator){if(!graph){throw new Error("Graph structure cannot be undefined")}var simulator=require("ngraph.physics.simulator"),physics=require("ngraph.physics.primitives");physicsSimulator=physicsSimulator||simulator();var nodeBodies={},springs={};initPhysics();listenToGraphEvents();return{step:function(){var totalMovement=physicsSimulator.step();return totalMovement<MAX_MOVEMENT},getNodePosition:function(nodeId){return getInitializedBody(nodeId).pos},setNodePosition:function(nodeId,x,y){var body=getInitializedBody(nodeId);body.prevPos.x=body.pos.x=x;body.prevPos.y=body.pos.y=y},getLinkPosition:function(linkId){var spring=springs[linkId];if(spring){return{from:spring.from.pos,to:spring.to.pos}}},getGraphRect:function(){return physicsSimulator.getBBox()},pinNode:function(node,isPinned){var body=getInitializedBody(node.id);body.isPinned=!!isPinned},isNodePinned:function(node){return getInitializedBody(node.id).isPinned},dispose:function(){graph.off("changed",onGraphChanged)},simulator:physicsSimulator};function listenToGraphEvents(){graph.on("changed",onGraphChanged)}function onGraphChanged(changes){for(var i=0;i<changes.length;++i){var change=changes[i];if(change.changeType==="add"){if(change.node){initBody(change.node.id)}if(change.link){initLink(change.link)}}else if(change.changeType==="remove"){if(change.node){releaseNode(change.node)}if(change.link){releaseLink(change.link)}}}}function initPhysics(){graph.forEachNode(function(node){initBody(node.id)});graph.forEachLink(initLink)}function initBody(nodeId){var body=nodeBodies[nodeId];if(!body){var node=graph.getNode(nodeId);if(!node){throw new Error("initBody() was called with unknown node id")}var pos=node.position;if(!pos){var neighbors=getNeighborBodies(node);pos=physicsSimulator.getBestNewBodyPosition(neighbors)}body=physicsSimulator.addBodyAt(pos);nodeBodies[nodeId]=body;updateBodyMass(nodeId);if(isNodeOriginallyPinned(node)){body.isPinned=true}}}function releaseNode(node){var nodeId=node.id;var body=nodeBodies[nodeId];if(body){nodeBodies[nodeId]=null;delete nodeBodies[nodeId];physicsSimulator.removeBody(body)}}function initLink(link){updateBodyMass(link.fromId);updateBodyMass(link.toId);var fromBody=nodeBodies[link.fromId],toBody=nodeBodies[link.toId],spring=physicsSimulator.addSpring(fromBody,toBody,link.length);springs[link.id]=spring}function releaseLink(link){var spring=springs[link.id];if(spring){var from=graph.getNode(link.fromId),to=graph.getNode(link.toId);if(from)updateBodyMass(from.id);if(to)updateBodyMass(to.id);delete springs[link.id];physicsSimulator.removeSpring(spring)}}function getNeighborBodies(node){var neighbors=[];if(!node.links){return neighbors}var maxNeighbors=Math.min(node.links.length,2);for(var i=0;i<maxNeighbors;++i){var link=node.links[i];var otherBody=link.fromId!==node.id?nodeBodies[link.fromId]:nodeBodies[link.toId];if(otherBody&&otherBody.pos){neighbors.push(otherBody)}}return neighbors}function updateBodyMass(nodeId){var body=nodeBodies[nodeId];body.mass=nodeMass(nodeId)}function isNodeOriginallyPinned(node){return node&&(node.isPinned||node.data&&node.data.isPinned)}function getInitializedBody(nodeId){var body=nodeBodies[nodeId];if(!body){initBody(nodeId);body=nodeBodies[nodeId]}return body}function nodeMass(nodeId){return 1+graph.getLinks(nodeId).length/3}}},{"ngraph.physics.primitives":7,"ngraph.physics.simulator":9}],7:[function(require,module,exports){module.exports={Body:Body,Vector2d:Vector2d,Body3d:Body3d,Vector3d:Vector3d};function Body(x,y){this.pos=new Vector2d(x,y);this.prevPos=new Vector2d(x,y);this.force=new Vector2d;this.velocity=new Vector2d;this.mass=1}Body.prototype.setPosition=function(x,y){this.prevPos.x=this.pos.x=x;this.prevPos.y=this.pos.y=y};function Vector2d(x,y){if(x&&typeof x!=="number"){this.x=typeof x.x==="number"?x.x:0;this.y=typeof x.y==="number"?x.y:0}else{this.x=typeof x==="number"?x:0;this.y=typeof y==="number"?y:0}}Vector2d.prototype.reset=function(){this.x=this.y=0};function Body3d(x,y,z){this.pos=new Vector3d(x,y,z);this.prevPos=new Vector3d(x,y,z);this.force=new Vector3d;this.velocity=new Vector3d;this.mass=1}Body3d.prototype.setPosition=function(x,y,z){this.prevPos.x=this.pos.x=x;this.prevPos.y=this.pos.y=y;this.prevPos.z=this.pos.z=z};function Vector3d(x,y,z){if(x&&typeof x!=="number"){this.x=typeof x.x==="number"?x.x:0;this.y=typeof x.y==="number"?x.y:0;this.z=typeof x.z==="number"?x.z:0}else{this.x=typeof x==="number"?x:0;this.y=typeof y==="number"?y:0;this.z=typeof z==="number"?z:0}}Vector3d.prototype.reset=function(){this.x=this.y=this.z=0}},{}],8:[function(require,module,exports){module.exports=merge;function merge(target,options){var key;if(!target){target={}}if(options){for(key in options){if(options.hasOwnProperty(key)){var targetHasIt=target.hasOwnProperty(key),optionsValueType=typeof options[key],shouldReplace=!targetHasIt||typeof target[key]!==optionsValueType;if(shouldReplace){target[key]=options[key]}else if(optionsValueType==="object"){target[key]=merge(target[key],options[key])}}}}return target}},{}],9:[function(require,module,exports){module.exports=physicsSimulator;function physicsSimulator(settings){var Spring=require("./lib/spring");var expose=require("ngraph.expose");var merge=require("ngraph.merge");settings=merge(settings,{springLength:30,springCoeff:8e-4,gravity:-1.2,theta:.8,dragCoeff:.02,timeStep:20});var createQuadTree=settings.createQuadTree||require("ngraph.quadtreebh");var createBounds=settings.createBounds||require("./lib/bounds");var createDragForce=settings.createDragForce||require("./lib/dragForce");var createSpringForce=settings.createSpringForce||require("./lib/springForce");var integrate=settings.integrator||require("./lib/eulerIntegrator");var createBody=settings.createBody||require("./lib/createBody");var bodies=[],springs=[],quadTree=createQuadTree(settings),bounds=createBounds(bodies,settings),springForce=createSpringForce(settings),dragForce=createDragForce(settings);var publicApi={bodies:bodies,step:function(){accumulateForces();var totalMovement=integrate(bodies,settings.timeStep);bounds.update();return totalMovement},addBody:function(body){if(!body){throw new Error("Body is required")}bodies.push(body);return body},addBodyAt:function(pos){if(!pos){throw new Error("Body position is required")}var body=createBody(pos);bodies.push(body);return body},removeBody:function(body){if(!body){return}var idx=bodies.indexOf(body);if(idx<0){return}bodies.splice(idx,1);if(bodies.length===0){bounds.reset()}return true},addSpring:function(body1,body2,springLength,springWeight,springCoefficient){if(!body1||!body2){throw new Error("Cannot add null spring to force simulator")}if(typeof springLength!=="number"){springLength=-1}var spring=new Spring(body1,body2,springLength,springCoefficient>=0?springCoefficient:-1,springWeight);springs.push(spring);return spring},removeSpring:function(spring){if(!spring){return}var idx=springs.indexOf(spring);if(idx>-1){springs.splice(idx,1);return true}},getBestNewBodyPosition:function(neighbors){return bounds.getBestNewPosition(neighbors)},getBBox:function(){return bounds.box},gravity:function(value){if(value!==undefined){settings.gravity=value;quadTree.options({gravity:value});return this}else{return settings.gravity}},theta:function(value){if(value!==undefined){settings.theta=value;quadTree.options({theta:value});return this}else{return settings.theta}}};expose(settings,publicApi);return publicApi;function accumulateForces(){var body,i=bodies.length;if(i){quadTree.insertBodies(bodies);while(i--){body=bodies[i];body.force.reset();quadTree.updateBodyForce(body);dragForce.update(body)}}i=springs.length;while(i--){springForce.update(springs[i])}}}},{"./lib/bounds":10,"./lib/createBody":11,"./lib/dragForce":12,"./lib/eulerIntegrator":13,"./lib/spring":14,"./lib/springForce":15,"ngraph.expose":16,"ngraph.merge":8,"ngraph.quadtreebh":18}],10:[function(require,module,exports){module.exports=function(bodies,settings){var random=require("ngraph.random").random(42);var boundingBox={x1:0,y1:0,x2:0,y2:0};return{box:boundingBox,update:updateBoundingBox,reset:function(){boundingBox.x1=boundingBox.y1=0;boundingBox.x2=boundingBox.y2=0},getBestNewPosition:function(neighbors){var graphRect=boundingBox;var baseX=0,baseY=0;if(neighbors.length){for(var i=0;i<neighbors.length;++i){baseX+=neighbors[i].pos.x;baseY+=neighbors[i].pos.y}baseX/=neighbors.length;baseY/=neighbors.length}else{baseX=(graphRect.x1+graphRect.x2)/2;baseY=(graphRect.y1+graphRect.y2)/2}var springLength=settings.springLength;return{x:baseX+random.next(springLength)-springLength/2,y:baseY+random.next(springLength)-springLength/2}}};function updateBoundingBox(){var i=bodies.length;if(i===0){return}var x1=Number.MAX_VALUE,y1=Number.MAX_VALUE,x2=Number.MIN_VALUE,y2=Number.MIN_VALUE;while(i--){var body=bodies[i];if(body.isPinned){body.pos.x=body.prevPos.x;body.pos.y=body.prevPos.y}else{body.prevPos.x=body.pos.x;body.prevPos.y=body.pos.y}if(body.pos.x<x1){x1=body.pos.x}if(body.pos.x>x2){x2=body.pos.x}if(body.pos.y<y1){y1=body.pos.y}if(body.pos.y>y2){y2=body.pos.y}}boundingBox.x1=x1;boundingBox.x2=x2;boundingBox.y1=y1;boundingBox.y2=y2}}},{"ngraph.random":22}],11:[function(require,module,exports){var physics=require("ngraph.physics.primitives");module.exports=function(pos){return new physics.Body(pos)}},{"ngraph.physics.primitives":17}],12:[function(require,module,exports){module.exports=function(options){var merge=require("ngraph.merge"),expose=require("ngraph.expose");options=merge(options,{dragCoeff:.02});var api={update:function(body){body.force.x-=options.dragCoeff*body.velocity.x;body.force.y-=options.dragCoeff*body.velocity.y}};expose(options,api,["dragCoeff"]);return api}},{"ngraph.expose":16,"ngraph.merge":8}],13:[function(require,module,exports){module.exports=integrate;function integrate(bodies,timeStep){var dx=0,tx=0,dy=0,ty=0,i,max=bodies.length;for(i=0;i<max;++i){var body=bodies[i],coeff=timeStep/body.mass;body.velocity.x+=coeff*body.force.x;body.velocity.y+=coeff*body.force.y;var vx=body.velocity.x,vy=body.velocity.y,v=Math.sqrt(vx*vx+vy*vy);if(v>1){body.velocity.x=vx/v;body.velocity.y=vy/v}dx=timeStep*body.velocity.x;dy=timeStep*body.velocity.y;body.pos.x+=dx;body.pos.y+=dy;tx+=dx;ty+=dy}return(tx*tx+ty*ty)/bodies.length}},{}],14:[function(require,module,exports){module.exports=Spring;function Spring(fromBody,toBody,length,coeff,weight){this.from=fromBody;this.to=toBody;this.length=length;this.coeff=coeff;this.weight=typeof weight==="number"?weight:1}},{}],15:[function(require,module,exports){module.exports=function(options){var merge=require("ngraph.merge");var random=require("ngraph.random").random(42);var expose=require("ngraph.expose");options=merge(options,{springCoeff:2e-4,springLength:80});var api={update:function(spring){var body1=spring.from,body2=spring.to,length=spring.length<0?options.springLength:spring.length,dx=body2.pos.x-body1.pos.x,dy=body2.pos.y-body1.pos.y,r=Math.sqrt(dx*dx+dy*dy);if(r===0){dx=(random.nextDouble()-.5)/50;dy=(random.nextDouble()-.5)/50;r=Math.sqrt(dx*dx+dy*dy)}var d=r-length;var coeff=(!spring.coeff||spring.coeff<0?options.springCoeff:spring.coeff)*d/r*spring.weight;body1.force.x+=coeff*dx;body1.force.y+=coeff*dy;body2.force.x-=coeff*dx;body2.force.y-=coeff*dy}};expose(options,api,["springCoeff","springLength"]);return api}},{"ngraph.expose":16,"ngraph.merge":8,"ngraph.random":22}],16:[function(require,module,exports){module.exports=exposeProperties;function exposeProperties(settings,target,filter){var needsFilter=Object.prototype.toString.call(filter)==="[object Array]";if(needsFilter){for(var i=0;i<filter.length;++i){augment(settings,target,filter[i])}}else{for(var key in settings){augment(settings,target,key)}}}function augment(source,target,key){if(source.hasOwnProperty(key)){if(typeof target[key]==="function"){return}target[key]=function(value){if(value!==undefined){source[key]=value;return target}return source[key]}}}},{}],17:[function(require,module,exports){module.exports={Body:Body,Vector2d:Vector2d,Body3d:Body3d,Vector3d:Vector3d};function Body(x,y){this.pos=new Vector2d(x,y);this.prevPos=new Vector2d(x,y);this.force=new Vector2d;this.velocity=new Vector2d;this.mass=1}function Vector2d(x,y){if(x&&typeof x!=="number"){this.x=typeof x.x==="number"?x.x:0;this.y=typeof x.y==="number"?x.y:0}else{this.x=typeof x==="number"?x:0;this.y=typeof y==="number"?y:0}}Vector2d.prototype.reset=function(){this.x=this.y=0};function Body3d(x,y,z){this.pos=new Vector3d(x,y,z);this.prevPos=new Vector3d(x,y,z);this.force=new Vector3d;this.velocity=new Vector3d;this.mass=1}function Vector3d(x,y,z){if(x&&typeof x!=="number"){this.x=typeof x.x==="number"?x.x:0;this.y=typeof x.y==="number"?x.y:0;this.z=typeof x.z==="number"?x.z:0}else{this.x=typeof x==="number"?x:0;this.y=typeof y==="number"?y:0;this.z=typeof z==="number"?z:0}}Vector3d.prototype.reset=function(){this.x=this.y=this.z=0}},{}],18:[function(require,module,exports){module.exports=function(options){options=options||{};options.gravity=typeof options.gravity==="number"?options.gravity:-1;options.theta=typeof options.theta==="number"?options.theta:.8;var random=require("ngraph.random").random(1984),Node=require("./node"),InsertStack=require("./insertStack"),isSamePosition=require("./isSamePosition");var gravity=options.gravity,updateQueue=[],insertStack=new InsertStack,theta=options.theta,nodesCache=[],currentInCache=0,newNode=function(){var node=nodesCache[currentInCache];if(node){node.quads[0]=null;node.quads[1]=null;node.quads[2]=null;node.quads[3]=null;node.body=null;node.mass=node.massX=node.massY=0;node.left=node.right=node.top=node.bottom=0}else{node=new Node;nodesCache[currentInCache]=node}++currentInCache;return node},root=newNode(),insert=function(newBody){insertStack.reset();insertStack.push(root,newBody);while(!insertStack.isEmpty()){var stackItem=insertStack.pop(),node=stackItem.node,body=stackItem.body;if(!node.body){var x=body.pos.x;var y=body.pos.y;node.mass=node.mass+body.mass;node.massX=node.massX+body.mass*x;node.massY=node.massY+body.mass*y;var quadIdx=0,left=node.left,right=(node.right+left)/2,top=node.top,bottom=(node.bottom+top)/2;if(x>right){quadIdx=quadIdx+1;var oldLeft=left;left=right;right=right+(right-oldLeft)}if(y>bottom){quadIdx=quadIdx+2;var oldTop=top;top=bottom;bottom=bottom+(bottom-oldTop)}var child=node.quads[quadIdx];if(!child){child=newNode();child.left=left;child.top=top;child.right=right;child.bottom=bottom;child.body=body;node.quads[quadIdx]=child}else{insertStack.push(child,body)}}else{var oldBody=node.body;node.body=null;if(isSamePosition(oldBody.pos,body.pos)){if(node.right-node.left<1e-8){return}do{var offset=random.nextDouble();var dx=(node.right-node.left)*offset;var dy=(node.bottom-node.top)*offset;oldBody.pos.x=node.left+dx;oldBody.pos.y=node.top+dy}while(isSamePosition(oldBody.pos,body.pos))}insertStack.push(node,oldBody);insertStack.push(node,body)}}},update=function(sourceBody){var queue=updateQueue,v,dx,dy,r,queueLength=1,shiftIdx=0,pushIdx=1;queue[0]=root;while(queueLength){var node=queue[shiftIdx],body=node.body;queueLength-=1;shiftIdx+=1;if(body&&body!==sourceBody){dx=body.pos.x-sourceBody.pos.x;dy=body.pos.y-sourceBody.pos.y;r=Math.sqrt(dx*dx+dy*dy);if(r===0){dx=(random.nextDouble()-.5)/50;dy=(random.nextDouble()-.5)/50;r=Math.sqrt(dx*dx+dy*dy)}v=gravity*body.mass*sourceBody.mass/(r*r*r); | |
sourceBody.force.x+=v*dx;sourceBody.force.y+=v*dy}else{dx=node.massX/node.mass-sourceBody.pos.x;dy=node.massY/node.mass-sourceBody.pos.y;r=Math.sqrt(dx*dx+dy*dy);if(r===0){dx=(random.nextDouble()-.5)/50;dy=(random.nextDouble()-.5)/50;r=Math.sqrt(dx*dx+dy*dy)}if((node.right-node.left)/r<theta){v=gravity*node.mass*sourceBody.mass/(r*r*r);sourceBody.force.x+=v*dx;sourceBody.force.y+=v*dy}else{if(node.quads[0]){queue[pushIdx]=node.quads[0];queueLength+=1;pushIdx+=1}if(node.quads[1]){queue[pushIdx]=node.quads[1];queueLength+=1;pushIdx+=1}if(node.quads[2]){queue[pushIdx]=node.quads[2];queueLength+=1;pushIdx+=1}if(node.quads[3]){queue[pushIdx]=node.quads[3];queueLength+=1;pushIdx+=1}}}}},insertBodies=function(bodies){var x1=Number.MAX_VALUE,y1=Number.MAX_VALUE,x2=Number.MIN_VALUE,y2=Number.MIN_VALUE,i,max=bodies.length;i=max;while(i--){var x=bodies[i].pos.x;var y=bodies[i].pos.y;if(x<x1){x1=x}if(x>x2){x2=x}if(y<y1){y1=y}if(y>y2){y2=y}}var dx=x2-x1,dy=y2-y1;if(dx>dy){y2=y1+dx}else{x2=x1+dy}currentInCache=0;root=newNode();root.left=x1;root.right=x2;root.top=y1;root.bottom=y2;i=max-1;if(i>0){root.body=bodies[i]}while(i--){insert(bodies[i],root)}};return{insertBodies:insertBodies,updateBodyForce:update,options:function(newOptions){if(newOptions){if(typeof newOptions.gravity==="number"){gravity=newOptions.gravity}if(typeof newOptions.theta==="number"){theta=newOptions.theta}return this}return{gravity:gravity,theta:theta}}}}},{"./insertStack":19,"./isSamePosition":20,"./node":21,"ngraph.random":22}],19:[function(require,module,exports){module.exports=InsertStack;function InsertStack(){this.stack=[];this.popIdx=0}InsertStack.prototype={isEmpty:function(){return this.popIdx===0},push:function(node,body){var item=this.stack[this.popIdx];if(!item){this.stack[this.popIdx]=new InsertStackElement(node,body)}else{item.node=node;item.body=body}++this.popIdx},pop:function(){if(this.popIdx>0){return this.stack[--this.popIdx]}},reset:function(){this.popIdx=0}};function InsertStackElement(node,body){this.node=node;this.body=body}},{}],20:[function(require,module,exports){module.exports=function isSamePosition(point1,point2){var dx=Math.abs(point1.x-point2.x);var dy=Math.abs(point1.y-point2.y);return dx<1e-8&&dy<1e-8}},{}],21:[function(require,module,exports){module.exports=function Node(){this.body=null;this.quads=[];this.mass=0;this.massX=0;this.massY=0;this.left=0;this.top=0;this.bottom=0;this.right=0;this.isInternal=false}},{}],22:[function(require,module,exports){module.exports={random:random,randomIterator:randomIterator};function random(inputSeed){var seed=typeof inputSeed==="number"?inputSeed:+new Date;var randomFunc=function(){seed=seed+2127912214+(seed<<12)&4294967295;seed=(seed^3345072700^seed>>>19)&4294967295;seed=seed+374761393+(seed<<5)&4294967295;seed=(seed+3550635116^seed<<9)&4294967295;seed=seed+4251993797+(seed<<3)&4294967295;seed=(seed^3042594569^seed>>>16)&4294967295;return(seed&268435455)/268435456};return{next:function(maxValue){return Math.floor(randomFunc()*maxValue)},nextDouble:function(){return randomFunc()}}}function randomIterator(array,customRandom){var localRandom=customRandom||random();if(typeof localRandom.next!=="function"){throw new Error("customRandom does not match expected API: next() function is missing")}return{forEach:function(callback){var i,j,t;for(i=array.length-1;i>0;--i){j=localRandom.next(i+1);t=array[j];array[j]=array[i];array[i]=t;callback(t)}if(array.length){callback(array[0])}},shuffle:function(){var i,j,t;for(i=array.length-1;i>0;--i){j=localRandom.next(i+1);t=array[j];array[j]=array[i];array[i]=t}return array}}}},{}],23:[function(require,module,exports){module.exports={collection:require("./lib/binding/collection"),model:require("./lib/binding/model"),bindingParser:require("./lib/binding/parser"),bootstrap:require("./lib/bootstrap"),createTag:require("./lib/utils/createTag"),svg:require("./lib/utils/svg")};var controls=require("./lib/controls");Object.keys(controls).forEach(exportControl);function exportControl(name){module.exports[name]=controls[name]}},{"./lib/binding/collection":24,"./lib/binding/model":26,"./lib/binding/parser":27,"./lib/bootstrap":28,"./lib/controls":31,"./lib/utils/createTag":35,"./lib/utils/svg":38}],24:[function(require,module,exports){module.exports=collection;var eventify=require("ngraph.events");function collection(){var source=[];var api={length:0,push:function(item){source.push(item);this.length+=1;api.fire("changed",{added:[item]})},splice:function(idx,count){var removed=source.splice(idx,count);this.length=source.length;api.fire("changed",{removed:removed,removeIdx:idx})},get:function(idx){return source[idx]},forEach:function(callback,thisArg){source.forEach(callback,thisArg)}};eventify(api);return api}},{"ngraph.events":5}],25:[function(require,module,exports){var domEvents=require("../utils/domEvents");module.exports=function(element,bindingParser){var binding;var attributes=element.attributes;if(attributes){for(var i=0;i<attributes.length;++i){var attr=attributes[i];binding=bindingParser.parse(attr.nodeValue);if(binding){if(isEvent(attr.localName)){var eventName=attr.localName.substr(2);var eventHandler=createEventHandler(binding);domEvents.on(element,eventName,eventHandler);binding.off=disposeEventListner(binding,element,eventName,eventHandler);element.removeAttributeNode(attr);i-=1}else{element.setAttributeNS(attr.namespaceURI,attr.localName,binding.provide());var activeProperties=binding.activeProperties;var boundPropertiesCount=activeProperties.length;if(boundPropertiesCount===1){binding.on(activeProperties[0],onAttributeChanged(element,attr,binding))}else if(boundPropertiesCount>1){var propertyChanged=onAttributeChanged(element,attr,binding);for(var j=0;j<boundPropertiesCount;++j){binding.on(activeProperties[j],propertyChanged)}}}}}}if(element.nodeType===3){binding=bindingParser.parse(element.nodeValue);if(binding){element.nodeValue=binding.provide()}}return binding};function disposeEventListner(binding,element,eventName,listener){prevOff=binding.off;return function(){prevOff();domEvents.off(element,eventName,listener)}}function onAttributeChanged(element,attr,binding){return function(){element.setAttributeNS(attr.namespaceURI,attr.localName,binding.provide())}}function createEventHandler(binding){var original=binding.provide();var model=binding.model;return function(e){original(e,model)}}function isEvent(targetName){return targetName.length>2&&targetName[0]==="o"&&targetName[1]==="n"}},{"../utils/domEvents":36}],26:[function(require,module,exports){var eventify=require("ngraph.events");module.exports=function(object){return eventify(object)}},{"ngraph.events":5}],27:[function(require,module,exports){var BINDING_REGEX=/{{(.+?)}}/g;var eventify=require("ngraph.events");module.exports=function(model){var modelIsActive=typeof model.on==="function";var on,off;if(modelIsActive){on=model.on;off=model.off}else{on=off=function(){}}return{parse:function(expression){var match=BINDING_REGEX.exec(expression);if(!match)return;var activeProperties;var moreMatches=BINDING_REGEX.exec(expression);var provider;if(moreMatches){var foundMatches={};activeProperties=[];expression.replace(BINDING_REGEX,function(_,bindingMatch){var modelName=bindingMatch.split(".")[0];if(!foundMatches[modelName]){activeProperties.push(modelName)}foundMatches[modelName]=1});provider=function(){return expression.replace(BINDING_REGEX,function(_,bindingMatch){var modelPropertyPath=bindingMatch.split(".");var localModel=model;for(var i=0;i<modelPropertyPath.length;++i){localModel=localModel[modelPropertyPath[i]];if(!localModel){return undefined}}return localModel})}}else{var modelPropertyPath=match[1].split(".");activeProperties=[modelPropertyPath[0]];if(modelPropertyPath.length===1){provider=function(){return model[modelPropertyPath[0]]}}else{provider=function(){var localModel=model;for(var i=0;i<modelPropertyPath.length;++i){localModel=localModel[modelPropertyPath[i]];if(!localModel){return undefined}}return localModel}}}var api={provide:provider,model:model,activeProperties:activeProperties,on:on,off:off};return api}}}},{"ngraph.events":5}],28:[function(require,module,exports){module.exports=function(domRoot,dataContext){var markup=domRoot.innerHTML;while(domRoot.firstChild){domRoot.removeChild(domRoot.firstChild)}var svgDoc=require("./controls/document")(domRoot);svgDoc.dataContext(dataContext);var contentControl=require("./controls/contentControl")();contentControl.markup(markup);svgDoc.appendChild(contentControl);return svgDoc}},{"./controls/contentControl":29,"./controls/document":30}],29:[function(require,module,exports){var createTag=require("../utils/createTag");var extensions=require("../extensions");module.exports=createTag("content",{_appendToDom:function(parentDom){compileMarkup(this,parentDom)}});function compileMarkup(contentControl,parentDom){var nodes=contentControl._markup;var model=contentControl._dataContext;if(typeof nodes==="string"){nodes=require("../utils/domParser")(nodes)}var bindingParser=require("../binding/parser")(model);var bindElement=require("../binding/element");if(nodes.length===1){contentControl._dom=compileNode(nodes[0],parentDom)}else{var g=contentControl.createElement("g");compileSubtree(nodes,g);parentDom.appendChild(g);contentControl._dom=g}function compileSubtree(nodes,visualParent){for(var i=0;i<nodes.length;++i){compileNode(nodes[i],visualParent)}}function compileNode(nodePrototype,visualParent){var TagCtor=extensions.getTag(nodePrototype.localName);if(TagCtor){var child=new TagCtor;child.markup(nodePrototype);contentControl.appendChild(child,visualParent);return child._dom}else{var node=nodePrototype.cloneNode(false);var binding=bindElement(node,bindingParser);if(binding){contentControl._registerBinding(binding)}visualParent.appendChild(node);var children=nodePrototype.childNodes;if(children&&children.length>0){compileSubtree(children,node)}return node}}}},{"../binding/element":25,"../binding/parser":27,"../extensions":34,"../utils/createTag":35,"../utils/domParser":37}],30:[function(require,module,exports){module.exports=Document;var UIElement=require("./uiElement");function Document(container){if(!(this instanceof Document)){return new Document(container)}UIElement.call(this);this._ownerDocument=this;if(container&&container.localName==="svg"){this._dom=container}else{this._dom=require("../utils/svg")("svg");container.appendChild(this._dom)}}Document.prototype=Object.create(UIElement.prototype);Document.prototype.constructor=Document;Document.prototype.dispose=function(){this._dispose();if(this._dom&&this._dom.parentNode){this._dom.parentNode.removeChild(this._dom)}};Document.prototype.addDef=function(defsMarkup){if(!defsMarkup)throw new Error("DefsMarkup is required argument for Document.addDef() method");var defs=getDefsElement(this._dom);var defContent=require("../utils/domParser")(defsMarkup);for(var i=0;i<defContent.length;++i){defs.appendChild(defContent[i])}};function getDefsElement(svgRoot){var children=svgRoot.childNodes;for(var i=0;i<children.length;++i){if(children[i].localName==="defs")return children[i]}var defs=require("../utils/svg")("defs");svgRoot.appendChild(defs);return defs}},{"../utils/domParser":37,"../utils/svg":38,"./uiElement":33}],31:[function(require,module,exports){module.exports={Document:require("./document"),ItemsControl:require("./itemsControl"),ContentControl:require("./contentControl"),UIElement:require("./uiElement")}},{"./contentControl":29,"./document":30,"./itemsControl":32,"./uiElement":33}],32:[function(require,module,exports){var createTag=require("../utils/createTag");var ContentControl=require("./contentControl");module.exports=createTag("items",{setItemTemplate:function(itemTemplate){this._itemTemplate=itemTemplate;this._nodePrototype=require("../utils/domParser")(itemTemplate)},setItemSource:function(itemSource){this._itemSource=itemSource;if(itemSource&&typeof itemSource.on==="function"){itemSource.on("changed",handleCollectionChanged.bind(this))}},_appendToDom:function(parentDom){this._dom=this.createElement("g");appendChildren(this);parentDom.appendChild(this._dom)},_addItem:function(itemModel){var contentControl=new ContentControl;contentControl.dataContext(itemModel);contentControl.markup(this._nodePrototype);this.appendChild(contentControl)},_removeItems:function(from,count){var removed=this._children.splice(from,count);var dom=this._dom;if(dom){for(var i=0;i<removed.length;++i){dom.removeChild(removed[i]._dom);removed[i]._dispose()}}}});function appendChildren(itemsControl){ensureCanAppendChildren(itemsControl);var itemSource=itemsControl._itemSource;itemSource.forEach(itemsControl._addItem,itemsControl)}function ensureCanAppendChildren(itemsControl){if(itemsControl._markup&&!itemsControl._itemSource){var markup=itemsControl._markup;var source=markup.getAttributeNS(null,"source");var bindingParser=require("../binding/parser")(itemsControl._dataContext);var sourceBinding=bindingParser.parse(source);if(sourceBinding){itemsControl.setItemSource(sourceBinding.provide())}itemsControl.setItemTemplate(markup.innerHTML)}if(!itemsControl._itemSource||!itemsControl._itemTemplate){throw new Error("Can not use items control without itemsSource and itemTemplate")}}function handleCollectionChanged(changeEventArgs){var i;var addedItems=changeEventArgs.added;if(addedItems){for(i=0;i<addedItems.length;++i){this._addItem(addedItems[i])}}var removedItems=changeEventArgs.removed;if(removedItems){var removeIdx=changeEventArgs.removeIdx||0;this._removeItems(removeIdx,removedItems.length)}}},{"../binding/parser":27,"../utils/createTag":35,"../utils/domParser":37,"./contentControl":29}],33:[function(require,module,exports){module.exports=UIElement;function UIElement(){if(!(this instanceof UIElement)){return new UIElement}this._children=null;this._parent=null}UIElement.prototype.render=function(){if(this._children){this._children.forEach(renderChild)}};UIElement.prototype.appendChild=function(child,visualParent){(this._children||(this._children=[])).push(child);child._setParent(this);child._appendToDom(visualParent||this._dom)};UIElement.prototype.removeChild=function(child){if(this._children){var idx=this._children.indexOf(child);if(idx>=0){this._children.splice(idx,1)}}child._dispose();if(child._dom&&this._dom){this._dom.removeChild(child._dom)}};UIElement.prototype.dataContext=function(context){this._dataContext=context};UIElement.prototype.getOwnerDocument=function(){return this._ownerDocument};UIElement.prototype.getVisual=function(){return this._dom};UIElement.prototype.markup=function(markup){this._markup=markup};UIElement.prototype.createElement=function(name){return document.createElementNS("http://www.w3.org/2000/svg",name)};UIElement.prototype._setParent=function(parent){this._parent=parent;this._ownerDocument=parent._ownerDocument;this._inheritDataContext()};UIElement.prototype._appendToDom=function(dom){if(this._dom){dom.appendChild(this._dom)}};UIElement.prototype._dispose=function(){if(this._bindings){this._bindings.forEach(disposeBinding)}if(this._children){this._children.forEach(disposeChild)}};UIElement.prototype._registerBinding=function(binding){(this._bindings||(this._bindings=[])).push(binding)};UIElement.prototype._inheritDataContext=function(){if(!this._dataContext&&this._parent){this._dataContext=this._parent._dataContext}};function renderChild(child){child.render()}function disposeChild(child){child._dispose()}function disposeBinding(binding){binding.off()}},{}],34:[function(require,module,exports){var registeredExtensions={};module.exports.register=function(name,ctor){registeredExtensions[name]=ctor};module.exports.getTag=function(name){return registeredExtensions[name]}},{}],35:[function(require,module,exports){var UIElement=require("../controls/uiElement");var extensions=require("../extensions");var VALID_TAG_NAME=/^\w+$/;module.exports=function(tagName,tagPrototype){if(!VALID_TAG_NAME.test(tagName)){throw new Error("tagName is expected to contain only word characters, but found: "+tagName)}var functionBody=getFunctionTemplate(tagName);var ctor=new Function("base",functionBody)(UIElement);ctor.prototype=Object.create(UIElement.prototype);ctor.prototype.constructor=ctor;Object.keys(tagPrototype).forEach(function(key){ctor.prototype[key]=tagPrototype[key]});if(tagName){extensions.register(tagName,ctor)}return ctor};function getFunctionTemplate(tagName){return["return function "+tagName+" () {","if (!(this instanceof "+tagName+")){"," return new "+tagName+"();","}","base.call(this);","}"].join("\n")}},{"../controls/uiElement":33,"../extensions":34}],36:[function(require,module,exports){var prefix="",addEventListener,removeEventListener;if(typeof window!=="undefined"&&window.addEventListener){addEventListener="addEventListener";removeEventListener="removeEventListener"}else{addEventListener="attachEvent";removeEventListener="detachEvent";prefix="on"}module.exports.on=function(element,eventName,handler){element[addEventListener](prefix+eventName,handler)};module.exports.off=function(element,eventName,handler){element[removeEventListener](prefix+eventName,handler)}},{}],37:[function(require,module,exports){var parser=new DOMParser;module.exports=function(template){return parser.parseFromString('<g xmlns="http://www.w3.org/2000/svg">'+template+"</g>","text/xml").children[0].children}},{}],38:[function(require,module,exports){var svgns="http://www.w3.org/2000/svg";module.exports=function(elementName){return document.createElementNS(svgns,elementName)}},{}],39:[function(require,module,exports){module.exports=addWheelListener;var prefix="",_addEventListener,onwheel,support;if(window.addEventListener){_addEventListener="addEventListener"}else{_addEventListener="attachEvent";prefix="on"}support="onwheel"in document.createElement("div")?"wheel":document.onmousewheel!==undefined?"mousewheel":"DOMMouseScroll";function addWheelListener(elem,callback,useCapture){_addWheelListener(elem,support,callback,useCapture);if(support=="DOMMouseScroll"){_addWheelListener(elem,"MozMousePixelScroll",callback,useCapture)}}function _addWheelListener(elem,eventName,callback,useCapture){elem[_addEventListener](prefix+eventName,support=="wheel"?callback:function(originalEvent){!originalEvent&&(originalEvent=window.event);var event={originalEvent:originalEvent,target:originalEvent.target||originalEvent.srcElement,type:"wheel",deltaMode:originalEvent.type=="MozMousePixelScroll"?0:1,deltaX:0,delatZ:0,preventDefault:function(){originalEvent.preventDefault?originalEvent.preventDefault():originalEvent.returnValue=false}};if(support=="mousewheel"){event.deltaY=-1/40*originalEvent.wheelDelta;originalEvent.wheelDeltaX&&(event.deltaX=-1/40*originalEvent.wheelDeltaX)}else{event.deltaY=originalEvent.detail}return callback(event)},useCapture||false)}},{}],"ngraph.vivasvg":[function(require,module,exports){require("./lib/arrow");var merge=require("ngraph.merge");var vivasvg=require("vivasvg");module.exports=function(graph,settings){settings=merge(settings,{physics:{springLength:30,springCoeff:8e-4,dragCoeff:.01,gravity:-1.2,theta:1}});var container=settings.container||document.body;var svgDoc=new vivasvg.Document(container);var zoomer;var nodes=vivasvg.collection();var edges=vivasvg.collection();var layout=getDefaultLayout();var isStable=false;var disposed=false;var sceneInitialized=false;var _nodeTemplate,_linkTemplate;var draggingNode,dragNodeDx,dragNodeDy;var api={run:animationLoop,renderOneFrame:renderOneFrame,layout:layout,dispose:function(){layout.dispose();svgDoc.dispose();api.off();disposed=true;listenToGraphEvents(false);listenToDomEvents(false)},nodeTemplate:function(template){_nodeTemplate=template},linkTemplate:function(template){_linkTemplate=template}};require("ngraph.events")(api);return api;function animationLoop(){if(disposed)return;requestAnimationFrame(animationLoop);if(!isStable){nowStable=layout.step();renderOneFrame()}}function renderOneFrame(){if(disposed)return;if(!sceneInitialized)initializeScene();nodes.forEach(notifyNodePositionChange);edges.forEach(notifyEdgePositionChange)}function notifyNodePositionChange(node){node.fire("pos")}function notifyEdgePositionChange(edge){edge.fire("from")}function getDefaultLayout(){if(settings.layout)return settings.layout;var createLayout=require("ngraph.forcelayout");var physics=require("ngraph.physics.simulator");return createLayout(graph,physics(settings.physics))}function initializeScene(){sceneInitialized=true;graph.forEachNode(addNode);graph.forEachLink(addLink);var Zoomer=require("./lib/zoomer");zoomer=new Zoomer;zoomer.moveTo(container.clientWidth/2,container.clientHeight/2);svgDoc.appendChild(zoomer);var edgesUI=new vivasvg.ItemsControl;edgesUI.setItemTemplate(_linkTemplate);edgesUI.setItemSource(edges);zoomer.appendChild(edgesUI);var nodesUI=new vivasvg.ItemsControl;nodesUI.setItemTemplate('<g transform="translate({{pos.x}}, {{pos.y}})" onmousedown="{{mousedown}}">'+_nodeTemplate+"</g>");nodesUI.setItemSource(nodes);zoomer.appendChild(nodesUI);listenToGraphEvents(true);listenToDomEvents(true)}function addNode(node){nodes.push(vivasvg.model({pos:layout.getNodePosition(node.id),id:node.id,node:node,mousedown:onMouseDownNode}))}function onMouseUp(e){if(draggingNode){var node=draggingNode.node;layout.pinNode(node,draggingNode.wasPinned)}draggingNode=null}function onMouseDownNode(e,model){draggingNode=model;draggingNode.wasPinned=layout.isNodePinned(model.node);layout.pinNode(model.node,true);var pos=zoomer.getModelPosition(e.clientX,e.clientY);dragNodeDx=pos.x-model.pos.x;dragNodeDy=pos.y-model.pos.y;e.stopPropagation();api.fire("nodeSelected",model.node)}function onMouseMove(e){if(!draggingNode)return;resetStable();var pos=zoomer.getModelPosition(e.clientX,e.clientY);layout.setNodePosition(draggingNode.id,pos.x-dragNodeDx,pos.y-dragNodeDy);notifyNodePositionChange(draggingNode);e.stopPropagation();e.preventDefault()}function removeNode(node){}function addLink(link){edges.push(vivasvg.model({pos:layout.getLinkPosition(link.id),link:link}))}function removeLink(node){}function listenToGraphEvents(isOn){graph[isOn?"on":"off"]("changed",onGraphChanged)}function listenToDomEvents(isOn){var visual=svgDoc.getVisual();var method=isOn?"addEventListener":"removeEventListener";visual[method]("mousemove",onMouseMove);visual[method]("mouseup",onMouseUp)}function onGraphChanged(changes){resetStable();for(var i=0;i<changes.length;++i){var change=changes[i];if(change.changeType==="add"){if(change.node){addNode(change.node)}if(change.link){addLink(change.link)}}else if(change.changeType==="remove"){if(change.node){removeNode(change.node)}if(change.link){removeLink(change.link)}}}}function resetStable(){isStable=false}}},{"./lib/arrow":1,"./lib/zoomer":4,"ngraph.events":5,"ngraph.forcelayout":6,"ngraph.merge":8,"ngraph.physics.simulator":9,vivasvg:23}]},{},[]);var graph=require("ngraph.generators").noLinks(142);graph.forEachNode(assignNiceColor);var clickMe=document.createElement("h1");clickMe.setAttribute("style","font-family: Helvetica, Arial; font-weight: 200; text-align: center; margin-top: 150px;");clickMe.innerHTML="CLICK ME";document.body.appendChild(clickMe);var svg=require("ngraph.vivasvg")(graph);svg.nodeTemplate("<circle r='5' fill='{{node.color}}'></circle>");svg.linkTemplate("<arrow></arrow>'");function assignNiceColor(node){var niceColors=["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"];node.color=niceColors[Math.random()*niceColors.length|0]}document.addEventListener("mousedown",function(){clickMe.setAttribute("style","display: none;");svg.run()}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "requirebin-sketch", | |
"version": "1.0.0", | |
"dependencies": { | |
"ngraph.generators": "0.0.3", | |
"ngraph.vivasvg": "0.0.2" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- contents of this file will be placed inside the <body> --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style type='text/css'>html, body { margin: 0; padding: 0; border: 0; } | |
body, html { height: 100%; width: 100%; }</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment