UNPKG

jointjs

Version:

JavaScript diagramming library

160 lines (138 loc) 9.65 kB
<p>Automatic layout of directed graphs. This plugin uses the open-source (MIT license) <a href="https://github.com/cpettitt/dagre">Dagre</a> library internally. It provides a wrapper so that you can call the layout directly on JointJS graphs.</p> <p><strong>Note</strong> that you must include both the <a href="https://github.com/cpettitt/dagre">Dagre</a> and <a href="https://github.com/cpettitt/graphlib">Graphlib</a> libraries as dependencies if you wish to use the layout.DirectedGraph plugin.</p> <h3>Usage</h3> <p><code>joint.layout.DirectedGraph</code> plugin exposes the <code>joint.layout.DirectedGraph.layout(graphOrElements, opt)</code> function. The first parameter <code>graphOrElements</code> is the <code>joint.dia.Graph</code> or an array of <code>joint.dia.Elements</code> we want to layout. The second parameter <code>options</code> is an object that contains various options for configuring the layout. </p> <pre><code>var graphBBox = joint.layout.DirectedGraph.layout(graph, { nodeSep: 50, edgeSep: 80, rankDir: "TB" }); console.log('x:', graphBBox.x, 'y:', graphBBox.y) console.log('width:', graphBBox.width, 'height:', graphBBox.height);</code></pre> <iframe src="about:blank" data-src="demo/layout/DirectedGraph/index.html" style="height: 621px; width: 403px;"></iframe> <p>A full blog post explaining this example in more detail can be found <a href="http://www.daviddurman.com/automatic-graph-layout-with-jointjs-and-dagre.html">here</a>.</p> <h4>Example with clusters</h4> <iframe src="about:blank" data-src="demo/layout/DirectedGraph/clusters.html" style="height: 404px; width: 603px;"></iframe> <h3>Configuration</h3> <p>The following table lists options that you can pass to the <code>joint.layout.DirectedGraph.layout(graph, opt)</code> function:</p> <table> <tr><th>nodeSep</th><td>a number of pixels representing the separation between adjacent nodes in the same rank</td></tr> <tr><th>edgeSep</th><td>a number of pixels representing the separation between adjacent edges in the same rank</td></tr> <tr><th>rankSep</th><td>a number of pixels representing the separation between ranks</td></tr> <tr><th>rankDir</th><td>direction of the layout (one of <code>"TB"</code> (top-to-bottom) / <code>"BT"</code> (bottom-to-top) / <code>"LR"</code> (left-to-right) / <code>"RL"</code> (right-to-left))</td></tr> <tr><th>marginX</th><td>number of pixels to use as a margin around the left and right of the graph.</td></tr> <tr><th>marginY</th><td>number of pixels to use as a margin around the top and bottom of the graph.</td></tr> <tr><th>ranker</th><td>Type of algorithm to assign a rank to each node in the input graph. Possible values: <code>'network-simplex'</code> (default), <code>'tight-tree'</code> or <code>'longest-path'</code>. number of pixels to use as a margin around the top and bottom of the graph.</td></tr> <tr><th>resizeClusters</th><td>set to <code>false</code> if you don't want parent elements to stretch in order to fit all their embedded children. Default is <code>true</code>.</td></tr> <tr><th>clusterPadding</th><td>A gap between the parent element and the boundary of its embedded children. It could be a number or an object e.g. <code>{ left: 10, right: 10, top: 30, bottom: 10 }</code>. It defaults to <code>10</code>.</td></tr> <tr><th>setPosition(element, position)</th><td>a function that will be used to set the position of elements at the end of the layout. This is useful if you don't want to use the default <code>element.set('position', position)</code> but want to set the position in an animated fashion via <a href="#dia.Element.prototype.transition">transitions</a>.</td></tr> <tr><th>setVertices(link, vertices)</th> <td> If set to <code>true</code> the layout will adjust the links by setting their vertices. It defaults to <code>false</code>. If the option is defined as a function it will be used to set the vertices of links at the end of the layout. This is useful if you don't want to use the default <code>link.set('vertices', vertices)</code> but want to set the vertices in an animated fashion via <a href="#dia.Link.prototype.transition">transitions</a>. </td> </tr> <tr><th>setLabels(link, labelPosition, points)</th> <td> If set to <code>true</code> the layout will adjust the labels by setting their position. It defaults to <code>false</code>. If the option is defined as a function it will be used to set the labels of links at the end of the layout. <em><b>Note:</b> Only the first label (<code>link.label(0);</code>) is positioned by the layout.</em> </td> </tr> <tr><th>dagre</th> <td> Optional. The DirectedGraph plugin has the dependency to the <a target="_blank" href="https://github.com/dagrejs/dagre">dagre</a> lay-outing tool. The DirectedGraph is expecting to have the <code>dagre</code> variable in the global namespace, you can, however, pass your own instance of the <code>dagre</code> using this property.</td> </tr> <tr><th>graphlib</th> <td> Optional. The DirectedGraph plugin has the dependency to the <a target="_blank" href="https://github.com/dagrejs/graphlib">graphlib</a> - a directed multi-graph library. The DirectedGraph is expecting to have the <code>grpahlib</code> variable in the global namespace, you can, however, pass your own instance of the <code>graphlib</code> using this property.</td> </tr> <tr><th>exportElement(element)</th> <td> Convert element attributes into dagre <a target="_blank" href="https://github.com/dagrejs/dagre/wiki#configuring-the-layout">node</a> attributes. By default, it returns the <a href="#layout.DirectedGraph.cellAttributes">element attributes</a> below. </td> </tr> <tr><th>exportLink(link)</th> <td> Convert link attributes into dagre <a target="_blank" href="https://github.com/dagrejs/dagre/wiki#configuring-the-layout">edge</a> attributes. By default, it returns the <a href="#layout.DirectedGraph.cellAttributes">link attributes</a> below. </td> </tr> </table> <p>Additionally, the layout engine takes into account some properties on elements/links to fine tune the layout further. These are:</p> <table id="layout.DirectedGraph.cellAttributes"> <tr> <th>size</th> <td>element</td> <td>An object with `width` and `height` properties representing the size of the element.</td> </tr> <tr> <th>minLen</th> <td>link</td> <td>The number of ranks to keep between the source and target of the link.</td> </tr> <tr> <th>weight</th> <td>link</td> <td>The weight to assign edges. Higher weight edges are generally made shorter and straighter than lower weight edges.</td> </tr> <tr> <th>labelPosition</th> <td>link</td> <td>Where to place the label relative to the edge. <code>'l'</code> = left, <code>'c'</code> = center (default), <code>'r'</code> = right. </td> </tr> <tr> <th>labelOffset</th> <td>link</td> <td>How many pixels to move the label away from the edge. Applies only when <code>labelPosition</code> is left or right.</td> </tr> <tr> <th>labelSize</th> <td>link</td> <td>The width and height of the edge label in pixels. e.g. <code>{ width: 100, height: 50 }</code></td> </tr> </table> <p>The <code>layout()</code> function returns a bounding box (<code>g.Rect</code>) of the resulting graph.</p> <h3>API</h3> <p>The <code>layout.DirectedGraph</code> plugins extends the <code>joint.dia.Graph</code> type with functions that make it easy to convert graphs to and from the <a href="https://github.com/dagrejs/graphlib">Graphlib</a> graph format. This allows you to easily use many of the <a href="https://github.com/dagrejs/graphlib/wiki/API-Reference">graph algorithms</a> provided by this library.</p> <table> <tr><th><p>toGraphLib()</th><td>Convert the JointJS <code>joint.dia.Graph</code> object to the Graphlib graph object.</p> <pre><code>var graph = new joint.dia.Graph; // ... populated the graph with elements connected with links graphlib.alg.isAcyclic(graph.toGraphLib()) // true if the graph is acyclic</code></pre> Please note, the <code>toGraphLib</code> has the dependency to the <a href="https://github.com/dagrejs/graphlib">graphlib</a> - a directed multi-graph library. You can either have the <code>graphlib</code> in the global namespace or you can pass the <code>graphlib</code> instance as an option property. </td></tr> <tr><th><p>fromGraphLib(glGraph, opt)</th><td>Convert the Graphlib graph representation to JointJS <code>joint.dia.Graph</code> object. <code>opt.importNode</code> and <code>opt.importEdge</code> are functions that accept a Graphlib node and edge objects and should return JointJS element/link.</p> <pre><code>var g = new graphlib.Graph(); g.setNode(1); g.setNode(2); g.setNode(3); g.setEdge(1, 2); g.setEdge(2, 3); var graph = new joint.dia.Graph; graph.fromGraphLib(g, { importNode: function(node) { return new joint.shapes.basic.Rect({ position: { x: node.x, y: node.y }, size: { width: node.width, height: node.height } }); }, importEdge: function(edge) { return new joint.dia.Link({ source: { id: edge.v }, target: { id: edge.w } }); } });</code></pre> </td></tr> </table>