Data Model / Updating Data

Updating Data

When you make changes to the underlying dataset used by an instance of the jsPlumb Toolkit, in most cases you'll want the UI to change to reflect those changes. There are ways you can achieve this - firstly, and preferably, you ask the Toolkit to make the updates and then refresh itself. Secondly, you can update the data yourself and then subsequently tell the Toolkit the data has already been updated and that it should refresh.

The methods discussed on this page are relevant when using "vanilla" jsPlumb Toolkit as well as when using the Angular/Vue/React integrations.

To update the dataset, use one of the updateXXX methods:

myToolkitInstance.updateNode("aNodeId", { foo:"bar", baz:42 });

Here, we have passed in a node id - "aNodeId" to identify which Node to update. As with all Node-related methods in the Toolkit, we could have passed in one of three things:

  • a Node id
  • a jsPlumb Toolkit Node object
  • the data representing some Node

For Edges, Ports and Groups the methods are:

  • updatePort( somePortOrPortId, { key:value... })
  • updateEdge( someEdgeOrEdgeId, { key:value... })
  • updateGroup( someGroupOrGroupId, { key:value... })

If you want to change the type of some object at runtime, you should use the setType method on a Toolkit instance:

toolkit.setType(someObject, "typeId")

Internally this method calls the appropriate updateXXX method, but also takes care of a few housekeeping tasks at the same time. For instance, with a type change for an edge, the underlying Community instance is instructed to change the connector type.


To do this, just call updateNode, updatePort, updateEdge or updateGroup with an empty data object, eg:

myToolkitInstance.updateNode("aNodeId");

The following events are fired by these methods:

MethodEventParameters
updateNodenodeUpdated{ node:Node }
updatePortportUpdated{ node:Node, port:Port }
updateEdgeedgeUpdated{ edge:Edge }

If you use the Graph JSON format when loading data into the Toolkit, the dataset is, by default, automatically updated whenever you add/remove Nodes and Edges. This is handled by a "data manager" that is registered in the jsPlumbToolkitIO namespace:

jsPlumbToolkitIO.managers["json"] = {

  addNode:function(dataset, node, idFunction) { ... },
  addEdge:function(dataset, edge, idFunction) { ... },
  removeNode:function(dataset, node, idFunction) { ... },
  removeEdge:function(dataset, edge, idFunction) { ... }
}

This behaviour can be suppressed by setting doNotUpdateOriginalData:true when you instantiate your instance of the Toolkit:

var myToolkit = jsPlumbToolkit.newInstance({doNotUpdateOriginalData:true});

The methods related to Nodes and Edges are given the associated Node/Edge as argument. The methods related to Ports are given an object containing both node and port.

The existence of this functionality means that when you're using the default "Graph JSON" syntax, if you loaded the data from a local object then you might not find yourself needing to call exportData on the Toolkit instance, since the dataset is always up to date. It might seem redundant to provide two ways to get the current dataset, but when you're using a custom loader, or the "hierarchical json" syntax, your original data will not be automatically updated. It's only for "graph json" that this functionality is enabled out of the box.


It may have already occurred to you, but you can write your own data manager and register it on an instance of the Toolkit. You just need to implement any of the six methods discussed above, and then register the manager using the same id under which you registered the associated data loader. Say you had a data loader with type "complicated":

jsPlumbToolkitIO.parsers["complicated"] = function(data, toolkit, parameters) {

  ...
};

Then you could also register this:

jsPlumbToolkitIO.managers["complicated"] = {

  addNode:function(dataset, node, idFunction) { ... },
  addEdge:function(dataset, edge, idFunction) { ... },
  removeNode:function(dataset, node, idFunction) { ... },
  removeEdge:function(dataset, edge, idFunction) { ... }

}

But note again that not all the methods are required.