UNPKG

dagre-d3

Version:

A D3-based renderer for Dagre

117 lines 28.2 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.dagreD3=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r}()({1:[function(require,module,exports){ /** * @license * Copyright (c) 2012-2013 Chris Pettitt * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ module.exports={graphlib:require("./lib/graphlib"),dagre:require("./lib/dagre"),intersect:require("./lib/intersect"),render:require("./lib/render"),util:require("./lib/util"),version:require("./lib/version")}},{"./lib/dagre":8,"./lib/graphlib":9,"./lib/intersect":10,"./lib/render":25,"./lib/util":27,"./lib/version":28}],2:[function(require,module,exports){var util=require("./util");module.exports={default:normal,normal:normal,vee:vee,undirected:undirected};function normal(parent,id,edge,type){var marker=parent.append("marker").attr("id",id).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto");var path=marker.append("path").attr("d","M 0 0 L 10 5 L 0 10 z").style("stroke-width",1).style("stroke-dasharray","1,0");util.applyStyle(path,edge[type+"Style"]);if(edge[type+"Class"]){path.attr("class",edge[type+"Class"])}}function vee(parent,id,edge,type){var marker=parent.append("marker").attr("id",id).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto");var path=marker.append("path").attr("d","M 0 0 L 10 5 L 0 10 L 4 5 z").style("stroke-width",1).style("stroke-dasharray","1,0");util.applyStyle(path,edge[type+"Style"]);if(edge[type+"Class"]){path.attr("class",edge[type+"Class"])}}function undirected(parent,id,edge,type){var marker=parent.append("marker").attr("id",id).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto");var path=marker.append("path").attr("d","M 0 5 L 10 5").style("stroke-width",1).style("stroke-dasharray","1,0");util.applyStyle(path,edge[type+"Style"]);if(edge[type+"Class"]){path.attr("class",edge[type+"Class"])}}},{"./util":27}],3:[function(require,module,exports){var util=require("./util");var d3=require("./d3");var addLabel=require("./label/add-label");module.exports=createClusters;function createClusters(selection,g){var clusters=g.nodes().filter(function(v){return util.isSubgraph(g,v)});var svgClusters=selection.selectAll("g.cluster").data(clusters,function(v){return v});svgClusters.selectAll("*").remove();svgClusters.enter().append("g").attr("class","cluster").attr("id",function(v){var node=g.node(v);return node.id}).style("opacity",0);svgClusters=selection.selectAll("g.cluster");util.applyTransition(svgClusters,g).style("opacity",1);svgClusters.each(function(v){var node=g.node(v);var thisGroup=d3.select(this);d3.select(this).append("rect");var labelGroup=thisGroup.append("g").attr("class","label");addLabel(labelGroup,node,node.clusterLabelPos)});svgClusters.selectAll("rect").each(function(c){var node=g.node(c);var domCluster=d3.select(this);util.applyStyle(domCluster,node.style)});var exitSelection;if(svgClusters.exit){exitSelection=svgClusters.exit()}else{exitSelection=svgClusters.selectAll(null);// empty selection }util.applyTransition(exitSelection,g).style("opacity",0).remove();return svgClusters}},{"./d3":7,"./label/add-label":18,"./util":27}],4:[function(require,module,exports){"use strict";var _=require("./lodash");var addLabel=require("./label/add-label");var util=require("./util");var d3=require("./d3");module.exports=createEdgeLabels;function createEdgeLabels(selection,g){var svgEdgeLabels=selection.selectAll("g.edgeLabel").data(g.edges(),function(e){return util.edgeToId(e)}).classed("update",true);svgEdgeLabels.exit().remove();svgEdgeLabels.enter().append("g").classed("edgeLabel",true).style("opacity",0);svgEdgeLabels=selection.selectAll("g.edgeLabel");svgEdgeLabels.each(function(e){var root=d3.select(this);root.select(".label").remove();var edge=g.edge(e);var label=addLabel(root,g.edge(e),0,0).classed("label",true);var bbox=label.node().getBBox();if(edge.labelId){label.attr("id",edge.labelId)}if(!_.has(edge,"width")){edge.width=bbox.width}if(!_.has(edge,"height")){edge.height=bbox.height}});var exitSelection;if(svgEdgeLabels.exit){exitSelection=svgEdgeLabels.exit()}else{exitSelection=svgEdgeLabels.selectAll(null);// empty selection }util.applyTransition(exitSelection,g).style("opacity",0).remove();return svgEdgeLabels}},{"./d3":7,"./label/add-label":18,"./lodash":21,"./util":27}],5:[function(require,module,exports){"use strict";var _=require("./lodash");var intersectNode=require("./intersect/intersect-node");var util=require("./util");var d3=require("./d3");module.exports=createEdgePaths;function createEdgePaths(selection,g,arrows){var previousPaths=selection.selectAll("g.edgePath").data(g.edges(),function(e){return util.edgeToId(e)}).classed("update",true);var newPaths=enter(previousPaths,g);exit(previousPaths,g);var svgPaths=previousPaths.merge!==undefined?previousPaths.merge(newPaths):previousPaths;util.applyTransition(svgPaths,g).style("opacity",1); // Save DOM element in the path group, and set ID and class svgPaths.each(function(e){var domEdge=d3.select(this);var edge=g.edge(e);edge.elem=this;if(edge.id){domEdge.attr("id",edge.id)}util.applyClass(domEdge,edge["class"],(domEdge.classed("update")?"update ":"")+"edgePath")});svgPaths.selectAll("path.path").each(function(e){var edge=g.edge(e);edge.arrowheadId=_.uniqueId("arrowhead");var domEdge=d3.select(this).attr("marker-end",function(){return"url("+makeFragmentRef(location.href,edge.arrowheadId)+")"}).style("fill","none");util.applyTransition(domEdge,g).attr("d",function(e){return calcPoints(g,e)});util.applyStyle(domEdge,edge.style)});svgPaths.selectAll("defs *").remove();svgPaths.selectAll("defs").each(function(e){var edge=g.edge(e);var arrowhead=arrows[edge.arrowhead];arrowhead(d3.select(this),edge.arrowheadId,edge,"arrowhead")});return svgPaths}function makeFragmentRef(url,fragmentId){var baseUrl=url.split("#")[0];return baseUrl+"#"+fragmentId}function calcPoints(g,e){var edge=g.edge(e);var tail=g.node(e.v);var head=g.node(e.w);var points=edge.points.slice(1,edge.points.length-1);points.unshift(intersectNode(tail,points[0]));points.push(intersectNode(head,points[points.length-1]));return createLine(edge,points)}function createLine(edge,points){var line=(d3.line||d3.svg.line)().x(function(d){return d.x}).y(function(d){return d.y});(line.curve||line.interpolate)(edge.curve);return line(points)}function getCoords(elem){var bbox=elem.getBBox();var matrix=elem.ownerSVGElement.getScreenCTM().inverse().multiply(elem.getScreenCTM()).translate(bbox.width/2,bbox.height/2);return{x:matrix.e,y:matrix.f}}function enter(svgPaths,g){var svgPathsEnter=svgPaths.enter().append("g").attr("class","edgePath").style("opacity",0);svgPathsEnter.append("path").attr("class","path").attr("d",function(e){var edge=g.edge(e);var sourceElem=g.node(e.v).elem;var points=_.range(edge.points.length).map(function(){return getCoords(sourceElem)});return createLine(edge,points)});svgPathsEnter.append("defs");return svgPathsEnter}function exit(svgPaths,g){var svgPathExit=svgPaths.exit();util.applyTransition(svgPathExit,g).style("opacity",0).remove()}},{"./d3":7,"./intersect/intersect-node":14,"./lodash":21,"./util":27}],6:[function(require,module,exports){"use strict";var _=require("./lodash");var addLabel=require("./label/add-label");var util=require("./util");var d3=require("./d3");module.exports=createNodes;function createNodes(selection,g,shapes){var simpleNodes=g.nodes().filter(function(v){return!util.isSubgraph(g,v)});var svgNodes=selection.selectAll("g.node").data(simpleNodes,function(v){return v}).classed("update",true);svgNodes.exit().remove();svgNodes.enter().append("g").attr("class","node").style("opacity",0);svgNodes=selection.selectAll("g.node");svgNodes.each(function(v){var node=g.node(v);var thisGroup=d3.select(this);util.applyClass(thisGroup,node["class"],(thisGroup.classed("update")?"update ":"")+"node");thisGroup.select("g.label").remove();var labelGroup=thisGroup.append("g").attr("class","label");var labelDom=addLabel(labelGroup,node);var shape=shapes[node.shape];var bbox=_.pick(labelDom.node().getBBox(),"width","height");node.elem=this;if(node.id){thisGroup.attr("id",node.id)}if(node.labelId){labelGroup.attr("id",node.labelId)}if(_.has(node,"width")){bbox.width=node.width}if(_.has(node,"height")){bbox.height=node.height}bbox.width+=node.paddingLeft+node.paddingRight;bbox.height+=node.paddingTop+node.paddingBottom;labelGroup.attr("transform","translate("+(node.paddingLeft-node.paddingRight)/2+","+(node.paddingTop-node.paddingBottom)/2+")");var root=d3.select(this);root.select(".label-container").remove();var shapeSvg=shape(root,bbox,node).classed("label-container",true);util.applyStyle(shapeSvg,node.style);var shapeBBox=shapeSvg.node().getBBox();node.width=shapeBBox.width;node.height=shapeBBox.height});var exitSelection;if(svgNodes.exit){exitSelection=svgNodes.exit()}else{exitSelection=svgNodes.selectAll(null);// empty selection }util.applyTransition(exitSelection,g).style("opacity",0).remove();return svgNodes}},{"./d3":7,"./label/add-label":18,"./lodash":21,"./util":27}],7:[function(require,module,exports){ // Stub to get D3 either via NPM or from the global object var d3;if(!d3){if(typeof require==="function"){try{d3=require("d3")}catch(e){ // continue regardless of error }}}if(!d3){d3=window.d3}module.exports=d3},{d3:undefined}],8:[function(require,module,exports){ /* global window */ var dagre;if(typeof require==="function"){try{dagre=require("dagre")}catch(e){ // continue regardless of error }}if(!dagre){dagre=window.dagre}module.exports=dagre},{dagre:undefined}],9:[function(require,module,exports){ /* global window */ var graphlib;if(typeof require==="function"){try{graphlib=require("graphlib")}catch(e){ // continue regardless of error }}if(!graphlib){graphlib=window.graphlib}module.exports=graphlib},{graphlib:undefined}],10:[function(require,module,exports){module.exports={node:require("./intersect-node"),circle:require("./intersect-circle"),ellipse:require("./intersect-ellipse"),polygon:require("./intersect-polygon"),rect:require("./intersect-rect")}},{"./intersect-circle":11,"./intersect-ellipse":12,"./intersect-node":14,"./intersect-polygon":15,"./intersect-rect":16}],11:[function(require,module,exports){var intersectEllipse=require("./intersect-ellipse");module.exports=intersectCircle;function intersectCircle(node,rx,point){return intersectEllipse(node,rx,rx,point)}},{"./intersect-ellipse":12}],12:[function(require,module,exports){module.exports=intersectEllipse;function intersectEllipse(node,rx,ry,point){ // Formulae from: http://mathworld.wolfram.com/Ellipse-LineIntersection.html var cx=node.x;var cy=node.y;var px=cx-point.x;var py=cy-point.y;var det=Math.sqrt(rx*rx*py*py+ry*ry*px*px);var dx=Math.abs(rx*ry*px/det);if(point.x<cx){dx=-dx}var dy=Math.abs(rx*ry*py/det);if(point.y<cy){dy=-dy}return{x:cx+dx,y:cy+dy}}},{}],13:[function(require,module,exports){module.exports=intersectLine; /* * Returns the point at which two lines, p and q, intersect or returns * undefined if they do not intersect. */function intersectLine(p1,p2,q1,q2){ // Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994, // p7 and p473. var a1,a2,b1,b2,c1,c2;var r1,r2,r3,r4;var denom,offset,num;var x,y; // Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x + // b1 y + c1 = 0. a1=p2.y-p1.y;b1=p1.x-p2.x;c1=p2.x*p1.y-p1.x*p2.y; // Compute r3 and r4. r3=a1*q1.x+b1*q1.y+c1;r4=a1*q2.x+b1*q2.y+c1; // Check signs of r3 and r4. If both point 3 and point 4 lie on // same side of line 1, the line segments do not intersect. if(r3!==0&&r4!==0&&sameSign(r3,r4)){return} // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0 a2=q2.y-q1.y;b2=q1.x-q2.x;c2=q2.x*q1.y-q1.x*q2.y; // Compute r1 and r2 r1=a2*p1.x+b2*p1.y+c2;r2=a2*p2.x+b2*p2.y+c2; // Check signs of r1 and r2. If both point 1 and point 2 lie // on same side of second line segment, the line segments do // not intersect. if(r1!==0&&r2!==0&&sameSign(r1,r2)){return} // Line segments intersect: compute intersection point. denom=a1*b2-a2*b1;if(denom===0){return}offset=Math.abs(denom/2); // The denom/2 is to get rounding instead of truncating. It // is added or subtracted to the numerator, depending upon the // sign of the numerator. num=b1*c2-b2*c1;x=num<0?(num-offset)/denom:(num+offset)/denom;num=a2*c1-a1*c2;y=num<0?(num-offset)/denom:(num+offset)/denom;return{x:x,y:y}}function sameSign(r1,r2){return r1*r2>0}},{}],14:[function(require,module,exports){module.exports=intersectNode;function intersectNode(node,point){return node.intersect(point)}},{}],15:[function(require,module,exports){ /* eslint "no-console": off */ var intersectLine=require("./intersect-line");module.exports=intersectPolygon; /* * Returns the point ({x, y}) at which the point argument intersects with the * node argument assuming that it has the shape specified by polygon. */function intersectPolygon(node,polyPoints,point){var x1=node.x;var y1=node.y;var intersections=[];var minX=Number.POSITIVE_INFINITY;var minY=Number.POSITIVE_INFINITY;polyPoints.forEach(function(entry){minX=Math.min(minX,entry.x);minY=Math.min(minY,entry.y)});var left=x1-node.width/2-minX;var top=y1-node.height/2-minY;for(var i=0;i<polyPoints.length;i++){var p1=polyPoints[i];var p2=polyPoints[i<polyPoints.length-1?i+1:0];var intersect=intersectLine(node,point,{x:left+p1.x,y:top+p1.y},{x:left+p2.x,y:top+p2.y});if(intersect){intersections.push(intersect)}}if(!intersections.length){console.log("NO INTERSECTION FOUND, RETURN NODE CENTER",node);return node}if(intersections.length>1){ // More intersections, find the one nearest to edge end point intersections.sort(function(p,q){var pdx=p.x-point.x;var pdy=p.y-point.y;var distp=Math.sqrt(pdx*pdx+pdy*pdy);var qdx=q.x-point.x;var qdy=q.y-point.y;var distq=Math.sqrt(qdx*qdx+qdy*qdy);return distp<distq?-1:distp===distq?0:1})}return intersections[0]}},{"./intersect-line":13}],16:[function(require,module,exports){module.exports=intersectRect;function intersectRect(node,point){var x=node.x;var y=node.y; // Rectangle intersection algorithm from: // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes var dx=point.x-x;var dy=point.y-y;var w=node.width/2;var h=node.height/2;var sx,sy;if(Math.abs(dy)*w>Math.abs(dx)*h){ // Intersection is top or bottom of rect. if(dy<0){h=-h}sx=dy===0?0:h*dx/dy;sy=h}else{ // Intersection is left or right of rect. if(dx<0){w=-w}sx=w;sy=dx===0?0:w*dy/dx}return{x:x+sx,y:y+sy}}},{}],17:[function(require,module,exports){var util=require("../util");module.exports=addHtmlLabel;function addHtmlLabel(root,node){var fo=root.append("foreignObject").attr("width","100000");var div=fo.append("xhtml:div");div.attr("xmlns","http://www.w3.org/1999/xhtml");var label=node.label;switch(typeof label){case"function":div.insert(label);break;case"object": // Currently we assume this is a DOM object. div.insert(function(){return label});break;default:div.html(label)}util.applyStyle(div,node.labelStyle);div.style("display","inline-block"); // Fix for firefox div.style("white-space","nowrap");var client=div.node().getBoundingClientRect();fo.attr("width",client.width).attr("height",client.height);return fo}},{"../util":27}],18:[function(require,module,exports){var addTextLabel=require("./add-text-label");var addHtmlLabel=require("./add-html-label");var addSVGLabel=require("./add-svg-label");module.exports=addLabel;function addLabel(root,node,location){var label=node.label;var labelSvg=root.append("g"); // Allow the label to be a string, a function that returns a DOM element, or // a DOM element itself. if(node.labelType==="svg"){addSVGLabel(labelSvg,node)}else if(typeof label!=="string"||node.labelType==="html"){addHtmlLabel(labelSvg,node)}else{addTextLabel(labelSvg,node)}var labelBBox=labelSvg.node().getBBox();var y;switch(location){case"top":y=-node.height/2;break;case"bottom":y=node.height/2-labelBBox.height;break;default:y=-labelBBox.height/2}labelSvg.attr("transform","translate("+-labelBBox.width/2+","+y+")");return labelSvg}},{"./add-html-label":17,"./add-svg-label":19,"./add-text-label":20}],19:[function(require,module,exports){var util=require("../util");module.exports=addSVGLabel;function addSVGLabel(root,node){var domNode=root;domNode.node().appendChild(node.label);util.applyStyle(domNode,node.labelStyle);return domNode}},{"../util":27}],20:[function(require,module,exports){var util=require("../util");module.exports=addTextLabel; /* * Attaches a text label to the specified root. Handles escape sequences. */function addTextLabel(root,node){var domNode=root.append("text");var lines=processEscapeSequences(node.label).split("\n");for(var i=0;i<lines.length;i++){domNode.append("tspan").attr("xml:space","preserve").attr("dy","1em").attr("x","1").text(lines[i])}util.applyStyle(domNode,node.labelStyle);return domNode}function processEscapeSequences(text){var newText="";var escaped=false;var ch;for(var i=0;i<text.length;++i){ch=text[i];if(escaped){switch(ch){case"n":newText+="\n";break;default:newText+=ch}escaped=false}else if(ch==="\\"){escaped=true}else{newText+=ch}}return newText}},{"../util":27}],21:[function(require,module,exports){ /* global window */ var lodash;if(typeof require==="function"){try{lodash={defaults:require("lodash/defaults"),each:require("lodash/each"),isFunction:require("lodash/isFunction"),isPlainObject:require("lodash/isPlainObject"),pick:require("lodash/pick"),has:require("lodash/has"),range:require("lodash/range"),uniqueId:require("lodash/uniqueId")}}catch(e){ // continue regardless of error }}if(!lodash){lodash=window._}module.exports=lodash},{"lodash/defaults":undefined,"lodash/each":undefined,"lodash/has":undefined,"lodash/isFunction":undefined,"lodash/isPlainObject":undefined,"lodash/pick":undefined,"lodash/range":undefined,"lodash/uniqueId":undefined}],22:[function(require,module,exports){"use strict";var util=require("./util");var d3=require("./d3");module.exports=positionClusters;function positionClusters(selection,g){var created=selection.filter(function(){return!d3.select(this).classed("update")});function translate(v){var node=g.node(v);return"translate("+node.x+","+node.y+")"}created.attr("transform",translate);util.applyTransition(selection,g).style("opacity",1).attr("transform",translate);util.applyTransition(created.selectAll("rect"),g).attr("width",function(v){return g.node(v).width}).attr("height",function(v){return g.node(v).height}).attr("x",function(v){var node=g.node(v);return-node.width/2}).attr("y",function(v){var node=g.node(v);return-node.height/2})}},{"./d3":7,"./util":27}],23:[function(require,module,exports){"use strict";var util=require("./util");var d3=require("./d3");var _=require("./lodash");module.exports=positionEdgeLabels;function positionEdgeLabels(selection,g){var created=selection.filter(function(){return!d3.select(this).classed("update")});function translate(e){var edge=g.edge(e);return _.has(edge,"x")?"translate("+edge.x+","+edge.y+")":""}created.attr("transform",translate);util.applyTransition(selection,g).style("opacity",1).attr("transform",translate)}},{"./d3":7,"./lodash":21,"./util":27}],24:[function(require,module,exports){"use strict";var util=require("./util");var d3=require("./d3");module.exports=positionNodes;function positionNodes(selection,g){var created=selection.filter(function(){return!d3.select(this).classed("update")});function translate(v){var node=g.node(v);return"translate("+node.x+","+node.y+")"}created.attr("transform",translate);util.applyTransition(selection,g).style("opacity",1).attr("transform",translate)}},{"./d3":7,"./util":27}],25:[function(require,module,exports){var _=require("./lodash");var d3=require("./d3");var layout=require("./dagre").layout;module.exports=render; // This design is based on http://bost.ocks.org/mike/chart/. function render(){var createNodes=require("./create-nodes");var createClusters=require("./create-clusters");var createEdgeLabels=require("./create-edge-labels");var createEdgePaths=require("./create-edge-paths");var positionNodes=require("./position-nodes");var positionEdgeLabels=require("./position-edge-labels");var positionClusters=require("./position-clusters");var shapes=require("./shapes");var arrows=require("./arrows");var fn=function(svg,g){preProcessGraph(g);var outputGroup=createOrSelectGroup(svg,"output");var clustersGroup=createOrSelectGroup(outputGroup,"clusters");var edgePathsGroup=createOrSelectGroup(outputGroup,"edgePaths");var edgeLabels=createEdgeLabels(createOrSelectGroup(outputGroup,"edgeLabels"),g);var nodes=createNodes(createOrSelectGroup(outputGroup,"nodes"),g,shapes);layout(g);positionNodes(nodes,g);positionEdgeLabels(edgeLabels,g);createEdgePaths(edgePathsGroup,g,arrows);var clusters=createClusters(clustersGroup,g);positionClusters(clusters,g);postProcessGraph(g)};fn.createNodes=function(value){if(!arguments.length)return createNodes;createNodes=value;return fn};fn.createClusters=function(value){if(!arguments.length)return createClusters;createClusters=value;return fn};fn.createEdgeLabels=function(value){if(!arguments.length)return createEdgeLabels;createEdgeLabels=value;return fn};fn.createEdgePaths=function(value){if(!arguments.length)return createEdgePaths;createEdgePaths=value;return fn};fn.shapes=function(value){if(!arguments.length)return shapes;shapes=value;return fn};fn.arrows=function(value){if(!arguments.length)return arrows;arrows=value;return fn};return fn}var NODE_DEFAULT_ATTRS={paddingLeft:10,paddingRight:10,paddingTop:10,paddingBottom:10,rx:0,ry:0,shape:"rect"};var EDGE_DEFAULT_ATTRS={arrowhead:"normal",curve:d3.curveLinear};function preProcessGraph(g){g.nodes().forEach(function(v){var node=g.node(v);if(!_.has(node,"label")&&!g.children(v).length){node.label=v}if(_.has(node,"paddingX")){_.defaults(node,{paddingLeft:node.paddingX,paddingRight:node.paddingX})}if(_.has(node,"paddingY")){_.defaults(node,{paddingTop:node.paddingY,paddingBottom:node.paddingY})}if(_.has(node,"padding")){_.defaults(node,{paddingLeft:node.padding,paddingRight:node.padding,paddingTop:node.padding,paddingBottom:node.padding})}_.defaults(node,NODE_DEFAULT_ATTRS);_.each(["paddingLeft","paddingRight","paddingTop","paddingBottom"],function(k){node[k]=Number(node[k])}); // Save dimensions for restore during post-processing if(_.has(node,"width")){node._prevWidth=node.width}if(_.has(node,"height")){node._prevHeight=node.height}});g.edges().forEach(function(e){var edge=g.edge(e);if(!_.has(edge,"label")){edge.label=""}_.defaults(edge,EDGE_DEFAULT_ATTRS)})}function postProcessGraph(g){_.each(g.nodes(),function(v){var node=g.node(v); // Restore original dimensions if(_.has(node,"_prevWidth")){node.width=node._prevWidth}else{delete node.width}if(_.has(node,"_prevHeight")){node.height=node._prevHeight}else{delete node.height}delete node._prevWidth;delete node._prevHeight})}function createOrSelectGroup(root,name){var selection=root.select("g."+name);if(selection.empty()){selection=root.append("g").attr("class",name)}return selection}},{"./arrows":2,"./create-clusters":3,"./create-edge-labels":4,"./create-edge-paths":5,"./create-nodes":6,"./d3":7,"./dagre":8,"./lodash":21,"./position-clusters":22,"./position-edge-labels":23,"./position-nodes":24,"./shapes":26}],26:[function(require,module,exports){"use strict";var intersectRect=require("./intersect/intersect-rect");var intersectEllipse=require("./intersect/intersect-ellipse");var intersectCircle=require("./intersect/intersect-circle");var intersectPolygon=require("./intersect/intersect-polygon");module.exports={rect:rect,ellipse:ellipse,circle:circle,diamond:diamond};function rect(parent,bbox,node){var shapeSvg=parent.insert("rect",":first-child").attr("rx",node.rx).attr("ry",node.ry).attr("x",-bbox.width/2).attr("y",-bbox.height/2).attr("width",bbox.width).attr("height",bbox.height);node.intersect=function(point){return intersectRect(node,point)};return shapeSvg}function ellipse(parent,bbox,node){var rx=bbox.width/2;var ry=bbox.height/2;var shapeSvg=parent.insert("ellipse",":first-child").attr("x",-bbox.width/2).attr("y",-bbox.height/2).attr("rx",rx).attr("ry",ry);node.intersect=function(point){return intersectEllipse(node,rx,ry,point)};return shapeSvg}function circle(parent,bbox,node){var r=Math.max(bbox.width,bbox.height)/2;var shapeSvg=parent.insert("circle",":first-child").attr("x",-bbox.width/2).attr("y",-bbox.height/2).attr("r",r);node.intersect=function(point){return intersectCircle(node,r,point)};return shapeSvg} // Circumscribe an ellipse for the bounding box with a diamond shape. I derived // the function to calculate the diamond shape from: // http://mathforum.org/kb/message.jspa?messageID=3750236 function diamond(parent,bbox,node){var w=bbox.width*Math.SQRT2/2;var h=bbox.height*Math.SQRT2/2;var points=[{x:0,y:-h},{x:-w,y:0},{x:0,y:h},{x:w,y:0}];var shapeSvg=parent.insert("polygon",":first-child").attr("points",points.map(function(p){return p.x+","+p.y}).join(" "));node.intersect=function(p){return intersectPolygon(node,points,p)};return shapeSvg}},{"./intersect/intersect-circle":11,"./intersect/intersect-ellipse":12,"./intersect/intersect-polygon":15,"./intersect/intersect-rect":16}],27:[function(require,module,exports){var _=require("./lodash"); // Public utility functions module.exports={isSubgraph:isSubgraph,edgeToId:edgeToId,applyStyle:applyStyle,applyClass:applyClass,applyTransition:applyTransition}; /* * Returns true if the specified node in the graph is a subgraph node. A * subgraph node is one that contains other nodes. */function isSubgraph(g,v){return!!g.children(v).length}function edgeToId(e){return escapeId(e.v)+":"+escapeId(e.w)+":"+escapeId(e.name)}var ID_DELIM=/:/g;function escapeId(str){return str?String(str).replace(ID_DELIM,"\\:"):""}function applyStyle(dom,styleFn){if(styleFn){dom.attr("style",styleFn)}}function applyClass(dom,classFn,otherClasses){if(classFn){dom.attr("class",classFn).attr("class",otherClasses+" "+dom.attr("class"))}}function applyTransition(selection,g){var graph=g.graph();if(_.isPlainObject(graph)){var transition=graph.transition;if(_.isFunction(transition)){return transition(selection)}}return selection}},{"./lodash":21}],28:[function(require,module,exports){module.exports="0.6.4"},{}]},{},[1])(1)});