JSON
Data serialization is very easy in JointJS. It is done through two import/export functions on the Graph class:
graph.toJSON()
- converts the whole graph into a JSON objectgraph.fromJSON()
- converts the whole graph into a JSON object
Persistenceβ
The functions preserve all cells that have been added to the graph. Additionally, note that custom properties saved on the graph are preserved as well. You can use this to store additional state information:
import { dia, shapes } from '@joint/core';
const graph1 = new dia.Graph({}, { cellNamespace: shapes });
graph1.set('graphCustomProperty', true);
graph1.set('graphExportTime', Date.now());
const jsonObject = graph1.toJSON();
// transmission of `jsonObject` across network etc.
const graph2 = new dia.Graph({}, { cellNamespace: shapes }); // new empty graph
graph2.fromJSON(jsonObject);
graph2.get('graphCustomProperty'); // true
graph2.get('graphExportTime'); // e.g. 627247800000
It is important to remember that the two functions work with JSON objects - not JSON strings. However, if necessary,
you can easily convert back and forth using the native JavaScript JSON.stringify()
and JSON.parse()
functions:
import { dia, shapes } from '@joint/core';
const graph1 = new dia.Graph({}, { cellNamespace: shapes });
const jsonObject = graph1.toJSON();
const jsonString = JSON.stringify(jsonObject);
// transmission of `jsonString` across network etc.
const graph2 = new dia.Graph({}, { cellNamespace: shapes }); // new empty graph
graph2.fromJSON(JSON.parse(jsonString));
Depending on how you store/transmit your app data, you may work with the JSON objects directly (e.g. when storing it in a non-relational database like MongoDB), or in the stringified form (which can be stored anywhere plaintext can be stored, at the added cost of stringifying & parsing of the JSON object for every transmission).
Synthetic Graphsβ
It is of course also possible to avoid using the graph.toJSON()
function altogether and instead construct your own
synthetic graphs; you just need to make sure that the object you provide is valid JSON and that it contains a cells
array property:
import { dia, shapes } from '@joint/core';
const graph = new dia.Graph({}, { cellNamespace: shapes });
graph.fromJSON({
cells: [{
id: 1,
type: 'standard.Rectangle',
position: {
x: 100,
y: 100
},
size: {
width: 100,
height: 100
}
}]
});
The cells
array can even be empty, if you want to create an empty synthetic graph:
const graph = new dia.Graph({}, { cellNamespace: shapes });
graph.fromJSON({ cells: [] });
Limitationsβ
Keep in mind the general limitations of the JSON format. Some commonly used native JavaScript data types (including
Function
, Date
, and undefined
) are not supported.
The variables that have values of these types will not be persisted. Among other things, this means that if persistence
is important in your application, you should choose to define custom element/link subtypes instead of embedding custom
functions into default dia.Element
and dia.Link
types.
Additionally, if you want to make use of the JSON objects and directly store them into MongoDB, you should remember its
additional restriction on object keys starting with the .
(dot) or $
(dollar sign) symbols. Those are reserved for
internal use of the MongoDB system. This is significant in the context of JointJS because it precludes the use of
CSS-style selectors in the attrs arrays of your Elements and Links. Therefore, if persistence is important to you and
you want to save data directly to MongoDB, you should always define
custom subelement selectors in the markup of your custom elements instead
of relying on CSS-style selectors.