Lang
Blog

How to Integrate MX Graph with Angular 8

ByAnirudh Singh
April 30th . 5 min read
How to Integrate MX Graph with Angular 8

MX-graph is a java-script based diagramming library which can be used to display interactive graphs or charts, having custom functionality. The benefit of using an MX-graph is that it is a vector-based graph, therefore, it runs natively in any browser. The popular graph-based websites like draw.io use the MX-graph library in their sites.

Angular is a popular framework to work for web-application and its easy to implement MX-graph in it for a quick start of your project.

After working on the MX-graph for a long time, I came to the conclusion that there’s not much content available about it and other related documents are not up to the mark. I’ve even seen some errors in the documentation.

So, here I am writing this blog to provide some details about how to integrate the MX graph with Angular 8.

This blog post is a brief discussion about important features of MX-graph and how to use them with Angular 8 without much sweat.

Integration of MX-Graph to Angular

First of all, we need to install MX-graph. Well, there is already an NPM package available for it, we just have to install it with this command-

npm install mxgraph — save

After the package is successfully installed, import the library to angular.json:

"build": {
          "options": {
            ...
            "assets": [
              { "glob": "**/*", "input": "src/assets/", "output": "/assets/" },
              { "glob": "favicon.ico", "input": "/src", "output": "/" },
              { "glob": "**/*", "input": "./node_modules/mxgraph/javascript/src", "output": "/assets/mxgraph" }
            ],
            ...
            "scripts": [
              "src/assets/js/mxgraph.conf.js",
              "node_modules/mxgraph/javascript/mxClient.js"
            ]
          }         
        }

Here, we change the assets and the scripts array, to the scripts we added two java-script files, mxgraph.conf.js that contains some MX-graph configuration and the mxClient.js that is MX-graph library.

But MX-graph has no typescript implementation, you need to create classes of it or even better, you can copy files and put to new directory mxtypes-

Features of MX-Graph

MX-graph provides lots of in-build functionalities. As I can not go through them all in this blog, I’ve tried to include some of the very important features you would require to build your application.

In this blog, I will discuss how to generate canvas in which you can add or remove vertex which is moveable and resize-able in that canvas. I have also discussed how to create edges or simply you can say arrows to show a link between two nodes.

Generating a New Graph-

After implementation, we can easily create a new graph in component as shown in the example-

export class AppComponent implements AfterViewInit {
@ViewChild('graphContainer') graphContainer: ElementRef;
ngAfterViewInit() {
    const newGraph = new mxGraph(this.graphContainer.nativeElement);
try {
      const parent = newGraph.getDefaultParent();
      newGraph.getModel().beginUpdate();
const vertex1 = newGraph.insertVertex(parent, '1', 'Vertex 1', 0, 0, 200, 80);
      const vertex2 = newGraph.insertVertex(parent, '2', 'Vertex 2', 0, 0, 200, 80);
newGraph.insertEdge(parent, '', '', vertex1, vertex2);
    } finally {
      newGraph.getModel().endUpdate();
      new mxHierarchicalLayout(newGraph).execute(newGraph.getDefaultParent());
    }
  }
}

Now, you have an integrated MX-graph and also have created a graph component but how to have custom graph punctuality that you want?

In the successive sections of this article, you will see some useful MX-graph functions to create custom functionality in the graph-

Insert New Vertex-

const vertex= newGraph.insertVertex(newGraph, vertex-ID, content, x-coordinates, y-coordinates, width, height,style);

Here, newGraph is the name of the graph (whatever you give it!), if there is some id to the vertex be given, you can pass it here else it can be null. In the third parameter, we can pass a string that is to be displayed inside vertex.

The next two parameters are x and y coordinates of the graph where you want to place the vertex and the last two are the width and height of the vertex. There is also an optional style parameter in which you can pass the style of the vertex. More on this is later in the article.

Finding All Vertex in Graph-

const cells = this.mxGraph.getChildVertices(this.newGraph );

It will help you find all the vertices with their data currently present in your graph. Create an edge between two vertices:

this.mxGraph.insertEdge(Graph-Name, edge-ID,content,source,target,style)

