In this blog post we will demonstrate how you can implement methods that save and load part of the information that a diagram renders into JSON format. The Diagram class has built-in toJson and fromJson methods. They serialize completely the diagram with every detail so you can restore it completely, exactly the way you see it. What we are going to do is write custom save and load methods that use only part of the information – namely the size and location of nodes and links as well as their text.
I. General Setup
We are going to use the JavaScript Diagram library. However, the logic of the code can easily be applied to all other MindFusion Diagramming components, as listed in the Diagramming Pack.
We create a folder for the project and we copy there the *.js files that are used by MindFusion Diagramming library for JavaScript:
- animations.js
- collections.js
- controls.js
- diagramming.js
- drawing.js
- graphs.js
You can get the scripts if you download the trial version from Mindfusion Diagramming for JavaScript product page. You can also get them through npm.
We create an empty web page where we add the scripts at the end of the page, right before the closing BODY tag:
<script src="Scripts/collections.js" type="text/javascript"></script> <script src="Scripts/drawing.js" type="text/javascript"></script> <script src="Scripts/controls.js" type="text/javascript"></script> <script src="Scripts/animations.js" type="text/javascript"></script> <script src="Scripts/graphs.js" type="text/javascript"></script> <script src="Scripts/diagramming.js" type="text/javascript"></script> <script src="CustomJson.js" type="text/javascript"></script>
The JavaScript code specific to the sample is going to be in a separate file – we call it CustomJson.js and include it as a reference as well.
Once we have linked the scripts, it is time to add a Canvas instance to the page. The Diagram needs an HTML Canvas element to render itself onto and we are going to add one:
<div> <!-- The DiagramView component is bound to the canvas element below --> <div style="width: 100%; height: 100%; overflow: auto;"> <canvas id="diagram" width="2100" height="2100"> This page requires a browser that supports HTML 5 Canvas element. </canvas> </div> </div>
Note that we need to provide an ID to the Canvas element so we can access it later, in the code-behind file.
II. The Diagram
In the CustomJson file we first initialize two variables:
var diagram; var maxId = 0;
We will create the diagram and write all diagram-related code in the DOMContentLoaded event of the document instance:
var diagramView = MindFusion.Diagramming.DiagramView.create(document.getElementById("diagram")); diagram = diagramView.diagram;
The Diagram class is taken from the DiagramView instance and the DiagramView is created with help of the Canvas element, which we named “diagram”.
We want to set an image as a background to the diagram. Given the time of this post, the Christmas holidays are just around the corner and we set a Christmas image as a background to the diagram:
diagram.backgroundImageUrl = "christmas.jpg"; diagram.backgroundImageAlign = MindFusion.Drawing.ImageAlign.Center;
The image is in the root folder of the project, so we don’t need any special code to load it – just use the backgroundImageUrl property to specify its name. We also make use of the backgroundImageAlign property to properly align the image. By default the image fits the Canvas and this renders it distorted.
We want to handle several diagram Events Events are exposed as properties and you can register handlers by calling the addEventListener method.
We want to handle the nodeCreating nodeCreated linkCreated and linkCreating events. The ***creating events are raised while the action is about to be performed. We want to use them to provide the would-be nodes and links with some appearance properties.
For the nodes, we want them to look red and with red border during the whole process of drawing them. So we use brush and stroke to specify the desired colours. In addition, we want text to be white, so we use textColor to set this as well:
diagram.nodeCreating.addEventListener((sender, args) => { args.node.brush = "#D90416"; args.node.stroke = "#730217"; args.node.textColor = "#f4f4f4"; });
The code is similar for the linkCreating event handler. We use a few additional properties, like headBrush headStroke headShapeSize and few more to customize the looks of our links. You can find the full list with appearance properties for DiagramNode and DiagramLink in the online documentation.
III. Export to JSON
As we mentioned at the beginning of the post, we are going to save only part of the data that describes each node. We choose to save the node –id, the text and its bounds We omit all styling, both for nodes, links and the diagram. We create an array and we push there the chosen information:
var nodesData = []; diagram.nodes.forEach(node => { nodesData.push({ id: node.id, text: node.text, bounds: `${node.bounds.x},${node.bounds.y},${node.bounds.width},${node.bounds.height}` }) });
Links are characterized by the start and end object that they connect, which are specified through their origin and destination properties. We add those to the array as well:
var linksData = []; diagram.links.forEach(link => { linksData.push({ source: link.origin.id, target: link.destination.id })
Finally we use the standard JSON.stringify method to convert the list to text in the JSON format. The saving of the text in a file is done by imitating a click on a link. We create a JSON file and initialize a link, which points to it. Then we simulate a click on the link and the default browser behaviour kicks in: the user is asked to save the file.
var filename = "CustomJson.json"; var text = saveJson(); var blob = new Blob([text], { type: 'application/json' }); var link = document.createElement("a"); link.download = filename; link.href = window.URL.createObjectURL(blob); link.click();
IV. Loading The Diagram From JSON
When we load the diagram, we will only get information about the properties we have saved: bounds of nodes, origin and destination of links, node text. You can expand the sample to style again the elements. We get the JSON file that holds the diagram and parse the data. We cycle through all nodes there and create them again, reading the id and the text
var fileName = "CustomJson.json"; fetch(fileName).then(response => response.json()).then((data) => { // load node data var nodes = data.nodes; for (var node of nodes) { var boundsArgs = node.bounds.split(',').map(x => +x); var diagramNode = diagram.factory.createShapeNode(...boundsArgs); diagramNode.id = +node.id; diagramNode.text = node.text;
We do something similar for the links: we cycle through all links in the JSON and get their origin and destination. Once we are done with that, we use the createDiagramLink method of the Factory class to create the links.
And with that our sample is finished. You can download the complete source code, together with the scripts from the link below:
Save and Load Specific Diagram Data To/From JSON
About Diagramming for JavaScript: This native JavaScript library provides developers with the ability to create and customize any type of diagram, decision tree, flowchart, class hierarchy, graph, genealogy tree, BPMN diagrams and much more. The control offers rich event set, numerous customization options, animations, graph operations, styling and themes. You have more than 100 predefined nodes, table nodes and more than 15 automatic layout algorithms. Learn more about Diagramming for JavaScript at https://mindfusion.eu/javascript-diagram.html.