Build interactive diagrams with storm-react-diagrams

Either to represent a workflow, configure an environment, or set up a visual programming tool; diagrams can be an important part of your toolbox.

Today, I want to focus on a library to create complex, highly customizable diagrams for your React apps.

[Today’s random Sourcerer profile: https://sourcerer.io/pablordrrbl]

The library

React-diagrams offers advanced diagram visualizations for your project. You will be able to display boxes with titles and properties, and links that are connecting those properties. Links can be drawn as curves, or you can specify anchor points to make the connection between the two properties a serie of segments.

Diagrams can be controled by the user. You can move nodes, links, create links between nodes, move and scale the viewport.

This library is really customizable, you can customize nearly every part of the rendered diagram, handle events to attach behaviours on clicking on elements or other user interactions.

Links

Repository: https://github.com/projectstorm/react-diagrams
Demo: http://projectstorm.cloud/react-diagrams
Docs: https://projectstorm.gitbooks.io/react-diagrams

Getting started

To install this library, you first need to install it into your React application

Via yarn

yarn install storm-react-diagrams

Via npm

npm install storm-react-diagrams

Then, import it and use it in your React app, in the component that will encapsulate your diagram :

import * as SRD from "storm-react-diagrams"
require("storm-react-diagrams/dist/style.min.css")

Once this step is done, you will be able to access all that you need to create a fully functionnal diagram, under the namespace SRD :

You can then render it with the following JSX code :

<SRD.DiagramWidget diagramEngine={engine} />

There you have a classy diagram!

Advanced concepts

Factories and node customization

First, let’s have a look at the factory pattern used to create new diagram nodes.

This pattern allows the library to be built around design patterns such as factories, that make the system highly configurable.

Let’s see this more in details, and take one example from their Storybook as an introduction to these concepts. In this example we want to draw a diamond shaped node, as shown in this screenshot :

Right after registering default factories from the diagram, we will declare two new factories.

This will teach the diagram engine how to draw diamond shaped nodes, and register this new node in the diagram engine. You will then be able to declare nodes of type “diamond”.

Binding events

Event handling allows you to define custom behaviours when interacting with diagrams and execute them when interacting with it.

This step is quite easy to reproduce :

var node = new DefaultNodeModel("Node 3", "rgb(128,99,255)");
node.addListener({
selectionChanged: () => { console.log("selectionChanged") }
});

This example shows how to bind events to a node model, but you can also bind events to link models and to the main diagram model.

Events for the diagram model

nodesUpdated
linksUpdated
offsetUpdated
zoomUpdated
gridUpdated
selectionChanged
entityRemoved

Events for Link models

sourcePortChanged
targetPortChanged
selectionChanged
entityRemoved

Events for Node models and Point models

selectionChanged
entityRemoved

Smart routing

By assigning smartRouting={true} to the main diagram component, you can display diagram links that are straight segments, automatically avoiding displayed nodes.

Diagram serialization and deserialization

At any time you can use a serialization method to export your dragram in JSON using theserializeDiagram method on your diagram model.

You can then restore a previously saved diagram using the deSerializeDiagram method on the same diagram model.

Full example available here.

Dagre

Dagre is a library used to reorder diagrams visually. It will reorganize your diagram to make it readable.

This library can work with any diagram libraries and tools, as long as you can retreive positions of your elements and move them programmatically.

A full example on how to bind it to storm-react-diagrams is available here.

Review

This library is really simple to use if you think about what is going on under the hood. Generate interactive diagrams is usually not an easy task, and adding customization abilities usually adds a burden to the API that can become really hard to understand.

React-diagrams does really well in that sense, and expose what’s necessary to the developer when it is necessary to him. The implementation work has been done in an elegant way and it is really pleasant to use it.

However, one thing which is currently missing (from my point of view) is the ability to setup diagrams directly from the template, using components. This could be an optional, less complex and less customizable way to implement a diagram. Such ideas have already been seen on other components, so why not?

Concerning under the hood remarks, the library uses div elements to render nodes, and groups all links rendering into a SVG element. This way of rendering diagrams can be questionable, but the developer already answered this question here, stating that he runned into several issues with SVG.

Project activity

The project is really active on Github. It received numerous pull request since its beginning, and both author and contributors are really active on issues. Lots of discussions are happening to propose new features or even to make it more simple to use.

Versioning is also well maintained, as well as changelog and documentation (some more API documentation could be appreciated, but you can also have a look at examples).

Alternatives for other frameworks and vanilla JS

If you want to achieve the same goals with vanilla Javascript, I would advise you to take a look at this post, comparing various libraries that would help you implement interactive diagrams in your project.

Using Vue.js, I did not find any library that was doing the job correctly, so I started to create one on my own. It is far from complete though.

If you have any alternative for other framework (I did not find anything for Angular yet), feel free to help me complete that list on the comments!

Leave Your Comment