Skip to main content

Layouts#

A core piece of functionality offered by the Toolkit is support for layouts - a means to control the positioning of the vertices in your application. Layouts are renderer agnostic - they don't know about the DOM - and are shipped either in the @jsplumbtoolkit/core package or in a separate package, depending on the layout. The available layouts are:

  • Absolute This layout positions vertices dependent on values in each vertex's backing data. For many applications in which the position of vertices is under the control of a user, this layout is a good choice. It can be combined with other layouts, such as the Spring layout, to implement a scheme whereby vertices untouched by a user are placed automatically and vertices touched by a user are placed wherever the user chose.

  • Spring This is a force directed layout, positioning vertices in an optimum position relative to vertices to which they are connected. As mentioned above, this layout is an extension of the Absolute layout, which can be instructed to honour user-supplied values for vertices if present.

  • Balloon This layout groups vertices into clusters. This is a useful layout for certain types of unstructured data such as mind maps.

  • Hierarchical Positions vertices in a hierarchy, oriented either vertically or horizontally. The classic use cases for this layout are such things as a family tree or an org chart.

  • Circular Arranges all the nodes/groups in the toolkit instance into a circle, with a radius sufficiently large that no two nodes/groups overlap.

In the UI, layouts are used by the Surface widget for positioning the vertices that are visible on the canvas, and also inside each group that is rendered by the Surface. For a discussion of layouts inside of groups, see the groups documentation.

Applying a layout#

Each instance of the Toolkit has zero or more associated Surface components. Each of these has an associated layout, which can be set when the surface is instantiated, or after the fact. You do not interact directly with a layout when using a surface: the methods you generally need to use are exposed through the surface class.

const toolkit = jsPlumbToolkitBrowserUI.newInstance()  ... load data...
let surface = toolkit.render(someElement, {    layout:{      type:"Hierarchical",      options:{        padding:[ 50, 50 ]      }    }})

... or you can call setLayout on a Surface at any time to change the Layout in use:

surface.setLayout({  type:"Circular"});

Parameters#

Each layout supports its own set of parameters. You set these inside a parameters member in the object that you pass to the layout member of a render call, or in the object you pass to a setLayout call.

In the first example above, for instance, we can see that the Hierarchical layout supports a padding parameter, which is an array of [ x, y ] padding values. For a discussion of the supported parameters for each layout, see the individual layout pages linked above.

TOP


Refreshing a layout#

All layouts offer two basic methods for user interaction (although, as mentioned above, you do not call these methods directly on a layout, you call them on a surface): refresh and relayout.

relayout#

Calling relayout will cause a Layout to clear all positioning data and start over from scratch. This is what is automatically called at the end of a data load, and can also be called manually should you wish to. For deterministic Layouts such as Hierarchical, you can be sure that relayout will always produce the same result from some given input. For other layouts, such as Spring, this is not the case: the Spring layout initially positions Nodes according to some random scheme, and so each time you run the algorithm you get a unique result.

Another distinction between relayout and refresh is that with relayout you can pass in a new set of parameters.

refresh#

Calling refresh will cause a layout to be re-run without first resetting itself. As mentioned above, for most layouts this will not be any different from a relayout. For other types of layout - Hierarchical, for instance - there is no discernible difference between a refresh and a re-layout, except for the fact that the relayout method allows you to pass in a new set of parameters for the layout to use.

Whenever a change is made to the data model, the default behaviour is to make an internal call to refresh. This keeps the state of the UI as constant as possible for the user. You can suppress this behaviour by setting refreshAutomatically:false to a render call on an instance of the toolkit. Should you wish to force a refresh or re-layout yourself, the surface component offers methods for you to do so:

const t = jsPlumbToolkit.newInstance()const surface = t.render( someElement, {   refreshAutomatically:false,  ...options... } );
//// things happen//surface.refresh()

and

surface.relayout({ ...options... });

Notice that when you call relayout you can pass a new set of options to the layout (but it is not compulsory).

Another important consideration is that refresh retains existing DOM elements, whereas relayout empties the DOM and creates everything anew. If you've registered any event listeners directly on previously rendered elements, you'll need to re-register them after arelayout. It's generally better to either use the events object of a definition inside of a view to capture events on a vertex, or to use delegated event handlers.

The Toolkit fires events whenever either of relayout or refresh are executed - see the documentation on Events.

TOP


AdHoc layout calls#

The Surface widget offers a method to run a layout on your data without making the layout permanent. Say, for instance, you were using an Absolute layout:

let surface = toolkit.render(someElement, {  layout:{    type:"Absolute"  }});

And at some point you wanted to apply a Spring layout just to clean up the UI. You can call adHocLayout for this:

surface.adHocLayout({    type:"Spring"});

The format of the argument to adHocLayout is the same as for any call to setLayout or for a layout specified in a view. If you have your own layouts registered with the Toolkit they can of course be referenced by this method too.

TOP


Custom Layouts#

For many UIs, the layouts that ship with the Toolkit will provide sufficient functionality. However you may find that you need to write a custom layout for your UI - the Toolkit allows you to do this. Documentation for this capability in version 5.x is still being generated - in the meantime, feel free to contact us if you need some guidelines on how to do this.