3

I'm a mxGraph and React beginner and would like to get the mxGraph hello world example working in React, just to get a basic understanding of how I can work with mxGraph (and other third party libs).

I've started a new React project using create-react-app with the typescript template and installed mxGraph with yarn add mxgraph.

I haven't found any official typescript typings, so I'm not really sure how I should import the library to be able to start using it.

Trying to import it like this

import * as mxGraph from "mxgraph";

gives me

Could not find a declaration file for module 'mxgraph'.

Also tried

const mxGraph = require("mxgraph");

but that doesn't work either...

So I'm a little bit stumped and don't know how to even get started.

Can anyone help me get things rolling?

Thanks!

mottosson
  • 3,283
  • 4
  • 35
  • 73
  • Here is typescript definition for this library https://github.com/lgleim/mxgraph-typings – demkovych Jan 24 '20 at 09:18
  • I've tried those, but couldn't get it to work. `import { mxgraph } from "mxgraph";` and `const { mxEvent } = mxgraph;`: Both mxgraph and mxEvent are undefined. Should I do it some other way? – mottosson Jan 24 '20 at 09:24
  • check this demo: https://codesandbox.io/s/github/eyupcolak/mxgraph-react/tree/master/?from-embed – demkovych Jan 24 '20 at 09:26
  • I have seen that one too. It's using `mxgraph-js` and not `mxgraph`. I'm not really sure what mxgraph-js is, but it does not look like the official mxGraph. – mottosson Jan 24 '20 at 09:28
  • mxGraph is a project in a number of languages, mxgraph-js is the JS only distro of it. https://github.com/jgraph/mxgraph , https://github.com/jgraph/mxgraph-js – Frodo Baggins Jan 24 '20 at 10:06
  • Oh! I didn't realize that! Now it makes more sense. Thank you for clarifying. – mottosson Jan 24 '20 at 10:26
  • @David, Can you clarify the npm package of mxgraph-js which is available at : https://www.npmjs.com/package/mxgraph-js. It seems that the package is old. The mxgraph it refers to is of version 3.6.0. I know that you are one of the contributors of both mxgraph and mxgraph-js; but I am not sure who created and published the package on npm which was published 4 years ago. – Lex Soft Jun 25 '20 at 13:19

3 Answers3

3

No need to use npm package named mxgraph-js, i.e npm mxgraph-js which seems to refer to the old version of mxgraph (3.6.0). We can just use the official mxgraph, by installing via npm : npm install mxgraph. After figuring out how to use mxgraph by reading the user manual, I can use it now. Here is my code for Hello World example :

import React, {Component} from "react"

var mxnspaceobj = require("mxgraph")({
    mxImageBasePath: "mxgraph/javascript/src/images",
    mxBasePath: "mxgraph/javascript/src"
})
// The manual tells the above factory function returns a "namespace" object 
// that has access to all objects of the mxgraph package. Here I give it a name
// mxnspaceobj, although we can use any valid name. We will use this object,
// including when calling mxGraph constructor.

export default class MyMxGraph extends React.Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        //let mxClient = mxnspaceobj.mxClient
        let mxRubberband = mxnspaceobj.mxRubberband
        let mxKeyHandler = mxnspaceobj.mxKeyHandler        
        let mxUtils = mxnspaceobj.mxUtils
        let mxEvent = mxnspaceobj.mxEvent

        const container = document.querySelector("#mxcontainer")        
    
        // Now, the tricky one, because most examples codes directly use the 
        // following statement :
        // let graph = new mxGraph(container); 
        // which will fail.
    
        // Instead, we have to call the mxGraph constructor via mxnspaceobj
        // variable as follows :
        let graph = new mxnspaceobj.mxGraph(container);

        // -- The rest is the same as usually found in examples -- //

        new mxRubberband(graph);
        let parent = graph.getDefaultParent();

        graph.getModel().beginUpdate();
        try {
            const v1 = graph.insertVertex(parent, null,
               'Hello,', 20, 20, 80, 30);
            const v2 = graph.insertVertex(parent, null,
               'World!', 200, 150, 80, 30);
            const e1 = graph.insertEdge(parent, null, '', v1, v2);
        } finally {
            graph.getModel().endUpdate();
        }
    }

    render(){
        return (
            <div id="mxcontainer" style={{height:"400px", width:"1200px"}}>
                <h3>Created using mxgraph</h3>
            </div>          
        );
    }
}
Lex Soft
  • 2,308
  • 2
  • 13
  • 13
0

This is how I got it working. Not sure if it's entirely correct, but I guess it's a start.

import React, { useEffect, useRef } from "react";
import { mxGraph, mxRubberband, mxClient, mxUtils, mxEvent } from "mxgraph-js";

const App: React.FC = () => {
  const divGraph = useRef(null);

  useEffect(() => {
    if (!mxClient.isBrowserSupported()) {
      mxUtils.error("Browser is not supported!", 200, false);
    } else {
      mxEvent.disableContextMenu(divGraph.current);
      const graph = new mxGraph(divGraph.current);
      new mxRubberband(graph);
      const parent = graph.getDefaultParent();
      graph.getModel().beginUpdate();

      try {
        const v1 = graph.insertVertex(parent, null, "Hello,", 20, 20, 80, 30);
        const v2 = graph.insertVertex(parent, null, "World!", 200, 150, 80, 30);
        const e1 = graph.insertEdge(parent, null, "", v1, v2);
      } finally {
        graph.getModel().endUpdate();
      }
    }
  });

  return <div className="graph-container" ref={divGraph} id="divGraph" />;
};

export default App;
mottosson
  • 3,283
  • 4
  • 35
  • 73
0

If you are using TypeScript, you can use this wrapper: ts-mxgraph.

Then, the Hello World example become:

import React from 'react';
import { mxgraphFactory } from "ts-mxgraph";

const { mxGraph, mxRubberband,  } = mxgraphFactory({
    mxLoadResources: false,
    mxLoadStylesheets: false
});


class App extends React.Component {

  componentDidMount() {
      let container = document.getElementById('containerMx')!;
      var graph = new mxGraph(container);

      // Enables rubberband selection
      new mxRubberband(graph);

      // Gets the default parent for inserting new cells. This
      // is normally the first child of the root (ie. layer 0).
      var parent = graph.getDefaultParent();

      // Adds cells to the model in a single step
      graph.getModel().beginUpdate();
      try
      {
          var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
          var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
          var e1 = graph.insertEdge(parent, null, '', v1, v2);
      }
      finally
      {
          // Updates the display
          graph.getModel().endUpdate();
      }
  }


  render() {
    return (
      <div id="containerMx">
          Hello World!
      </div>
    );
  }

}

export default App;