Open zhujik opened 4 years ago
Hi @zhujik
You are probably missing the mxgraph JavaScript dependency. The mxgraph-type-definitions lib contains no code but only definitions so you need the js lib at runtime. This can be managed via something like npm install mxgraph
About the current documentation status, it is clearly missing details and should be straightforward for anybody Prior discussions on this topic happened in #10 and I plan to provide Pull Request in this area soon I have been able to integrate the definitions by setting a typeroots entry in my tsconfig.json file as described in https://github.com/ivamax9/angular-mxgraph-demo but I am not very happy with it: I would lke to not define a typeRoot entry and use regular imports. Could you share your tsconfig.json or any project settings (or a git repo) to explain how you proceeded to setup mxgraph?
Hi @zhujik,
Sorry for the late reply, I'm busy looking for a new job recently. As @tbouffard said, you can refer to #10 if you are using some typescript wrapper for mxgraph. Or refer to this example I am created via crearte-react-app
without typescript wrapper, I use git submodule
to load the type declaration to keep up to date.
Hi @tbouffard and @hungtcs and thank you for your quick reply.
My setup is currently as follows:
package.json:
...
"dependencies": {
...
"mxgraph": "^4.1.1",
...
}
...
"devDependencies": {
"@types/jest": "^26.0.3",
"@types/node": "*",
"@types/react": "^16.9.41",
"@types/react-dom": "^16.9.8",
"@types/react-native": "^0.62.16",
"@types/react-test-renderer": "^16.9.2",
"mxgraph-type-definitions": "^1.0.3",
"typescript": "^3.9.6"
}
My tsconfig.json without changes looks like so:
{
"compileOnSave": false,
"compilerOptions": {
"suppressExcessPropertyErrors": true,
"declaration": false,
"strictNullChecks": false,
"sourceMap": true,
"skipLibCheck": true,
"jsx": "preserve",
"target": "ES6",
"module": "esnext",
"strict": false,
"lib": [
"DOM",
"ES6"
],
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": [
"./src"
]
}
I tried adding the following:
"types": [
"mxgraph-type-definitions"
],
or
"typeRoots": [
"node_modules/mxgraph-type-definitions",
"node_modules/@types"
],
with the same result.
My sample app looks like so:
import React, {Component} from "react";
// according to mxgraph, this is the way to import mxgraph loaded from npm
var mx = require("mxgraph")({
mxImageBasePath: "./src/images",
mxBasePath: "./src"
});
export default class App extends Component {
private containerRef: React.RefObject<HTMLDivElement>;
private graph: mxGraph;
constructor(props) {
super(props);
this.state = {};
this.LoadGraph = this.LoadGraph.bind(this);
this.containerRef = React.createRef()
}
componentDidMount() {
this.LoadGraph();
}
async LoadGraph() {
let container = this.containerRef.current;
// Checks if the browser is supported
if (!mx.mxClient.isBrowserSupported()) {
// Displays an error message if the browser is not supported.
// mx.mxUtils.error("Browser is not supported!", 200, false, null);
} else {
// Disables the built-in context menu
mx.mxEvent.disableContextMenu(container);
// Creates the graph inside the given container
this.graph = new mx.mxGraph(container);
// Enables rubberband selection
new mx.mxRubberband(this.graph);
// Gets the default parent for inserting new cells. This is normally the first
// child of the root (ie. layer 0).
const parent = this.graph.getDefaultParent();
// Enables tooltips, new connections and panning
this.graph.setPanning(true);
this.graph.setTooltips(true);
this.graph.setConnectable(true);
this.graph.setEnabled(true);
this.graph.setEdgeLabelsMovable(false);
this.graph.setVertexLabelsMovable(false);
this.graph.setGridEnabled(true);
this.graph.setAllowDanglingEdges(false);
this.graph.getModel().beginUpdate();
try {
let nodeMap = new Map<string, mxCell>();
let response = await DataService.retrieveAllNodes("test");
response.data.forEach(
node => {
let vertex = this.graph.insertVertex(parent, null, node.name, 0, 0, 50, 50, "rounded=1;strokeColor=red;fillColor=orange");
nodeMap.set(node.id, vertex);
});
let transitionResponse = await DataService.retrieveAllTransitions("test")
transitionResponse.data.forEach(
transition => {
let from = nodeMap.get(transition.from.id);
let to = nodeMap.get(transition.to.id);
this.graph.insertEdge(parent, null, null, from, to);
});
//data
} finally {
// Updates the display
this.graph.getModel().endUpdate();
}
... etc. sample code taken from an mxgraph demo ...
}
}
render() {
return <div className="graph-container" ref={this.containerRef} />;
}
}
With this setup, the applications tarts and mxgraph is displayed. I also noticed that compile-time type checkings work. For example, if I change let nodeMap = new Map<string, mxCell>();
to let nodeMap = new Map<string, mxGraph>();
, I get the correct error that vertex could not be inserted into the map because mxCell is not assignable to mxGraph. However, the type definitions are not read by IntellIj IDEA, there is no code completion. Frankly I don't know how the objects from the mx namespace (like mx.mxGraph) are connected to the type definitions provided by mxgraph-type-definitions. Could you give some insights?
Hi @zhujik, I did some attempts, but there are still many shortcomings, we will create a new issues to discuss these problems.
MoveTo #29
@hungtcs I suggest to keep this issue opened there is definitely a need for more documentation about how to use mxgraph with typescript and the definitions npm package. For sure there is currently an issue with the mxClient class (let's manage this through #29) but appart from that, it is possible to use the npm mxgraph-type-definitions package.
@zhujik, What I currently do (this is what https://github.com/ivamax9/angular-mxgraph-demo does as well)
require
statement in the code, no import for instance this.graph = new mxGraph(container);
or https://github.com/process-analytics/bpmn-visualization-js/blob/v0.1.6/src/component/mxgraph/MxGraphConfigurator.ts#L32I am planning to create a demo vanilla typescript project to demonstrate that, but I don't have time for that now
mxgraph settings
// options to set
const options = {
mxLoadResources: false,
mxLoadStylesheets: false,
};
// available options
const optionKeys = [
'mxBasePath',
'mxDefaultLanguage',
'mxForceIncludes',
'mxImageBasePath',
'mxLanguage',
'mxLanguages',
'mxLoadResources',
'mxLoadStylesheets',
'mxResourceExtension',
];
optionKeys.forEach(key => {
window[key] = options[key];
});
@zhujik do you still have issues with your IntelliJ IDE (except with the mxClient import no available because of #29 )? I can probably help you on this if needed.
@tbouffard sorry for the late response. I settled for the solution with the subrepository right now because I have to use the latest commit on master for my project, but I want to revisit the npm package later again and also check out that new solution "typed-mxgraph". I really appreciate all the work that has been put in here by you guys and if I find something to contribute, I'll gladly do so.
Hi, I'm developing a react app with typescript and want to use mxgraph. I'm not super proficient in typescript but so far I had no trouble setting up libraries. With mxgraph-type-definitions however it seems this is targeted to advanced typescript programmers who exactly know where to make some adjustments.
I followed the instructions for the usage (using npm) and in my Intellij IDEA, the type definitions appear and in the code it is parsed. However, when running the app the objects are undefined. For example,
mxClient.isBrowserSupported()
is parsed by the IDE and I can click on the function to go to the definition (which is the mxgraph-type-definitions module). However, on runtime I get the error "Cannot read property 'isBrowserSupported' of undefined". I'm importing the mxgraph elements like so:import { mxClient } from 'mxgraph'
Please advice on how to setup the project so that the definitions are compiled.