If you don’t want to pass an id then you can pass null, it will work all fine. The source is the vertex id from which edge will start and the target is where your edge will end.

The last parameter style is an option, used only if you want to add style to the edge as the last parameter in quotes.

Link if I want edge with no arrow’s, in the end, I can add ‘endArrow=none;’ as the fourth parameter.

To check there is an edge to vertex-

const edgeData = this.mxGraph.getEdgeBetween(source, target, true);

If there is an edge between source and target then all its properties with value will come in the edgeData else it will be null.

Remove Vertex-

this.mxGraph.removeCells([vertex ID], true);

In removeCells, the third parameter is to remove all vertex edges in your graph. Also, if you don’t want to remove vertex edges you can make it false.

Event Listener Functionality

Adding event listening functionality in your graph is one of the challenging tasks, MX-graph provides lots of event listeners like click, double click, hover, touch, and many more which you can check in their official documents. Some of the important have been mentioned below-

For Single Click:

this.mxGraph.addListener(mxEvent.CLICK, (sender, evt) => {})

To detect whether vertex or graph was clicked, you can use MX-event property to get vertex id as well.

this.mxGraph.addListener(mxEvent.CLICK, (sender, evt) => {
const vertexID = evt.getProperty(‘cell’);
if(vertexID ) {
console.log(`Vertex with id{$vertexID } was pressed`)
} else {
console.log(`Graph was clicked.`)
}
}

For Double Click:

It is mostly similar to the single click event, just with a slight change.

this.mxGraph.addListener(mxEvent.DOUBLE_CLICK, (sender, evt) => {})

Styling the Vertex

You can use mxStylesheet for styling the vertex but it is quite time-consuming as we don’t know all the properties in it. We have to find the required property first and then implement it which makes this approach slower.

For Fast implementation of required styling, I’ve found a better way-

As I mentioned earlier that draw.io also use MX-graph- Go to the site, create required shape and color, and then click on Edit Style as shown in below image-

integrate-mx-graph-with-angular_1.jpg

In Edit Style Box, you can see some styling properties of the vertex, you can copy it and can use directly while creating a new vertex, like this-

integrate-mx-graph-with-angular_2.jpg

Inserting Complex Shapes in Graph-

One of the major problems I’ve faced is to insert a custom shape in the graph. The only effective solution I came to know is to create an SVG of that shape and add that shape to your style.

shape=image;image=Image-URL

Text Wrapping of Vertex-

You can do wrapping of the text from style parameter, and can find all properties in draw.io. But it’s not effective, especially for complex shapes. To overcome this problem, I have created a custom function with the help of the pre-build properties of the MX-graph.

wraptext(){
  this.mxGraph.getLabel = function(cell)
  {
    const label = (this.labelsVisible) ? this.convertValueToString(cell) : '';
    const geometry = this.model.getGeometry(cell);
if (!this.model.isCollapsed(cell) && geometry != null && (geometry.offset == null ||
        (geometry.offset.x == 0 && geometry.offset.y == 0)) && this.model.isVertex(cell) &&
      geometry.width >= 2)
    {
      const style = this.getCellStyle(cell);
      const fontSize = style[mxConstants.STYLE_FONTSIZE] || mxConstants.DEFAULT_FONTSIZE;
      const max = geometry.width / (fontSize * 0.625);
if (max < label.length)
      {
        return label.substring(0, max*2) + '...';
      }
    }
return label;
  };
}

Basically, the width of each vertex in the graph is being calculated in this function. Then the maximum amount of text that can be entered based on the font size of the vertex is calculated.

If the text present in the vertex is larger than max two line’s occupancy then the rest of all text will be not shown in the graph and in the end, “…” is placed to indicate that there is more text.

Conclusion:

Now that we have a basic graph integration knowledge, the possibilities are limitless with MX-Graph. It can be used as the base for any custom graph-based application imaginable.

Lots of popular sites like draw.io uses the MX-graph in its core. It’s free unlike other libraries and is easy to use. Not only for Angular projects, this graph library can be used for other technologies also.

For a better understanding of this version, it would do no harm to have a better insight into Angular 8 and its Features.

If you enjoyed the blog, do clap on it (as many as you find worthy).

Thanks for reading!!

Share:
0
+0