Ejemplo n.º 1
2
module.exports.draw = function (text, id) {
  cd.yy.clear()
  cd.parse(text)

  log.info('Rendering diagram ' + text)

  /// / Fetch the default direction, use TD if none was found
  var diagram = d3.select('#' + id)
  insertMarkers(diagram)

  // Layout graph, Create a new directed graph
  var g = new dagre.graphlib.Graph({
    multigraph: true
  })

  // Set an object for the graph label
  g.setGraph({
    isMultiGraph: true
  })

  // Default to assigning a new object as a label for each new edge.
  g.setDefaultEdgeLabel(function () {
    return {}
  })

  var classes = cDDb.getClasses()
  var keys = Object.keys(classes)
  var i
  for (i = 0; i < keys.length; i++) {
    var classDef = classes[keys[i]]
    var node = drawClass(diagram, classDef)
    // Add nodes to the graph. The first argument is the node id. The second is
    // metadata about the node. In this case we're going to add labels to each of
    // our nodes.
    g.setNode(node.id, node)
    log.info('Org height: ' + node.height)
  }

  var relations = cDDb.getRelations()
  relations.forEach(function (relation) {
    log.info('tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation))
    g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), { relation: relation })
  })
  dagre.layout(g)
  g.nodes().forEach(function (v) {
    if (typeof v !== 'undefined') {
      log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)))
      d3.select('#' + v).attr('transform', 'translate(' + (g.node(v).x - (g.node(v).width / 2)) + ',' + (g.node(v).y - (g.node(v).height / 2)) + ' )')
    }
  })
  g.edges().forEach(function (e) {
    log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e)))
    drawEdge(diagram, g.edge(e), g.edge(e).relation)
  })

  diagram.attr('height', '100%')
  diagram.attr('width', '100%')
  diagram.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20))
}
Ejemplo n.º 2
0
      function positionGraph() {

        // Create a new directed graph
        var g = new Graph();

        // Set an object for the graph label
        g.setGraph({
          rankdir: 'BT',
          nodesep: 150,
          edgesep: 70,
          marginx: 10,
          marginy: 30

        });

        // Default to assigning a new object as a label for each new edge.
        g.setDefaultEdgeLabel(function() {
          return {};
        });

        // Automatically label each of the nodes
        model.schemas.forEach(function(schema) {

          var el = document.getElementById(schema.id);
          var style = window.getComputedStyle(el);

          var width = parseInt(style.width, 10);
          var height = parseInt(style.height, 10);

          g.setNode(schema.id, {
            label: schema.name,
            width: width,
            height: height
          });

        });

        model.schemaReferences().forEach(function(key) {
          g.setEdge(key.keys.schema.id, key.ref());
        });

        var grp = dagre.layout(g);

        g.nodes().forEach(function(v) {
          console.log("Node " + v + ": " + JSON.stringify(g.node(v)));

          var el = document.getElementById(v);
          var node = g.node(v);

          var top = node.y - (node.height / 2);
          var left = node.x - (node.width / 2);

          el.style.top = top + 'px';
          el.style.left = left + 'px';

        });

      }
Ejemplo n.º 3
0
  this.render = function() {
    if(this.held()) {
      return;
    }
    var self = this;

    // Give plugins a chance to play with the config and preprocess the graph.
    var config = dagre.layout();
    var graph = this.graph.copy();
    this.doPreLayout(config, graph);

    // Instead of a list of IDs, our data should be a list of objects.
    var nodes = graph.nodes().map(function(id) {
      return graph.node(id);
    });
    this.nodes = nodes;

    // Perform graph layout.
    var result = this.renderNodes.run(nodes);
    var layout = config.run(graph);
    this.doPostLayout(layout);

    // Augment existing node data with layout information.
    nodes.forEach(function(node) {
      node.layout = layout.node(node.id);
    });
    this.positionNodes.run(nodes);

    var g = graph;
    var edges = layout.edges().map(function(id) {
      return {
        id: id,
        source: g.node(g.incidentNodes(id)[0]),
        target: g.node(g.incidentNodes(id)[1]),
        value: g.edge(id),
        layout: layout.edge(id)
      };
    });
    this.edges = edges;
    this.renderEdges.run(edges);
    this.positionEdges.run(edges);

    this.layout = layout;
    this.doPostRender();

    return this;
  };
Ejemplo n.º 4
0
function Renderer() {
  // Set up defaults...
  this._layout = layout();

  this.drawNodes(defaultDrawNodes);
  this.drawEdgeLabels(defaultDrawEdgeLabels);
  this.drawEdgePaths(defaultDrawEdgePaths);
  this.positionNodes(defaultPositionNodes);
  this.positionEdgeLabels(defaultPositionEdgeLabels);
  this.positionEdgePaths(defaultPositionEdgePaths);
  this.transition(defaultTransition);
  this.postLayout(defaultPostLayout);
  this.postRender(defaultPostRender);

  this.edgeInterpolate('bundle');
  this.edgeTension(0.95);
}
Ejemplo n.º 5
0
        render: function(svg, graph, layout) {
          var renderedGraph = graph;
          if(layout) { // Performs layout and draw the graph
            // we simplifies the graph so dagre process the layout faster
            var simpleGraph = this.createGraph();
            planLayout.simplify(graph, simpleGraph, 'end');
            // add hosts back
            var clusters = graph.nodes().filter(function(v) { return !!graph.children(v).length; });
            _.each(clusters, function(clusterKey) {
              simpleGraph.setNode(clusterKey, graph.node(clusterKey));
            });
            // dagre layout
            dagre.layout(simpleGraph, {debugTiming: false});
            // unwrap simplified nodes
            planLayout.unwrap(simpleGraph, 'end');
            planLayout.unwrapEdges(simpleGraph, graph);
            renderedGraph = simpleGraph;
            var bbox = bboxFactory.create();
            // cleanup layout data from graph
            _.each(graph.nodes(), function(nodeKey) {
              var node = graph.node(nodeKey);
              delete node.simplified;
              delete node.merged;
              delete node.unwraped;
              delete node.mergeId;
              bbox.addPoint(node.x, node.y);
              bbox.addPoint(node.x + node.width, node.y + node.height);
            });
            this.bbox = bbox;
          }

          // prepare groups to draw clusters, edges and nodes.
          var clustersGroup = this.createOrSelectGroup(svg, 'clusters'),
            edgesGroup = this.createOrSelectGroup(svg, 'edges'),
            nodesGroup = this.createOrSelectGroup(svg, 'nodes');

          // draw nodes
          this.createNodes(nodesGroup, renderedGraph);
          this.createClusters(clustersGroup, renderedGraph);
          this.createEdges(edgesGroup, renderedGraph);
        },
