DEMOS
DOCS
FEATURES
DOWNLOAD
PURCHASE
CONTACT
BLOG

Loading & Saving Data

Getting data into and out of the Toolkit is easy.

Node, Edge and Port Data

Before we start, a quick note about what happens to the data you load.

Nodes

When you load a Node such as this:

{ "id":"123", "name":"Foo", "aValue":567 }

This JSON object is available on the resulting Node instance as the data variable. This object is also what is passed to the templating code. So this snippet of code would get you the Node that was loaded and then access aValue on the Node's data:

var node = toolkitInstance.getNode("123");
console.log(node.data.aValue);
--> 567

Ports

Ports are also backed with data. Consider a table in a database: in the Toolkit's example, we model a table as a Node, and each of the table's columns are Ports. Each column - each Port - has its own specific data such as ID, datatype, etc.

The loaders for the default JSON schemes add Nodes and Edges to the Toolkit. An example Node from the Database Visualizer is this:

{
  "id":"book",
  "name":"Book",
  "type":"table",
  "columns":[
    { "id":"id", "datatype":"integer", "primaryKey":true },
    { "id":"isbn", "datatype":"varchar" },
    { "id":"title", "datatype":"varchar" }
  ]
}

The Database Visualizer's port extractor function returns three Ports - the entries in the columns array. So the backing data for this first Port is:

{ "id":"id", "datatype":"integer", "primaryKey":true }

Edges

Edges also support the concept of being backed with data, but for Edges the Toolkit does not take the top-level JSON object - instead, it looks for a data member, eg:

edges:[
  { source:1, target:2, data:{ id:"edgeFu", name:"An Edge", aValue:"I am an edge" } }
  ...
]

The data object is what is passed to the jsPlumb code that binds edge definitions from the model to actual jsPlumb Connections. Here is the equivalent code to the snippet given for Nodes above:

var edge = toolkitInstance.getEdge("edgeFu");
console.log(edge.data.aValue);
--> "I am an edge"

Loading

To load data into an instance of the Toolkit, use the load method. You can load data from a remote source - using ajax - or directly from an object in memory.

Loading data via ajax

var t = jsPlumbToolkit.newInstance();
t.load({
  type:"json",
  url:"someUrl.json",
  onload:function() {                
    // called after the data has loaded.    
  }
});

Specifying HTTP Headers

By default, the Toolkit will set the HTTP header Accept to the value application/json. You can override this by providing your own HTTP headers in the load call:

var t = jsPlumbToolkit.newInstance();
t.load({
  type:"xml",
  url:"someUrl.xml",
  headers:{
    Accept:"text/xml",
    X-My-Header:"FOO"
  },
  onload:function() {                
    // called after the data has loaded.    
  }
});

Note: if you provide headers you must set an Accept header (if you want it to be set), because the Toolkit will not write a value for Accept into an HTTP headers object that does not have it.

Loading data from memory

