jointjs
Version:
JavaScript diagramming library
160 lines (138 loc) • 9.65 kB
HTML
<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>