Ejemplo n.º 6
0
        function layout(paper) {
            var graph = paper.model;
            var i;
            var g = new dagre.graphlib.Graph();
            g.setGraph({});
            g.setDefaultEdgeLabel(function() {return{};});

            var nodes = graph.getElements();
            for (i = 0; i < nodes.length; i++) {
                var node = nodes[i];
                if (node.get('type') === joint.shapes.flo.NODE_TYPE) {
                    g.setNode(node.id, node.get('size'));
                }
            }

            var links = graph.getLinks();
            for (i = 0; i < links.length; i++) {
                var link = links[i];
                if (link.get('type') === joint.shapes.flo.LINK_TYPE) {
                    var options = {
                        minlen: 1.5
                    };
//					if (link.get('labels') && link.get('labels').length > 0) {
//						options.minlen = 1 + link.get('labels').length * 0.5;
//					}
                    g.setEdge(link.get('source').id, link.get('target').id, options);
                    link.set('vertices', []);
                }
            }

            g.graph().rankdir = 'LR';
            dagre.layout(g);
            g.nodes().forEach(function(v) {
                var node = graph.getCell(v);
                if (node) {
                    var bbox = node.getBBox();
                    node.translate(g.node(v).x - bbox.x, g.node(v).y - bbox.y);
                }
            });
        }
Ejemplo n.º 7
0
    layout: function(graphOrCells, opt) {

        var graph;

        if (graphOrCells instanceof joint.dia.Graph) {
            graph = graphOrCells;
        } else {
            graph = (new joint.dia.Graph()).resetCells(graphOrCells);
        }

        // This is not needed anymore.
        graphOrCells = null;

        opt = _.defaults(opt || {}, {
            resizeClusters: true,
            clusterPadding: 10
        });

        // create a graphlib.Graph that represents the joint.dia.Graph
        var glGraph = graph.toGraphLib({
            directed: true,
            // We are about to use edge naming feature.
            multigraph: true,
            // We are able to layout graphs with embeds.
            compound: true,
            setNodeLabel: function(element) {
                return {
                    width: element.get('size').width,
                    height: element.get('size').height,
                    rank: element.get('rank')
                };
            },
            setEdgeLabel: function(link) {
                return {
                    minLen: link.get('minLen') || 1
                };
            },
            setEdgeName: function(link) {
                // Graphlib edges have no ids. We use edge name property
                // to store and retrieve ids instead.
                return link.id;
            }
        });

        var glLabel = {};
        var marginX = opt.marginX || 0;
        var marginY = opt.marginY || 0;

        // Dagre layout accepts options as lower case.
        // Direction for rank nodes. Can be TB, BT, LR, or RL
        if (opt.rankDir) glLabel.rankdir = opt.rankDir;
        // Alignment for rank nodes. Can be UL, UR, DL, or DR
        if (opt.align) glLabel.align = opt.align;
        // Number of pixels that separate nodes horizontally in the layout.
        if (opt.nodeSep) glLabel.nodesep = opt.nodeSep;
        // Number of pixels that separate edges horizontally in the layout.
        if (opt.edgeSep) glLabel.edgesep = opt.edgeSep;
        // Number of pixels between each rank in the layout.
        if (opt.rankSep) glLabel.ranksep = opt.rankSep;
        // Number of pixels to use as a margin around the left and right of the graph.
        if (marginX) glLabel.marginx = marginX;
        // Number of pixels to use as a margin around the top and bottom of the graph.
        if (marginY) glLabel.marginy = marginY;

        // Set the option object for the graph label.
        glGraph.setGraph(glLabel);

        // Executes the layout.
        dagre.layout(glGraph, { debugTiming: !!opt.debugTiming });

        // Wrap all graph changes into a batch.
        graph.startBatch('layout');

        // Update the graph.
        graph.fromGraphLib(glGraph, {
            importNode: function(v, gl) {

                var element = this.getCell(v);
                var glNode = gl.node(v);

                if (opt.setPosition) {
                    opt.setPosition(element, glNode);
                } else {
                    element.set('position', {
                        x: glNode.x - glNode.width / 2,
                        y: glNode.y - glNode.height / 2
                    });
                }
            },
            importEdge: function(edgeObj, gl) {

                var link = this.getCell(edgeObj.name);
                var glEdge = gl.edge(edgeObj);
                var points = glEdge.points || [];

                if (opt.setLinkVertices) {
                    if (opt.setVertices) {
                        opt.setVertices(link, points);
                    } else {
                        // Remove the first and last point from points array.
                        // Those are source/target element connection points
                        // ie. they lies on the edge of connected elements.
                        link.set('vertices', points.slice(1, points.length - 1));
                    }
                }
            }
        });

        if (opt.resizeClusters) {
            // Resize and reposition cluster elements (parents of other elements)
            // to fit their children.
            // 1. filter clusters only
            // 2. map id on cells
            // 3. sort cells by their depth (the deepest first)
            // 4. resize cell to fit their direct children only.
            _.chain(glGraph.nodes())
                .filter(function(v) { return glGraph.children(v).length > 0; })
                .map(graph.getCell, graph)
                .sortBy(function(cluster) { return -cluster.getAncestors().length; })
                .invoke('fitEmbeds', { padding: opt.clusterPadding })
                .value();
        }

        graph.stopBatch('layout');

        // Width and height of the graph extended by margins.
        var glSize = glGraph.graph();
        // Return the bounding box of the graph after the layout.
        return g.Rect(
            marginX,
            marginY,
            Math.abs(glSize.width - 2 * marginX),
            Math.abs(glSize.height - 2 * marginY)
        );
    },
    layout: function(graph, opt) {

        opt = _.defaults(opt || {}, {
            resizeClusters: true,
            clusterPadding: 10
        });

        // create a graphlib.Graph that represents the joint.dia.Graph
        var glGraph = graph.toGraphLib({
            directed: true,
            // We are about to use edge naming feature.
            multigraph: true,
            // We are able to layout graphs with embeds.
            compound: true,
            setNodeLabel: function(element) {
                return {
                    width: element.get('size').width,
                    height: element.get('size').height,
                    rank: element.get('rank')
                };
            },
            setEdgeLabel: function(link) {
                return {
                    minLen: link.get('minLen') || 1
                };
            },
            setEdgeName: function(link) {
                // Graphlib edges have no ids. We use edge name property
                // to store and retrieve ids instead.
                return link.id;
            }
        });

        var glLabel = {};

        // Dagre layout accepts options as lower case.
        if (opt.rankDir) glLabel.rankdir = opt.rankDir;
        if (opt.nodeSep) glLabel.nodesep = opt.nodeSep;
        if (opt.edgeSep) glLabel.edgesep = opt.edgeSep;
        if (opt.rankSep) glLabel.ranksep = opt.rankSep;
        if (opt.marginX) glLabel.marginx = opt.marginX;
        if (opt.marginY) glLabel.marginy = opt.marginY;

        // Set the option object for the graph label
        glGraph.setGraph(glLabel);

        // executes the layout
        dagre.layout(glGraph, { debugTiming: !!opt.debugTiming });

        // Update the graph
        graph.fromGraphLib(glGraph, {
            importNode: function(v, gl) {

                var element = this.getCell(v);
                var glNode = gl.node(v);

                if (opt.setPosition) {
                    opt.setPosition(element, glNode);
                } else {
                    element.set('position', {
                        x: glNode.x - glNode.width / 2,
                        y: glNode.y - glNode.height / 2
                    });
                }
            },
            importEdge: function(edgeObj, gl) {

                var link = this.getCell(edgeObj.name);
                var glEdge = gl.edge(edgeObj);

                if (opt.setLinkVertices) {
                    if (opt.setVertices) {
                        opt.setVertices(link, glEdge.points);
                    } else {
                        link.set('vertices', glEdge.points);
                    }
                }
            }
        });

        if (opt.resizeClusters) {
            // Resize and reposition cluster elements (parents of other elements)
            // to fit their children.
            // 1. filter clusters only
            // 2. map id on cells
            // 3. sort cells by their depth (the deepest first)
            // 4. resize cell to fit their direct children only.
            _.chain(glGraph.nodes())
                .filter(function(v) { return glGraph.children(v).length > 0; })
                .map(graph.getCell, graph)
                .sortBy(function(cluster) { return -cluster.getAncestors().length; })
                .invoke('fitEmbeds', { padding: opt.clusterPadding })
                .value();
        }

        // Return an object with height and width of the graph.
        return glGraph.graph();
    }