var t = jsPlumbToolkit.newInstance();
t.load({
  type:"json",
  data:{
    nodes:[
      { id:"foo", value1:"foo", value2:34 },
      { id:"bar", value1:"bar", value2:24 }
    ],
    edges:[
      { source:"foo", target:"bar", data: { value1:89 } }
    ]
});

Note that load returns the Toolkit instance, so in the case of loading data from memory you can chain methods that operate on the Toolkit:

t.load({
  type:"json",
  data: { some data }
}).render({
  container:"someElement",
  layout:{
    type:"hierarchical"
  }
});

TOP


Appending Data

One thing to keep in mind is that the load method causes the underlying Graph to be cleared: it cannot be used for an incremental load. To perform an incremental load you need to use the append method. The arguments to this method are identical to the arguments to load; the difference is that the Graph is not cleared.

t.append({
  type:"json",
  data: { some data }
});

TOP


Data Formats

The Toolkit ships with support for two JSON formats for loading and saving data. Should you need to, you can create custom load/save handlers for your own syntax.

Graph JSON Syntax

This JSON syntax - the default - consists of a JSON object with an array for nodes, edges and ports. All of these are optional, but of course if you declare an Edge then the Nodes for that Edge are expected to be present!

Here's an example with Nodes and Edges:

{
  "nodes": [
    { id:"1", name:"foo"  },
    { id:"2", name:"baz"  },
    { id:"3", name:"foo"  },
    { id:"4", name:"ding" },
    { id:"5", name:"dong" },
    { id:"6", name:"ping" },
    { id:"7", name:"pong" }
  ],
  "edges":[
    { source:"1", target:"2" },
    { source:"1", target:"3" },
    { source:"2", target:"4" },
    { source:"2", target:"5" },
    { source:"3", target:"6" },
    { source:"3", target:"7" }                
  ]
}
Loading Graph JSON
toolkitInstance.load({
  type:"json",
  url:"http://mydata.com?xyz"
});

Since Graph JSON is the default syntax, you can in fact omit the type parameter in the above example:

toolkitInstance.load({
  url:"http://mydata.com?xyz"
});

TOP


Hierarchical JSON Syntax

This JSON syntax represents hierarchical data, in which every Node may have zero or more child Nodes. It is assumed that there is an Edge between a Node and each of its child Nodes. Note that the children member on each Node's data is optional.

{
  "id":"foo",
  "name":"FOO!",
  "children":[
    {
      "id":"bar",
      "name":"BAR!",
      "children":[
        {
          "id":"baz",
          "name":"BAZ!"
        }
      ]
    },
    {
      "id":"qux",
      "name":"QUX!"
    }
  ]
}
Loading Hierarchical JSON
toolkitInstance.load({
  type:"hierarchical-json",
  url:"http://myhierarchicaldata.com?xyz"
});

TOP


Loading Custom Formats

To register your own data loader, do the following:

jsPlumbToolkitIO.parsers["myFormat"] = function(data, toolkit, parameters) {
  // process data here.
};

Your loader function is responsible for populating the Toolkit instance with Nodes, Edges and Ports, using the addNode, addEdge and addPort functions. These functions are discussed in the API documentation.

Note the parameters argument: you can pass parameters to the load function:

t.load({
  type:"myFormat",
  url:"http://myFormat.com",
  parameters:{
    doThis:true,
    doThat:false
  }
});

TOP


Saving

You can either tell the Toolkit to save data on demand, using the save function, or configure it to save automatically, whenever it detects that the data model has changed.

The Toolkit uses an HTTP POST to save data. You cannot configure it to use anything other than a POST. If you absolutely do not want to use POST, then you can use the method described at the bottom of this page to export the data, then save it yourself.

Save on demand

var t = jsPlumbToolkit.newInstance();
...
t.save({
  url:"http://foo.com"
})

Here, as with the load function, the type of the dataset is assumed to be the Toolkit's default JSON syntax (see below for an example of how to write a custom exporter).

Save Automatically

To configure the Toolkit to save automatically, you set the autoSave flag, and supply a saveUrl:

var t = jsPlumbToolkit.newInstance({
  autoSave:true,
  saveUrl:"http://foo.com"
});

The Toolkit will save the dataset whenever one of these methods is called:

  • addNode
  • removeNode
  • addNodes
  • addEdge
  • removeEdge
  • addPort
  • addNewPort
  • removePort
  • refresh
  • refreshNode
  • refreshEdge
  • refreshPort

Note the dataset will not be saved automatically when you call the clear method.

Autosave Callbacks

You can also supply a callback for both auto save success and error:

var t = jsPlumbToolkit.newInstance({
  autoSave:true,
  saveUrl:"http://foo.com",
  onAutoSaveError:function(msg) { ... },
  onAutoSaveSuccess:function(response) { ... }
});

Autosave HTTP Headers

To set headers as discussed below when auto-saving, provide a saveHeaders object in the Toolkit's constructor:

var toolkit = jsPlumbToolkit.newInstance({
  autoSave:true,
  saveUrl:"http://sava-data.com",
  saveHeaders:{
    "X-My-Header":"My Header Value"
  }
});

Saving Custom Formats

To save/export in your own format, do the following:

jsPlumbToolkitIO.exporters["myFormat"] = function(toolkit, parameters) {
  // process data here.
}

Your exporter function is responsible for retrieving the data from the Toolkit instance. There are a number of different ways this can be done - see the API documentation.

Content Type

The Toolkit will, by default, set the Content-Type header on a save POST to:

Content-Type:"application/json"

Specifying HTTP Headers

You can set arbitrary headers (including to override Content-Type) via the headers parameter on a save call:

toolkit.save({
  url:"http://save-data.com",
  headers:{
    "X-My-Header":"headerValue"
  }
});

TOP


Exporting

If you want to just export the data, you can do the following:

var t = jsPlumbToolkit.newInstance();
...
var data = t.exportData();

This will assume you want the data in the Toolkit's default JSON syntax. If you have a custom exporter you wish to use, you can specify that using the type parameter. You can also pass in parameters for the export:

var t = jsPlumbToolkit.newInstance();
...
var data = t.exportData({
  type:"myFormat",
  parameters:{
    importantNumber:34,
    somePrefix:"foo-"
  }
});

TOP