Introduction / Getting Started

Getting Started

Although it is strongly recommended you familiarise yourself with the basic concepts in the jsPlumb Toolkit before writing an app, everybody knows that developers like to get in and get something working right away, then do some research later. So, there are a few ways to jump right in with the Toolkit.

A Gruntfile.js and matching package.json are included in your licensed copy of the Toolkit. This Gruntfile has two targets, allowing you to create a clone of one of the example apps that ship with the Toolkit, or to create a basic 'Hello World' app.

Clone an example app via Grunt

In the root directory of your Toolkit files, run this command (this is assuming that you have Grunt installed on your computer, instructions for which are outside the scope of this document):

  grunt clone --app=database-visualizer --o=<your output directory>

Here we've cloned the database-visualizer app. You can clone any of the demonstrations that ship with the Toolkit. The full list is:

  • layouts
  • multiple
  • database-visualizer
  • flowchart-builder
  • groups
  • angular-1.x-groups
  • angular-1.x
  • angular
  • angular-skeleton
  • angular-groups
  • react
  • react-skeleton
  • vue

If your output directory already exists, the clone will not proceed. Otherwise, the app will be cloned into the appropriate directory, and you can access it via the index.html. Remember to host the app with an http server and not try to use it by opening the local file.

Create an empty-ish app via Grunt

grunt create --o=<your output directory>

This will create a basic skeleton app in <your output directory>, with just enough functionality for you to see something working which you can then enhance and adjust.

Create an empty app manually

There are a million different ways to create a page from scratch, so here we'll talk only about the basic imports required:

CSS

jsplumbtoolkit-defaults.css (found in the /css directory) contains suggested defaults for your CSS, and it is recommended that you include it. Inside this file you will see comments for each style that detail whether or not it is an absolute requirement, or a suggestion, or just a cosmetic style used by the Toolkit to demonstrate how things should be setup.

Javascript

From version 1.2.0 the Toolkit bundles the required Community edition, so you need only the import the jsplumbtoolkit-x.x.x.js script.

And of course you'll likely have your own JS file containing your app code. Remember always to wrap your app's initialization like this:

jsPlumbToolkit.ready({

  // your code here
});

This method wraps jsPlumb's ready function and ensures that everything is in order before you start to make calls to the API.


Ingest an existing Community edition instance

This is a useful upgrade path for people who have an existing jsPlumb setup and wish to progressively make use of all the features the Toolkit has to offer. With this method you can instantly add pan/zoom capabilities to your UI, without making any changes to your current code.

It's straightforward to ingest an instance of the Community edition:

  var renderer = jsPlumbToolkit.Support.ingest({
    jsPlumb:instance
  });

Here, instance is some instance of jsPlumb. What you get back is a Surface widget, which is ordinarily the result of a call to the render method of an instance of the Toolkit. The Surface canvas (the element on which you pan and zoom) becomes the jsPlumb instance's Container.

Accessing the underlying Toolkit

Usually when you work with the Toolkit you perform data operations on the Toolkit itself. To access this from the renderer variable returned from an ingest, call this method:

  var toolkit = renderer.getToolkit();
Suppressing Rendering

By default, the ingest method will configure a Surface from the jsPlumb instance's Container. You can suppress this behavior and get back just a Toolkit instance like this:

  var toolkit = jsPlumbToolkit.Support.ingest({
    jsPlumb:instance,
    render:false
  });
Supplying Rendering Parameters

You can also supply parameters for the Surface widget if you wish to:

  var renderer = jsPlumbToolkit.Support.ingest({
    jsPlumb:instance,
    renderParams:{
      consumeRightClick:false,
      clampZoom:false
    }
  });

Here we've instructed the Toolkit to enable right-click on the Surface (very useful when developing), and also to not clamp the movement of the UI when the user zooms. The default behaviour is to clamp the UI to prevent the content from disappearing if the user zooms in such a way that it ordinarily would.


Adding Nodes after Ingest

Once you've ingested your existing jsPlumb instance you have two options for adding new nodes:

Use your existing mechanism and advise the Surface via its ingest method.

This method is added to any Surface that was created via the jsPlumbToolkit.Support.ingest method; it is not present on a Surface created via the Toolkit's render method. An example:

var renderer = jsPlumbToolkit.Support.ingest({ jsPlumb:instance });

// time passes. eventually a DOM element - `el` - has been added to your UI. Now you want to tell the Toolkit about it.

renderer.ingest(el);

ingest takes an optional second argument providing backing data for the node you are importing:

var renderer = jsPlumbToolkit.Support.ingest({ jsPlumb:instance });

// time passes. eventually a DOM element - `el` - has been added to your UI. Now you want to tell the Toolkit about it.

renderer.ingest(el, {left:50, top:150, label:"a new node"});

In this example, we provide a label, as well as a left/top position for the node. See below for a discussion of how nodes are positioned.

Use the Toolkit's data binding mechanism to add and render new nodes.

To do this you will most likely want to supply a view in your renderParams. This defines a variety of things pertaining to the appearance and behaviour of the UI; the link provided goes through your options here in detail. A simple example:

var renderer = jsPlumbToolkit.Support.ingest({
 jsPlumb:instance,
 renderParams:{
   view:{
    nodes:{
      "default":{
        template:"tmplNode",
        events:{
          click:function(params) { alert("you clicked node " + params.node.id); }
        }
    },
    events:{
        "canvasClick":function() { alert("you clicked on the canvas"); }
    }
  }
 }
});

The point here is that renderParams supports the exact set of parameters as the params object on a render method call on an instance of the Toolkit. In this example we've provided the ID of the template to use to render nodes, and we've registered a click listener for nodes as well as for the whitespace in the work area.

Node Positioning

By default, the Surface resulting from an ingest call will have a layout of type Absolute assigned. The initial positions for existing elements will have been retrieved by getting the offset for each of these elements, and these values will be stored in the left and top members of each node's backing data.

When you subsequently add a new node, the node will again be placed in the layout at the position derived from its current offset. You can override that behaviour, should you wish to (as shown in the example above), by providing left and top values for the node when you ingest it:

renderer.ingest(el, {left:50, top:150, label:"a new node"});