Ejemplo n.º 9
0
function process() {
  var g = new dagre.Digraph(),
      properties,
      node,
      library = container.analyzer,
      str = library.stringify(),
      libraryNodes = str.nodes,
      libraryEdges = str.edges;

  // create the graph
  // each element of the graph has
  // - label
  // - width
  // - height
  // - properties
  _.forOwn(libraryNodes, function (properties, k) {
    var label = k.match(/\S*?-(.*)/)[1];
    // console.log(k, label.length);
    node = {
      label: k,
      width: label.length * 10
    };
    // lines + header + padding bottom
    node.height = properties.length * 15 + 50;
    node.properties = properties;
    properties.forEach(function (v) {
      node.width = Math.max(node.width, v.name.length * 10);
    });
    g.addNode(k, node);
  });

  // build the edges from node to node
  _.forOwn(libraryEdges, function (links) {
    links.forEach(function (link) {
      if (g.hasNode(link.from) && g.hasNode(link.to)) {
        g.addEdge(null, link.from, link.to);
      }
    });
  });

  // layout of the graph
  var layout = dagre.layout()
    .nodeSep(30)
    // .rankSep(70)
    // .rankDir('TB')
    .run(g);

  var nodes = [],
      edges = [],
      center = {x: 0, y: 0},
      mn = {x: Infinity, y: Infinity},
      mx = {x: -Infinity, y: -Infinity},
      total = g.nodes().length;

  // update the node info of the node adding:
  // - x
  // - y
  // - predecessors
  // - successors
  layout.eachNode(function (k, layoutInfo) {
    var x = layoutInfo.x;
    var y = layoutInfo.y;

    node = g.node(k);
    node.x = x;
    node.y = y;
    node.predecessors = g.predecessors(k);
    node.successors = g.successors(k);
    nodes.push(node);

    // calculate the bbox of the graph to center the graph
    var mnx = x - node.width / 2;
    var mny = y - node.height / 2;
    var mxx = x + node.width / 2;
    var mxy = y + node.height / 2;

    center.x += x;
    center.y += y;
    mn.x = Math.min(mn.x, mnx);
    mn.y = Math.min(mn.y, mny);
    // console.log(x, y, ' dim ', node.width, node.height);
    mx.x = Math.max(mx.x, mxx);
    mx.y = Math.max(mx.y, mxy);
  });

  center.x /= (total || 1);
  center.y /= (total || 1);

  // create the edges from property to node
  _(libraryEdges).forOwn(function (links) {
    links.forEach(function (link) {
      if (g.hasNode(link.from) && g.hasNode(link.to)) {
        edges.push(link);
      }
    });
  });

  return {
    edges: edges,
    nodes: nodes,
    center: center,
    mn: mn,
    mx: mx
  };
}
Ejemplo n.º 10
0
/**
 * Layout engine runner
 * After the layout engine run nodes and edges have x-y-coordinates. Engine is
 * not run if the number of nodes is bigger than `MAX_NODES`.
 * @param  {Object} graph dagre graph instance
 * @param  {Map} imNodes new node set
 * @param  {Map} imEdges new edge set
 * @param  {Object} opts    dimensions, scales, etc.
 * @return {Object}         Layout with nodes, edges, dimensions
 */
