Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Typescript

Typed mxGraph with Angular 15

5.00/5 (2 votes)
10 Jan 2023MIT2 min read 10.4K   111  
How to integrate mxGraph with Angular 15 and above
There are a limited number of posts on how to integrate mxGraph with Angular. However, from Angular13, none of them seems to work. This article discusses how to overcome common errors when implementing typed mxgraph with Angular.

Image 1

Introduction

MxGraph is a pure JavaScript library which generates interactive graph and charting applications. Currently, it does not support Typescript, however there are several projects which take lead on that.

There are limited number of articles on how to integrate mxGraph with Angular with most of them out of date. This article discusses how to overcome common errors when implementing typed mxgraph with Angular 15.

The proposed implementation uses mxgraph and @typed-mxgraph/typed-mxgraph dependencies without the need to copy mxgraph assets into the project

The most common error this article is trying to address is:

Uncaught TypeError: Cannot set properties of undefined (setting 'mxBasePath')

Basic Principles

Angular Configuration

As a first step, let’s create a new project (my current cli version is 15.0.4):

$ npm install -g @angular/cli
$ ng new ngmxgraph       // Set Angular15 Application on your PC
cd ngmxgraph             // Go inside project folder
ng serve                 // Run project
http://localhost:4200/   // Check working Local server 

Next, let's install the mxgraph dependencies.

npm install --save mxgraph
npm install --save-dev @typed-mxgraph/typed-mxgraph

Next, we need to let Angular know where are the installed libraries by appending the mxgraph assets and scripts into the angular.json file.

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

The assets section configures, in the output property, where the scripts will be dumped.

The final configuration step will add mxgraph types in the compiler section of the tsconfig.json file. Please note that if you encounter undefined property exception, then add strictPropertyInitialization: false as shown below:

JavaScript
"compilerOptions": {

   "strictPropertyInitialization": false, <-- This avoids undefined exceptions
   "typeRoots": [
     "node_modules/@types",
     "node_modules/@typed-mxgraph"
   ]
 },

Drawing Implementation

As as starting point, let's create a helper file which will wrap mxgraph global settings. Please note that mxBasePath is passed to the window in the factory.call.

TypeScript
// src/mxgraph.ts
import factory from 'mxgraph';

declare global {
  interface Window {
    mxBasePath: string;
    mxLoadResources: boolean;
    mxForceIncludes: boolean;
    mxLoadStylesheets: boolean;
    mxResourceExtension: string;
  }
}

window.mxBasePath = '../../assets/mxgraph';
window.mxLoadResources = true;
window.mxForceIncludes = false;
window.mxLoadStylesheets = true;
window.mxResourceExtension = '.txt';

export default factory.call(window, {
  // not working see https://github.com/jgraph/mxgraph/issues/479
  mxBasePath: '../../assets/mxgraph',
});

The main logic will be implemented in AfterViewInit rather than in the constructor of the application.component.ts file. We are going to add a simple rectangle with "Test" text onto a graphContainer.

TypeScript
import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';
import factory, { mxGraph, mxGraphModel, mxHierarchicalLayout } from 'mxgraph';
import mx from '../mxgraph';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements AfterViewInit {

  title = 'ngmxgraph';

  @ViewChild("graphContainer") containerElementRef: ElementRef ;

  get container() {
    return this.containerElementRef.nativeElement;
  }

  ngAfterViewInit(): void {
    if(mx.mxClient.isBrowserSupported()) {
      console.log('Yes! Yes!');
    }

    const graph: mxGraph = new mx.mxGraph(this.container);
    const model: mxGraphModel = graph.getModel();
    model.beginUpdate();
    try {
      graph.insertVertex(graph.getDefaultParent(), '', 'TEST', 0, 0, 100, 100);
    } finally {
      model.endUpdate();
    }
  }
}

Finally, the view in app.component.html defines the drawing canvas.

HTML
<div id="demoGraph">
  <div #graphContainer></div>
</div> 

If you follow the above steps, you should be able to integrate Angular 15 and above with the latest mxgraph library.

Summary

This is a basic introduction on how to integrate mxGraph with the Angular 15. The final project can be used as a starter for your new idea.

History

  • 5th January, 2023: Initial version

License

This article, along with any associated source code and files, is licensed under The MIT License