🎉 JointJS has new documentation! 🥳
ForceDirected plugin implements automatic layouts for graphs using a force-directed approach. This is useful for, usually larger, undirected graphs.
Include the joint.layout.ForceDirected.js
file into your HTML:
<script src="joint.layout.ForceDirected.js"></script>
ForceDirected layout plugin auto-layouts graphs based on three forces: repulsive force (forces nodes to move out of each other), attractive force (tries to get nodes together like a spring) and a gravity force (tendency of the nodes to move to a certain point).
The ForceDirected
constructor accepts a couple of parameters for configuring the layout.
The gravityCenter
parameter is the point the nodes tend to move to.
This is usually set to the center of the area where the nodes are to be laid out.
charge
parameter affects the repulsive force. Bigger the parameter is, bigger the repulsive force.
linkDistance
and linkStrength
both affect the attractive force
(you can think of it as parameters of a spring that tights together two nodes).
Bigger the linkStrength
, bigger the attractive force between two connected nodes.
On the other hand, smaller the linkDistance
, shorter links you allow and so the attractive force is bigger between two connected nodes.
There is no one-fits-all set of parameters that would give great result for all possible graphs. Therefore, it is suggested that you to play with the parameters, try to set different values so that it gives a good result for your use case.
var graphLayout = new joint.layout.ForceDirected({
graph: graph // or array of selected cells
x: 0,
y: 0,
width: 600,
height: 400,
gravityCenter: { x: 300, y: 200 },
charge: 180,
linkDistance: 30
});
graphLayout.start();
Array.from({ length: 100 }).forEach(function() { graphLayout.step(); });
Note: It is recommended to use the requestAnimationFrame for stepping the layout.
GridLayout implements automatic layouts for graphs. This is useful in many scenarios, one of them being e.g. automatically positioning elements in Stencil.
Include the joint.layout.GridLayout.js
file into your HTML:
<script src="joint.layout.GridLayout.js"></script>
GridLayout plugin exposes one function joint.layout.GridLayout.layout(graphOrElements, options)
.
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.
graph.addCells([
new joint.shapes.basic.Rect({ size: { width: 80, height: 50 }}),
new joint.shapes.basic.Rect({ size: { width: 50, height: 50 }}),
new joint.shapes.basic.Circle({ size: { width: 80, height: 50 }}),
new joint.shapes.basic.Circle({ size: { width: 50, height: 50 }})
]);
// Layout the entire graph
joint.layout.GridLayout.layout(graph, {
columns: 2,
columnWidth: 100,
rowHeight: 70
});
// Layout the circles with minimal resulting `y` coordinate equals 100.
var circles = graph.getElements().filter(function(el) {
return el instanceof joint.shapes.basic.Circle;
});
joint.layout.GridLayout.layout(circles, {
columns: 2,
marginY: 100
});
Here are the options for configuring the GridLayout:
columns
- Number of columns. It defaults to 1
.columnWidth
'auto'
- width of a column is equal to the widest element amongst all elements'compact'
- width of a column is equal to the widest element in the columnnumber
- value of a column width (e.g. 200)'auto'
.
rowHeight
'auto'
- height of a row is equal to the highest element amongst all elements'compact'
- height of a row is equal to the highest element in the rownumber
- value of a row height (e.g. 100)'auto'
.
dx
- Shifts the elements horizontally by a given amount. It defaults to 0
.dy
- Shifts the elements vertically by a given amount. It defaults to 0
.centre
- Positions the elements in the centre of a grid cell. It defaults to true
.resizeToFit
- Resizes the elements to fit a grid cell, preserving the aspect ratio (default: false
)marginX
- Sets the origin (x
coordinate) of the most top-left element. It defaults to 0
.marginY
- Sets the origin (y
coordinate) of the most top-left element. It defaults to 0
.deep
- Uses deep positioning for elements when set to true
. i.e. moves not only the elements but also their descendants. It defaults to false
.parentRelative
- Position the elements relatively to their parents.
var padding = 20;
// layout the children of the element `el`
joint.layout.GridLayout.layout(el.getEmbeddedCells(), {
parentRelative: true,
marginX: padding,
marginY: padding
});
// resize the element `el` to fit all children
el.fitEmbeds({ padding: padding });
layout.TreeLayout
is a layout algorithm for tree-like graphs. It's great for displaying
org charts, mind maps, class hierarchies and other tree structures. The layout.TreeLayout
is strong
in combination with the ui.TreeLayoutView which implements drag&drop
functionality useful when editing a tree structure.
Include joint.layout.treeLayout.js
file to your HTML:
<script src="joint.layout.treeLayout.js"></script>
Create an object of layout.TreeLayout
type passing your graph (object of type joint.dia.Graph
) as a parameter.
Then you can just call the layout()
method and the graph will be automatically laid out. It's important to note that
the position of the root element of the tree will stay the same as it was before the layout. This
allows you to move the tree to a position you want or have your tree be laid out around
the root.
var graphLayout = new joint.layout.TreeLayout({
graph: graph,
parentGap: 20,
siblingGap: 20
});
// Root element position stays the same after the layout.
// In this demo, we assume the root is the first element.
var root = graph.getElements()[0].position(200, 200);
graphLayout.layout();
The following table lists options that you can pass to the layout.TreeLayout
constructor function:
graph | The JointJS graph object on which you want to perform the layout. |
---|---|
parentGap | The distance between a parent element and its children. Defaults to 20 . |
siblingGap | The distance between siblings. Defaults to 20 . |
firstChildGap | The distance between the first sibling and its parent. It's applicable only for diagonal layouts ('TL' , 'TR' ,'BL' , 'BR' ). It defaults to 20 .
|
direction | The default direction of the layout. It can be set to one of the following values: 'L' , 'R' , 'T' , 'B' (for left-to-right, right-to-left, top-to-bottom and bottom-to-top layouts) or diagonal variants 'TL' , 'TR' ,'BL' , 'BR' (for top-left, top-right, bottom-left and bottom-right). It defaults to
'R' .
The |
filter(children, parent, opt) |
An arbitrary element or sub-tree can be skipped by the layout. By providing a filter function, one can control, which elements will be laid out and which not. The filter function returns an array of elements to be laid out and runs for every single parent element in the graph. Parameters:
No element is filtered out by default. |
updatePosition(element, position, opt) | A function responsible for setting the resulting position on the elements. It calls element.set('position', position, opt); by default. It can be used for positioning the elements in an animated manner. For instance:
|
updateVertices(link, vertices, opt) | A function responsible for setting the resulting vertices on the links. It calls link.set('vertices', vertices, opt); by default. If the option is defined as null no vertices will be set by the layout. |
attributeNames | An object that maps element attributes accepted by the layout to user defined attribute names. Useful for resolving conflicts when an attribute is already in use by the application logic. e.g Setting { siblingRank: 'index' } will make the layout look for the index attribute instead of siblingRank when trying to figure out the order of siblings. |
The tree layout also reads some element properties allowing for a fine control of the layout engine. These are:
direction | The direction of the layout for this specific node. Note the tree layout can handle even mixed layout directions on a per-node basis.
See the globally defined |
---|---|
siblingRank | The index of the element among its siblings. |
offset | The additional distance from the parent (the real distance is a sum of parentGap - defined globally in the TreeLayout constructor function configuration. - and the offset ).
|
margin | Extends the area occupied by the element on both sibling sides.
|
prevSiblingGap | The additional gap next to the element sub-tree on the side of the previous sibling. The previous sibling is defined as the sibling with the closest smaller siblingRank . |
nextSiblingGap | The additional gap next to the element sub-tree on the side of the next sibling. The next sibling is defined as the sibling with the closest larger siblingRank . |
firstChildGap | The distance between the element and the first child. It's applicable only for diagonal layouts ('TL' , 'TR' ,'BL' , 'BR' ). It overides the global firstChildGap option.
|
layout([opt]) |
Layout the graph in a tree. It iterates over all graph sources (elements without a parent) and layout them as separate trees. The option object |
---|---|
getLayoutBBox() |
Returns the bounding box of all affected elements from the last layout run (i.e. elements, which have been filtered are not taken into account when calculating the bounding box). |