function runLayoutEngine(graph, imNodes, imEdges, opts) {
  let nodes = imNodes;
  let edges = imEdges;

  const options = opts || {};
  const scale = options.scale || DEFAULT_SCALE;
  const ranksep = scale(RANK_SEPARATION_FACTOR);
  const nodesep = scale(NODE_SEPARATION_FACTOR);
  const nodeWidth = scale(NODE_SIZE_FACTOR);
  const nodeHeight = scale(NODE_SIZE_FACTOR);

  // configure node margins
  graph.setGraph({
    nodesep,
    ranksep
  });

  // add nodes to the graph if not already there
  nodes.forEach(node => {
    const gNodeId = graphNodeId(node.get('id'));
    if (!graph.hasNode(gNodeId)) {
      graph.setNode(gNodeId, {
        width: nodeWidth,
        height: nodeHeight
      });
    }
  });

  // remove nodes that are no longer there or are 0-degree nodes
  graph.nodes().forEach(gNodeId => {
    const nodeId = fromGraphNodeId(gNodeId);
    if (!nodes.has(nodeId) || nodes.get(nodeId).get('degree') === 0) {
      graph.removeNode(gNodeId);
    }
  });

  // add edges to the graph if not already there
  edges.forEach(edge => {
    const s = graphNodeId(edge.get('source'));
    const t = graphNodeId(edge.get('target'));
    if (!graph.hasEdge(s, t)) {
      const virtualNodes = s === t ? 1 : 0;
      graph.setEdge(s, t, {id: edge.get('id'), minlen: virtualNodes});
    }
  });

  // remove edges that are no longer there
  graph.edges().forEach(edgeObj => {
    const edge = [fromGraphNodeId(edgeObj.v), fromGraphNodeId(edgeObj.w)];
    const edgeId = edge.join(EDGE_ID_SEPARATOR);
    if (!edges.has(edgeId)) {
      graph.removeEdge(edgeObj.v, edgeObj.w);
    }
  });

  dagre.layout(graph);
  const layout = graph.graph();

  // apply coordinates to nodes and edges

  graph.nodes().forEach(gNodeId => {
    const graphNode = graph.node(gNodeId);
    const nodeId = fromGraphNodeId(gNodeId);
    nodes = nodes.setIn([nodeId, 'x'], graphNode.x);
    nodes = nodes.setIn([nodeId, 'y'], graphNode.y);
  });

  graph.edges().forEach(graphEdge => {
    const graphEdgeMeta = graph.edge(graphEdge);
    const edge = edges.get(graphEdgeMeta.id);
    let points = fromJS(graphEdgeMeta.points);

    // set beginning and end points to node coordinates to ignore node bounding box
    const source = nodes.get(fromGraphNodeId(edge.get('source')));
    const target = nodes.get(fromGraphNodeId(edge.get('target')));
    points = points.mergeIn([0], {x: source.get('x'), y: source.get('y')});
    points = points.mergeIn([points.size - 1], {x: target.get('x'), y: target.get('y')});

    edges = edges.setIn([graphEdgeMeta.id, 'points'], points);
  });

  // return object with the width and height of layout
  return {
    width: layout.width,
    height: layout.height,
    nodes,
    edges
  };
}
if("object"==typeof exports)var graphlib=require("graphlib"),dagre=require("dagre");graphlib=graphlib||"undefined"!=typeof window&&window.graphlib,dagre=dagre||"undefined"!=typeof window&&window.dagre,joint.layout.DirectedGraph={layout:function(a,b){var c;c=a instanceof joint.dia.Graph?a:(new joint.dia.Graph).resetCells(a),a=null,b=_.defaults(b||{},{resizeClusters:!0,clusterPadding:10});var d=c.toGraphLib({directed:!0,multigraph:!0,compound:!0,setNodeLabel:function(a){return{width:a.get("size").width,height:a.get("size").height,rank:a.get("rank")}},setEdgeLabel:function(a){return{minLen:a.get("minLen")||1}},setEdgeName:function(a){return a.id}}),e={};return b.rankDir&&(e.rankdir=b.rankDir),b.align&&(e.align=b.align),b.nodeSep&&(e.nodesep=b.nodeSep),b.edgeSep&&(e.edgesep=b.edgeSep),b.rankSep&&(e.ranksep=b.rankSep),b.marginX&&(e.marginx=b.marginX),b.marginY&&(e.marginy=b.marginY),d.setGraph(e),dagre.layout(d,{debugTiming:!!b.debugTiming}),c.startBatch("layout"),c.fromGraphLib(d,{importNode:function(a,c){var d=this.getCell(a),e=c.node(a);b.setPosition?b.setPosition(d,e):d.set("position",{x:e.x-e.width/2,y:e.y-e.height/2})},importEdge:function(a,c){var d=this.getCell(a.name),e=c.edge(a),f=e.points||[];b.setLinkVertices&&(b.setVertices?b.setVertices(d,f):d.set("vertices",f.slice(1,f.length-1)))}}),b.resizeClusters&&_.chain(d.nodes()).filter(function(a){return d.children(a).length>0}).map(c.getCell,c).sortBy(function(a){return-a.getAncestors().length}).invoke("fitEmbeds",{padding:b.clusterPadding}).value(),c.stopBatch("layout"),d.graph()},fromGraphLib:function(a,b){b=b||{};var c=b.importNode||_.noop,d=b.importEdge||_.noop,e=this instanceof joint.dia.Graph?this:new joint.dia.Graph;return a.nodes().forEach(function(d){c.call(e,d,a,e,b)}),a.edges().forEach(function(c){d.call(e,c,a,e,b)}),e},toGraphLib:function(a,b){b=b||{};var c=_.pick(b,"directed","compound","multigraph"),d=new graphlib.Graph(c),e=b.setNodeLabel||_.noop,f=b.setEdgeLabel||_.noop,g=b.setEdgeName||_.noop;return a.get("cells").each(function(a){if(a.isLink()){var b=a.get("source"),c=a.get("target");if(!b.id||!c.id)return;d.setEdge(b.id,c.id,f(a),g(a))}else d.setNode(a.id,e(a)),d.isCompound()&&a.has("parent")&&d.setParent(a.id,a.get("parent"))}),d}},joint.dia.Graph.prototype.toGraphLib=function(a){return joint.layout.DirectedGraph.toGraphLib(this,a)},joint.dia.Graph.prototype.fromGraphLib=function(a,b){return joint.layout.DirectedGraph.fromGraphLib.call(this,a,b)};
if("object"==typeof exports)var graphlib=require("graphlib"),dagre=require("dagre");graphlib=graphlib||"undefined"!=typeof window&&window.graphlib,dagre=dagre||"undefined"!=typeof window&&window.dagre,joint.dia.Graph.prototype.toGraphLib=function(a){a=a||{};var b=_.pick(a,"directed","compound","multigraph"),c=new graphlib.Graph(b),d=a.setNodeLabel||_.noop,e=a.setEdgeLabel||_.noop,f=a.setEdgeName||_.noop;return this.get("cells").each(function(a){if(a.isLink()){var b=a.get("source"),g=a.get("target");if(!b.id||!g.id)return;c.setEdge(b.id,g.id,e(a),f(a))}else c.setNode(a.id,d(a)),c.isCompound()&&a.has("parent")&&c.setParent(a.id,a.get("parent"))}),c},joint.dia.Graph.prototype.fromGraphLib=function(a,b){b=b||{};var c=b.importNode||_.noop,d=b.importEdge||_.noop;a.nodes().forEach(function(d){c.call(this,d,a,this,b)},this),a.edges().forEach(function(c){d.call(this,c,a,this,b)},this)},joint.layout.DirectedGraph={layout:function(a,b){b=_.defaults(b||{},{resizeClusters:!0,clusterPadding:10});var c=a.toGraphLib({directed:!0,multigraph:!0,compound:!0,setNodeLabel:function(a){return{width:a.get("size").width,height:a.get("size").height,rank:a.get("rank")}},setEdgeLabel:function(a){return{minLen:a.get("minLen")||1}},setEdgeName:function(a){return a.id}}),d={};return b.rankDir&&(d.rankdir=b.rankDir),b.nodeSep&&(d.nodesep=b.nodeSep),b.edgeSep&&(d.edgesep=b.edgeSep),b.rankSep&&(d.ranksep=b.rankSep),b.marginX&&(d.marginx=b.marginX),b.marginY&&(d.marginy=b.marginY),c.setGraph(d),dagre.layout(c,{debugTiming:!!b.debugTiming}),a.fromGraphLib(c,{importNode:function(a,c){var d=this.getCell(a),e=c.node(a);b.setPosition?b.setPosition(d,e):d.set("position",{x:e.x-e.width/2,y:e.y-e.height/2})},importEdge:function(a,c){var d=this.getCell(a.name),e=c.edge(a);b.setLinkVertices&&(b.setVertices?b.setVertices(d,e.points):d.set("vertices",e.points))}}),b.resizeClusters&&_.chain(c.nodes()).filter(function(a){return c.children(a).length>0}).map(a.getCell,a).sortBy(function(a){return-a.getAncestors().length}).invoke("fitEmbeds",{padding:b.clusterPadding}).value(),c.graph()}};
Ejemplo n.º 13
0
function Graph(props) {
  var g = new dagre.graphlib.Graph();
  g.setGraph({
    width: 1000,
    height: 1000,
    nodesep: 50,
    edgesep: 150,
    ranksep: 150,
    marginx: 100,
    marginy: 100,
  });

  var edgeLabels = {};
  React.Children.forEach(props.children, function(child) {
    if (!child) {
      return;
    }
    if (child.type.isVertex) {
      g.setNode(child.key, {
        label: child,
        width: child.props.width,
        height: child.props.height,
      });
    } else if (child.type.isEdge) {
      const relationshipKey = child.props.source + ':' + child.props.target;
      if (!edgeLabels[relationshipKey]) {
        edgeLabels[relationshipKey] = [];
      }
      edgeLabels[relationshipKey].push(child);
    }
  });

  Object.keys(edgeLabels).forEach(key => {
    const children = edgeLabels[key];
    const child = children[0];
    g.setEdge(child.props.source, child.props.target, {
      label: child,
      allChildren: children.map(c => c.props.children),
      weight: child.props.weight,
    });
  });

  dagre.layout(g);

  var activeNode = g
    .nodes()
    .map(v => g.node(v))
    .find(node => node.label.props.isActive);
  const [winX, winY] = [window.innerWidth / 2, window.innerHeight / 2];
  var focusDx = activeNode ? winX - activeNode.x : 0;
  var focusDy = activeNode ? winY - activeNode.y : 0;

  var nodes = g.nodes().map(v => {
    var node = g.node(v);
    return (
      <Motion
        style={{
          x: props.isDragging ? node.x + focusDx : spring(node.x + focusDx),
          y: props.isDragging ? node.y + focusDy : spring(node.y + focusDy),
        }}
        key={node.label.key}>
        {interpolatingStyle =>
          React.cloneElement(node.label, {
            x: interpolatingStyle.x + props.dx,
            y: interpolatingStyle.y + props.dy,
            vanillaX: node.x,
            vanillaY: node.y,
          })}
      </Motion>
    );
  });

  var edges = g.edges().map(e => {
    var edge = g.edge(e);
    let idx = 0;
    return (
      <Motion
        style={edge.points.reduce((bag, point) => {
          bag[idx + ':x'] = props.isDragging
            ? point.x + focusDx
            : spring(point.x + focusDx);
          bag[idx + ':y'] = props.isDragging
            ? point.y + focusDy
            : spring(point.y + focusDy);
          idx++;
          return bag;
        }, {})}
        key={edge.label.key}>
        {interpolatedStyle => {
          let points = [];
          Object.keys(interpolatedStyle).forEach(key => {
            const [idx, prop] = key.split(':');
            if (!points[idx]) {
              points[idx] = {x: props.dx, y: props.dy};
            }
            points[idx][prop] += interpolatedStyle[key];
          });
          return React.cloneElement(edge.label, {
            points,
            id: edge.label.key,
            children: edge.allChildren.join(', '),
          });
        }}
      </Motion>
    );
  });

  return (
    <div
      style={{
        position: 'relative',
        height: '100%',
      }}>
      {edges}
      {nodes}
    </div>
  );
}
    directedGraph: function (slide, data, settings, name) {
        slide.name = name;
        /**
         *  to make the line you need to provide the start point and the extension length
         *  we will generate the extension from second point coordinates
         */
        function getCoordinates(x1, y1, x2, y2) {
            var flipH = false, flipV = false;
            if (y2 < y1) {
                flipV = true;
            }
            if (x2 < x1) {
                flipH = true;
            }
            return {
                x: x1 < x2 ? x1 : x2,
                y: y1 < y2 ? y1 : y2,
                cx: Math.abs(x2 - x1),
                cy: Math.abs(y2 - y1),
                flipH: flipH,
                flipV: flipV
            }
        }

        // Create a new directed graph
        var g = new dagre.graphlib.Graph();

        // Set an object for the graph label
        g.setGraph({});

        // Default to assigning a new object as a label for each new edge.
        g.setDefaultEdgeLabel(function () {
            return {};
        });


        var offset = 50; //margin from borders

        for (var i in data.nodes) {
            g.setNode(data.nodes[i].id, {
                label: data.nodes[i].label,
                width: settings.nodeWidth * 2,
                height: 50
            });
        }

        for (var i in data.edges) {
            g.setEdge(data.edges[i].source.id, data.edges[i].target.id);
        }

        dagre.layout(g);

        g.nodes().forEach(function (node) {
            var n = g.node(node);
            slide.addShape('rect', {
                x: n.x - n.width / 2 + offset,
                y: n.y - n.height / 2 + offset,
                cx: n.width,
                cy: n.height,
                fill: settings.nodeColor.substr(1)
            });
            slide.addText(n.label, {
                x: n.x - n.width / 2 + offset,
                y: n.y - n.height / 2 + offset,
                cx: n.width,
                cy: n.height,
                color: '000000',
                font_size: 15
            });
        });

        g.edges().forEach(function (edge) {
            var e = g.edge(edge).points;
            for (var i = 0; i < e.length - 1; i++) {
                var coord = getCoordinates(e[i].x + offset, e[i].y + offset, e[i + 1].x + offset, e[i + 1].y + offset);
                slide.addShape('line', {
                    x: coord.x,
                    y: coord.y,
                    cx: coord.cx,
                    cy: coord.cy,
                    line: settings.edgeColor.substr(1),
                    line_size: settings.edgeWidth,
                    flip_vertical: coord.flipV,
                    flip_horizontal: coord.flipH,
                    line_tail: i == e.length - 2 ? 'triangle' : 'none'
                });
            }
        });

    },
