Automatic layout of directed graphs. This plugin uses the open-source (MIT license) Dagre library internally. It provides a wrapper so that you can call the layout directly on JointJS graphs.

Note that you must include both the Dagre and Graphlib libraries as dependencies if you wish to use the layout.DirectedGraph plugin.

### Usage

`joint.layout.DirectedGraph` plugin exposes the `joint.layout.DirectedGraph.layout(graphOrElements, opt)` function. The first parameter `graphOrElements` is the `joint.dia.Graph` or an array of `joint.dia.Elements` we want to layout. The second parameter `options` is an object that contains various options for configuring the layout.

    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);

A full blog post explaining this example in more detail can be found here.

#### Example with clusters

### Configuration

The following table lists options that you can pass to the `joint.layout.DirectedGraph.layout(graph, opt)` function:

nodeSep | a number of pixels representing the separation between adjacent nodes in the same rank
edgeSep | a number of pixels representing the separation between adjacent edges in the same rank
rankSep | a number of pixels representing the separation between ranks
rankDir | direction of the layout (one of `"TB"` (top-to-bottom) / `"BT"` (bottom-to-top) / `"LR"` (left-to-right) / `"RL"` (right-to-left))
marginX | number of pixels to use as a margin around the left and right of the graph.
marginY | number of pixels to use as a margin around the top and bottom of the graph.
ranker | Type of algorithm to assign a rank to each node in the input graph. Possible values: `'network-simplex'` (default), `'tight-tree'` or `'longest-path'`. number of pixels to use as a margin around the top and bottom of the graph.
resizeClusters | set to `false` if you don't want parent elements to stretch in order to fit all their embedded children. Default is `true`.
clusterPadding | A gap between the parent element and the boundary of its embedded children. It could be a number or an object e.g. `{ left: 10, right: 10, top: 30, bottom: 10 }`. It defaults to `10`.
setPosition(element, position) | 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 `element.set('position', position)` but want to set the position in an animated fashion via transitions.
setVertices(link, vertices) | If set to `true` the layout will adjust the links by setting their vertices. It defaults to `false`. 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 `link.set('vertices', vertices)` but want to set the vertices in an animated fashion via transitions.
setLabels(link, labelPosition, points) | If set to `true` the layout will adjust the labels by setting their position. It defaults to `false`. If the option is defined as a function it will be used to set the labels of links at the end of the layout. Note: Only the first label (`link.label(0);`) is positioned by the layout.
dagre | Optional. The DirectedGraph plugin has the dependency to the dagre lay-outing tool. The DirectedGraph is expecting to have the `dagre` variable in the global namespace, you can, however, pass your own instance of the `dagre` using this property.
graphlib | Optional. The DirectedGraph plugin has the dependency to the graphlib - a directed multi-graph library. The DirectedGraph is expecting to have the `grpahlib` variable in the global namespace, you can, however, pass your own instance of the `graphlib` using this property.

Additionally, the layout engine takes into account some properties on elements/links to fine tune the layout further. These are:

size | element | An object with `width` and `height` properties representing the size of the element.
minLen | link | The number of ranks to keep between the source and target of the link.
weight | link | The weight to assign edges. Higher weight edges are generally made shorter and straighter than lower weight edges.
labelPosition | link | Where to place the label relative to the edge. `'l'` = left, `'c'` = center (default), `'r'` = right.
labelOffset | link | How many pixels to move the label away from the edge. Applies only when `labelPosition` is left or right.
labelSize | link | The width and height of the edge label in pixels. e.g. `{ width: 100, height: 50 }`

The `layout()` function returns a bounding box (`g.Rect`) of the resulting graph.

### API

The `layout.DirectedGraph` plugins extends the `joint.dia.Graph` type with functions that make it easy to convert graphs to and from the Graphlib graph format. This allows you to easily use many of the graph algorithms provided by this library.

toGraphLib() | Convert the JointJS `joint.dia.Graph` object to the Graphlib graph object.
    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
Please note, the `toGraphLib` has the dependency to the graphlib - a directed multi-graph library. You can either have the `graphlib` in the global namespace or you can pass the `graphlib` instance as an option property.
fromGraphLib(glGraph, opt) | Convert the Graphlib graph representation to JointJS `joint.dia.Graph` object. `opt.importNode` and `opt.importEdge` are functions that accept a Graphlib node and edge objects and should return JointJS element/link.
    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 }
            });
        }
    });