Ejemplo n.º 15
0
DagreLayout.prototype.run = function(){
  let options = this.options;
  let layout = this;

  let cy = options.cy; // cy is automatically populated for us in the constructor
  let eles = options.eles;

  let getVal = function( ele, val ){
    return isFunction(val) ? val.apply( ele, [ ele ] ) : val;
  };

  let bb = options.boundingBox || { x1: 0, y1: 0, w: cy.width(), h: cy.height() };
  if( bb.x2 === undefined ){ bb.x2 = bb.x1 + bb.w; }
  if( bb.w === undefined ){ bb.w = bb.x2 - bb.x1; }
  if( bb.y2 === undefined ){ bb.y2 = bb.y1 + bb.h; }
  if( bb.h === undefined ){ bb.h = bb.y2 - bb.y1; }

  let g = new dagre.graphlib.Graph({
    multigraph: true,
    compound: true
  });

  let gObj = {};
  let setGObj = function( name, val ){
    if( val != null ){
      gObj[ name ] = val;
    }
  };

  setGObj( 'nodesep', options.nodeSep );
  setGObj( 'edgesep', options.edgeSep );
  setGObj( 'ranksep', options.rankSep );
  setGObj( 'rankdir', options.rankDir );
  setGObj( 'ranker', options.ranker );

  g.setGraph( gObj );

  g.setDefaultEdgeLabel(function() { return {}; });
  g.setDefaultNodeLabel(function() { return {}; });

  // add nodes to dagre
  let nodes = eles.nodes();
  for( let i = 0; i < nodes.length; i++ ){
    let node = nodes[i];
    let nbb = node.layoutDimensions( options );

    g.setNode( node.id(), {
      width: nbb.w,
      height: nbb.h,
      name: node.id()
    } );

    // console.log( g.node(node.id()) );
  }

  // set compound parents
  for( let i = 0; i < nodes.length; i++ ){
    let node = nodes[i];

    if( node.isChild() ){
      g.setParent( node.id(), node.parent().id() );
    }
  }

  // add edges to dagre
  let edges = eles.edges().stdFilter(function( edge ){
    return !edge.source().isParent() && !edge.target().isParent(); // dagre can't handle edges on compound nodes
  });
  for( let i = 0; i < edges.length; i++ ){
    let edge = edges[i];

    g.setEdge( edge.source().id(), edge.target().id(), {
      minlen: getVal( edge, options.minLen ),
      weight: getVal( edge, options.edgeWeight ),
      name: edge.id()
    }, edge.id() );

    // console.log( g.edge(edge.source().id(), edge.target().id(), edge.id()) );
  }

  dagre.layout( g );

  let gNodeIds = g.nodes();
  for( let i = 0; i < gNodeIds.length; i++ ){
    let id = gNodeIds[i];
    let n = g.node( id );

    cy.getElementById(id).scratch().dagre = n;
  }

  let dagreBB;

  if( options.boundingBox ){
    dagreBB = { x1: Infinity, x2: -Infinity, y1: Infinity, y2: -Infinity };
    nodes.forEach(function( node ){
      let dModel = node.scratch().dagre;

      dagreBB.x1 = Math.min( dagreBB.x1, dModel.x );
      dagreBB.x2 = Math.max( dagreBB.x2, dModel.x );

      dagreBB.y1 = Math.min( dagreBB.y1, dModel.y );
      dagreBB.y2 = Math.max( dagreBB.y2, dModel.y );
    });

    dagreBB.w = dagreBB.x2 - dagreBB.x1;
    dagreBB.h = dagreBB.y2 - dagreBB.y1;
  } else {
    dagreBB = bb;
  }

  let constrainPos = function( p ){
    if( options.boundingBox ){
      let xPct = dagreBB.w === 0 ? 0 : (p.x - dagreBB.x1) / dagreBB.w;
      let yPct = dagreBB.h === 0 ? 0 : (p.y - dagreBB.y1) / dagreBB.h;

      return {
        x: bb.x1 + xPct * bb.w,
        y: bb.y1 + yPct * bb.h
      };
    } else {
      return p;
    }
  };

  nodes.layoutPositions(layout, options, function( ele ){
    ele = typeof ele === "object" ? ele : this;
    let dModel = ele.scratch().dagre;

    return constrainPos({
      x: dModel.x,
      y: dModel.y
    });
  });

  return this; // chaining
};
arguments.length>1?(this._strictGetNode(b),b in this._incidentEdges[a]?this._incidentEdges[a][b].keys():[]):g.union(e.values(this._incidentEdges[a])).keys()},d.prototype.toString=function(){return"Graph "+JSON.stringify(this,null,2)},d.prototype.addNode=function(a,b){return a=f.prototype.addNode.call(this,a,b),this._incidentEdges[a]={},a},d.prototype.delNode=function(a){f.prototype.delNode.call(this,a),delete this._incidentEdges[a]},d.prototype.addEdge=function(a,b,c,d){return f.prototype._addEdge.call(this,a,b,c,d,this._incidentEdges,this._incidentEdges)},d.prototype.delEdge=function(a){f.prototype._delEdge.call(this,a,this._incidentEdges,this._incidentEdges)}},{"./BaseGraph":25,"./util":45,"cp-data":19}],30:[function(a,b,c){function d(a){function b(c,e){d.has(c)||(d.add(c),e.push(c),a.neighbors(c).forEach(function(a){b(a,e)}))}var c=[],d=new e;return a.nodes().forEach(function(a){var d=[];b(a,d),d.length>0&&c.push(d)}),c}var e=a("cp-data").Set;b.exports=d},{"cp-data":19}],31:[function(a,b,c){function d(a,b,c,d){function f(b){var d=a.incidentNodes(b),e=d[0]!==i?d[0]:d[1],f=g[e],k=c(b),l=j.distance+k;if(0>k)throw new Error("dijkstra does not allow negative edge weights. Bad edge: "+b+" Weight: "+k);l<f.distance&&(f.distance=l,f.predecessor=i,h.decrease(e,l))}var g={},h=new e;c=c||function(){return 1},d=d||(a.isDirected()?function(b){return a.outEdges(b)}:function(b){return a.incidentEdges(b)}),a.eachNode(function(a){var c=a===b?0:Number.POSITIVE_INFINITY;g[a]={distance:c},h.add(a,c)});for(var i,j;h.size()>0&&(i=h.removeMin(),j=g[i],j.distance!==Number.POSITIVE_INFINITY);)d(i).forEach(f);return g}var e=a("cp-data").PriorityQueue;b.exports=d},{"cp-data":19}],32:[function(a,b,c){function d(a,b,c){var d={};return a.eachNode(function(f){d[f]=e(a,f,b,c)}),d}var e=a("./dijkstra");b.exports=d},{"./dijkstra":31}],33:[function(a,b,c){function d(a){return e(a).filter(function(a){return a.length>1})}var e=a("./tarjan");b.exports=d},{"./tarjan":39}],34:[function(a,b,c){function d(a,b,c){var d={},e=a.nodes();return b=b||function(){return 1},c=c||(a.isDirected()?function(b){return a.outEdges(b)}:function(b){return a.incidentEdges(b)}),e.forEach(function(f){d[f]={},d[f][f]={distance:0},e.forEach(function(a){f!==a&&(d[f][a]={distance:Number.POSITIVE_INFINITY})}),c(f).forEach(function(c){var e=a.incidentNodes(c),g=e[0]!==f?e[0]:e[1],h=b(c);h<d[f][g].distance&&(d[f][g]={distance:h,predecessor:f})})}),e.forEach(function(a){var b=d[a];e.forEach(function(c){var f=d[c];e.forEach(function(c){var d=f[a],e=b[c],g=f[c],h=d.distance+e.distance;h<g.distance&&(g.distance=h,g.predecessor=e.predecessor)})})}),d}b.exports=d},{}],35:[function(a,b,c){function d(a){try{e(a)}catch(b){if(b instanceof e.CycleException)return!1;throw b}return!0}var e=a("./topsort");b.exports=d},{"./topsort":40}],36:[function(a,b,c){function d(a,b,c){function d(b,e){if(f.has(b))throw new Error("The input graph is not a tree: "+a);f.add(b),a.neighbors(b).forEach(function(a){a!==e&&d(a,b)}),c(b)}var f=new e;if(a.isDirected())throw new Error("This function only works for undirected graphs");d(b)}var e=a("cp-data").Set;b.exports=d},{"cp-data":19}],37:[function(a,b,c){function d(a,b,c){function d(b,e){if(f.has(b))throw new Error("The input graph is not a tree: "+a);f.add(b),c(b),a.neighbors(b).forEach(function(a){a!==e&&d(a,b)})}var f=new e;if(a.isDirected())throw new Error("This function only works for undirected graphs");d(b)}var e=a("cp-data").Set;b.exports=d},{"cp-data":19}],38:[function(a,b,c){function d(a,b){function c(c){var e=a.incidentNodes(c),f=e[0]!==d?e[0]:e[1],g=i.priority(f);if(void 0!==g){var j=b(c);g>j&&(h[f]=d,i.decrease(f,j))}}var d,g=new e,h={},i=new f;if(0===a.order())return g;a.eachNode(function(a){i.add(a,Number.POSITIVE_INFINITY),g.addNode(a)}),i.decrease(a.nodes()[0],0);for(var j=!1;i.size()>0;){if(d=i.removeMin(),d in h)g.addEdge(null,d,h[d]);else{if(j)throw new Error("Input graph is not connected: "+a);j=!0}a.incidentEdges(d).forEach(c)}return g}var e=a("../Graph"),f=a("cp-data").PriorityQueue;b.exports=d},{"../Graph":29,"cp-data":19}],39:[function(a,b,c){function d(a){function b(g){var h=e[g]={onStack:!0,lowlink:c,index:c++};if(d.push(g),a.successors(g).forEach(function(a){a in e?e[a].onStack&&(h.lowlink=Math.min(h.lowlink,e[a].index)):(b(a),h.lowlink=Math.min(h.lowlink,e[a].lowlink))}),h.lowlink===h.index){var i,j=[];do i=d.pop(),e[i].onStack=!1,j.push(i);while(g!==i);f.push(j)}}if(!a.isDirected())throw new Error("tarjan can only be applied to a directed graph. Bad input: "+a);var c=0,d=[],e={},f=[];return a.nodes().forEach(function(a){a in e||b(a)}),f}b.exports=d},{}],40:[function(a,b,c){function d(a){function b(g){if(g in d)throw new e;g in c||(d[g]=!0,c[g]=!0,a.predecessors(g).forEach(function(a){b(a)}),delete d[g],f.push(g))}if(!a.isDirected())throw new Error("topsort can only be applied to a directed graph. Bad input: "+a);var c={},d={},f=[],g=a.sinks();if(0!==a.order()&&0===g.length)throw new e;return a.sinks().forEach(function(a){b(a)}),f}function e(){}b.exports=d,d.CycleException=e,e.prototype.toString=function(){return"Graph has at least one cycle"}},{}],41:[function(a,b,c){function d(a){function b(){a.call(this),this._parents={},this._children={},this._children[null]=new e}return b.prototype=new a,b.prototype.constructor=b,b.prototype.parent=function(a,b){if(this._strictGetNode(a),arguments.length<2)return this._parents[a];if(a===b)throw new Error("Cannot make "+a+" a parent of itself");null!==b&&this._strictGetNode(b),this._children[this._parents[a]].remove(a),this._parents[a]=b,this._children[b].add(a)},b.prototype.children=function(a){return null!==a&&this._strictGetNode(a),this._children[a].keys()},b.prototype.addNode=function(b,c){return b=a.prototype.addNode.call(this,b,c),this._parents[b]=null,this._children[b]=new e,this._children[null].add(b),b},b.prototype.delNode=function(b){var c=this.parent(b);return this._children[b].keys().forEach(function(a){this.parent(a,c)},this),this._children[c].remove(b),delete this._parents[b],delete this._children[b],a.prototype.delNode.call(this,b)},b.prototype.copy=function(){var b=a.prototype.copy.call(this);return this.nodes().forEach(function(a){b.parent(a,this.parent(a))},this),b},b.prototype.filterNodes=function(b){function c(a){var b=d.parent(a);return null===b||e.hasNode(b)?(f[a]=b,b):b in f?f[b]:c(b)}var d=this,e=a.prototype.filterNodes.call(this,b),f={};return e.eachNode(function(a){e.parent(a,c(a))}),e},b}var e=a("cp-data").Set;b.exports=d},{"cp-data":19}],42:[function(a,b,c){function d(a){return Object.prototype.toString.call(a).slice(8,-1)}var e=a("../Graph"),f=a("../Digraph"),g=a("../CGraph"),h=a("../CDigraph");c.decode=function(a,b,c){if(c=c||f,"Array"!==d(a))throw new Error("nodes is not an Array");if("Array"!==d(b))throw new Error("edges is not an Array");if("string"==typeof c)switch(c){case"graph":c=e;break;case"digraph":c=f;break;case"cgraph":c=g;break;case"cdigraph":c=h;break;default:throw new Error("Unrecognized graph type: "+c)}var i=new c;return a.forEach(function(a){i.addNode(a.id,a.value)}),i.parent&&a.forEach(function(a){a.children&&a.children.forEach(function(b){i.parent(b,a.id)})}),b.forEach(function(a){i.addEdge(a.id,a.u,a.v,a.value)}),i},c.encode=function(a){var b=[],c=[];a.eachNode(function(c,d){var e={id:c,value:d};if(a.children){var f=a.children(c);f.length&&(e.children=f)}b.push(e)}),a.eachEdge(function(a,b,d,e){c.push({id:a,u:b,v:d,value:e})});var d;if(a instanceof h)d="cdigraph";else if(a instanceof g)d="cgraph";else if(a instanceof f)d="digraph";else{if(!(a instanceof e))throw new Error("Couldn't determine type of graph: "+a);d="graph"}return{nodes:b,edges:c,type:d}}},{"../CDigraph":26,"../CGraph":27,"../Digraph":28,"../Graph":29}],43:[function(a,b,c){var d=a("cp-data").Set;c.all=function(){return function(){return!0}},c.nodesFromList=function(a){var b=new d(a);return function(a){return b.has(a)}}},{"cp-data":19}],44:[function(a,b,c){var d=a("./Graph"),e=a("./Digraph");d.prototype.toDigraph=d.prototype.asDirected=function(){var a=new e;return this.eachNode(function(b,c){a.addNode(b,c)}),this.eachEdge(function(b,c,d,e){a.addEdge(null,c,d,e),a.addEdge(null,d,c,e)}),a},e.prototype.toGraph=e.prototype.asUndirected=function(){var a=new d;return this.eachNode(function(b,c){a.addNode(b,c)}),this.eachEdge(function(b,c,d,e){a.addEdge(b,c,d,e)}),a}},{"./Digraph":28,"./Graph":29}],45:[function(a,b,c){c.values=function(a){var b,c=Object.keys(a),d=c.length,e=new Array(d);for(b=0;d>b;++b)e[b]=a[c[b]];return e}},{}],46:[function(a,b,c){b.exports="0.7.4"},{}]},{},[1]),"object"==typeof exports)var dagre=require("dagre");joint.layout.DirectedGraph={layout:function(a,b){b=b||{};var c=this._prepareData(a),d=dagre.layout();b.debugLevel&&d.debugLevel(b.debugLevel),b.rankDir&&d.rankDir(b.rankDir),b.rankSep&&d.rankSep(b.rankSep),b.edgeSep&&d.edgeSep(b.edgeSep),b.nodeSep&&d.nodeSep(b.nodeSep);var e=d.run(c);return e.eachNode(function(c,d){if(!d.dummy){var e=a.getCell(c);b.setPosition?b.setPosition(e,d):e.set("position",{x:d.x-d.width/2,y:d.y-d.height/2})}}),b.setLinkVertices&&e.eachEdge(function(c,d,e,f){var g=a.getCell(c);g&&(b.setVertices?b.setVertices(g,f.points):g.set("vertices",f.points))}),{width:e.graph().width,height:e.graph().height}},_prepareData:function(a){var b=new dagre.Digraph;return _.each(a.getElements(),function(a){b.hasNode(a.id)||b.addNode(a.id,{width:a.get("size").width,height:a.get("size").height,rank:a.get("rank")})}),_.each(a.getLinks(),function(a){if(!b.hasEdge(a.id)){var c=a.get("source").id,d=a.get("target").id;b.addEdge(a.id,c,d,{minLen:a.get("minLen")||1})}}),b}};