Ich arbeite an Angular 4 und möchte mxGraph in mein Projekt integrieren. Ich habe danach gegoogelt, aber ich bekomme nicht das vollständige Arbeitsbeispiel.

Ich habe versucht, folgenden Weg zu gehen, aber es funktioniert auch nicht für mich.

Schritte, die ich befolgt habe:

  1. Installierter mxgraph: npm install mxgraph --save

    npm-Paket für mxgraph: https://www.npmjs.com/package/mxgraph

  2. Installierte mxgraph-Typisierungen: npm install lgleim/mxgraph-typings --save

    Github Repo von mxgraph-Typings - https://github.com/lgleim/mxgraph-typings

  3. Jetzt habe ich es in meine Komponente importiert: import {mxgraph} from 'mxgraph';

  4. Die folgende Zeile im Assets-Array .angular-cli.json wurde hinzugefügt, um die mxGraph-Assets verfügbar zu machen.

    {"glob":"**/*", "input":"node_modules/mxgraph/javascript/src", "output": "./mxgraph"}
    
  5. Wenn ich versuche, es wie folgt zu verwenden: const graph: mxgraph.mxGraph = new mxgraph.mxGraph(document.getElementById('graphContainer'));

    Und wenn ich ng serve starte

    Dann bekomme ich ein Problem / einen Fehler wie:
    Module not found: Error: Can't resolve 'mxgraph' in 'path to my file where I have imported and used mxgraph'

  6. Wenn ich nun versuche, mxBasePath einzustellen:

    const mx = require('mxgraph')({
      mxImageBasePath: 'mxgraph/images',
      mxBasePath: 'mxgraph'
    });
    

    Und so verwendet:

    const graph: mxgraph.mxGraph = mx.mxGraph(document.getElementById('graphContainer'));

    Und wenn ich ng serve starte

    Dieses Mal bekomme ich auch das gleiche Problem / den gleichen Fehler:
    Module not found: Error: Can't resolve 'mxgraph' in 'path to my file where I have imported and used mxgraph'

Hat jemand eine Vorstellung davon, was mir hier fehlt? Oder warum funktioniert es nicht?

Wenn jemand eine andere / bessere Möglichkeit zur Integration von mxGraph in Angular 4 kennt, lassen Sie es mich bitte wissen.

Danke im Voraus !!

6
viks 19 Apr. 2018 im 16:45

5 Antworten

Beste Antwort

Wenn jemand immer noch Probleme mit der Integration von mxGraph in Angular 4/5/6 hat. Dann ist hier die Komplettlösung:

Einige Details zu verschiedenen mxGraph Repos:

Repo-1: https://github.com/jgraph/mxgraph
        This is an official release repo of mxGraph. With npm issues.

Repo-2: https://bitbucket.org/jgraph/mxgraph2
        This is an official development repo of mxGraph. With npm issues.

If anyone wants to see what npm issues with these above repos(i.e. Repo-1 and Repo-2), then check these following issues:  
            - https://github.com/jgraph/mxgraph/issues/169
            - https://github.com/jgraph/mxgraph/issues/175

Repo-3: https://bitbucket.org/lgleim/mxgraph2
        Fork of Repo-2. With npm fixes.

Repo-4: https://github.com/ViksYelapale/mxgraph2
        Fork of Repo-2. Merged npm fixes from Repo-3 as well. Added changes(i.e. required for local installation of mxGraph) to this repo.

Schritte:

  1. Repo-4 klonen. Fügen Sie außerdem eine Fernbedienung des offiziellen Repos hinzu (d. H. Repo-2), um die neuesten mxGraph-Updates / Releases / Fixes zu erhalten.

  2. Wechseln Sie in das Verzeichnis mxgraph2 und führen Sie die npm-Installation aus

    $ cd mxgraph2
    $ npm install

  3. Gehen Sie nun zu Ihrem Winkelprojekt-Repo und installieren Sie mxGraph (d. H. Mxgraph2, das wir lokal erstellt haben).

    $ npm install /path/to/mxgraph2

    z.B. npm install /home/user/workspace/mxgraph2

    Womit ein ähnlicher Eintrag wie unten in Ihrer package.json-Datei hinzugefügt wird:

    "mxgraph": "file:../mxgraph2"

  4. Führen Sie die normale npm-Installation einmal aus. Zum Hinzufügen eines fehlenden / abhängigen Pakets.

    $ npm install

  5. Jetzt werden wir mxgraph-Typisierungen installieren

    Hinweis - Die erforderliche Mindestversion des Typoskripts ist 2.4.0

    $ npm install lgleim/mxgraph-typings --save

  6. Jetzt können Sie mxGraph in Ihrer App verwenden.

    ich. component.ts

    import { mxgraph } from "mxgraph";
    
    declare var require: any;
    
    const mx = require('mxgraph')({
      mxImageBasePath: 'assets/mxgraph/images',
      mxBasePath: 'assets/mxgraph'
    });
    
    .
    .
    .
    
    ngOnInit() {
       // Note - All mxGraph methods accessible using mx.xyz
       // Eg. mx.mxGraph, mx.mxClient, mx.mxKeyHandler, mx.mxUtils and so on.
    
       // Create graph
    
       var container = document.getElementById('graphContainer');
       var graph = new mx.mxGraph(container);
    
       // You can try demo code given in official doc with above changes.
    }
    

    ii. component.html

    <div id="graphContainer"></div>

  7. Das ist es !!

Hoffe es wird hilfreich sein.

6
viks 14 Feb. 2019 im 12:16

Ich hatte genau das gleiche Problem. Laut 'lgleim' liegt das Problem beim Paket mxgraph npm. Das Problem wird hier behandelt: https://github.com/jgraph/mxgraph/issues/169 < / a>.

Ich kann das besagte Problem nicht lösen. Ich habe mxgraph jedoch erfolgreich in Angular 7 integriert, indem ich diesem Artikel gefolgt bin: https : //itnext.io/how-to-integrate-mxgraph-with-angular-6-18c3a2bb8566

Schritt 1:

Installieren Sie zunächst die neueste Version von mxgraph:

npm install mxgraph

Schritt 2:

Laden Sie dann die Eingaben von https://github.com/gooddaytoday/mxgraph-typescript-definitions herunter .git. Extrahieren Sie die Datei in den Ordner 'src' Ihres Winkelprojekts

Schritt 3

Fügen Sie in Ihrer Datei angle.json Folgendes hinzu:

  1. Fügen Sie im Assets-Array Folgendes hinzu:

    {"glob": "** / *", "input": "src / assets /", "output": "/ assets /"},

    {"glob": "** / *", "input": "./node_modules/mxgraph/javascript/src", "output": "/ assets / mxgraph"}

  2. Fügen Sie im Skript-Array Folgendes hinzu:

    "node_modules / mxgraph / javascript / mxClient.js"

Es gibt zwei Skripte und Assets-Arrays. Einmal in "Build" und einmal in "Test". Fügen Sie beide hinzu.

Nachdem Sie das alles getan haben, können Sie loslegen. :) :)

Beispielcode:

Component.html:

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

Component.ts

import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
declare var mxPerimeter: any;
declare var mxConstants: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {

  @ViewChild('graphContainer') graphContainer: ElementRef;
  graph: mxGraph;

  ngAfterViewInit() {
    this.graph = new mxGraph(this.graphContainer.nativeElement);

    // set default styles for graph
    const style = this.graph.getStylesheet().getDefaultVertexStyle();
    style[mxConstants.STYLE_PERIMETER] = mxPerimeter.EllipsePerimeter;
    style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_ELLIPSE;
    style[mxConstants.DEFAULT_VALID_COLOR] = '#00FF00';
    this.graph.getStylesheet().putDefaultVertexStyle (style);

    // add cells
    try {
      const parent = this.graph.getDefaultParent();
      this.graph.getModel().beginUpdate();
      const vertex1 = this.graph.insertVertex(parent, '1', 'Vertex 1', 0, 0, 200, 80);
      const vertex2 = this.graph.insertVertex(parent, '2', 'Vertex 2', 0, 0, 200, 80);
      this.graph.insertEdge(parent, '', '', vertex1, vertex2);
    } finally {
      this.graph.getModel().endUpdate();
      new mxHierarchicalLayout(this.graph).execute(this.graph.getDefaultParent());
    }
  }

}

Beachten Sie, dass ich die Anweisung declare verwendet habe, um mxPerimeter und mxConstants zu deklarieren. Der Grund ist, dass die Typdefinitionen unvollständig sind. Daher musste ich einige der Klassennamen selbst deklarieren. Dies ist nur ein kleiner Hack, um Compilerfehler zu vermeiden. Durch die Verwendung der Anweisung declare fordere ich den Compiler im Wesentlichen auf, diese Klasse zuzulassen. Es hilft jedoch nicht bei der Intelligenz, die von verschiedenen Texteditoren verwendet wird.

4
Haseeb Awan 30 Okt. 2018 im 18:28

So implementiere ich die Verwendung von mxGraph auf Angular. Ich hoffe das könnte anderen helfen.

Wichtig: Dies funktionierte nicht bei Angular / Cli - Prod Build. Sie müssen die Optimierungsoption auf angle.json deaktivieren

"production": {
              "outputPath": "dist/PRO",
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              **"optimization": false,**
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
... and so on

Installieren Sie zunächst mxgraph und Typins von npm als Abhängigkeit und Dev-Abhängigkeit

npm install mxgrapf --save
npm install @types/mxgraph --save-dev

Dies muss beide Einträge in der package.json des Projekts generieren

"@types/mxgraph": "github:lgleim/mxgraph-typings",
"mxgraph": "4.0.4",

Danach deklariere ich in derselben Datei alle meine benötigten Klassen, die den mxgraph erweitern. Dies spart die Kosten für die Deklaration von const mx in allen Klassen, die mxgraph verwenden.

Die Datei, die mxgraph-Klassen erweitert, sieht ungefähr so ​​aus:

import { mxgraph } from 'mxgraph'; // Typings only - no code!
declare var require: any;

/**
 *  init mxGraph whith a config object
 */
const mx: typeof mxgraph = require('mxgraph')({
    // mxgraph assets base path
    mxBasePath: 'assets/mxgraph',
    // mxgraph images
    mxImageBasePath: 'assets/mxgraph/images',
    // avoid mxgraph resources load
    mxLoadResources: false,
    mxForceIncludes: false

});

// Objects load in window object
// The original library load, loads object into the window object, this is necesray if you use
// the decode and encode models funcionality of mxgraph. Is necesary that you include all object you 
// use into your models. this is only my case.
window['mxGraphModel'] = mx.mxGraphModel;
window['mxGeometry'] = mx.mxGeometry;
window['MxGeometry'] = mx.mxGeometry;
window['MxPoint'] = mx.mxPoint;
window['mxPoint'] = mx.mxPoint;

/**
 * Into MXUTILITIES exports all the object created by mxgraph as staric properties as we need
 **/
export class MXUTILITIES {
    static mxEvent = mx.mxEvent;
    static mxUtils = mx.mxUtils;
    static mxConstants = mx.mxConstants;
    static mxStencilRegistry = mx.mxStencilRegistry;
    static mxPerimeter = mx.mxPerimeter;
    static mxEdgeStyle = mx.mxEdgeStyle;
    static mxEffects = mx.mxEffects;
    static mxClient = mx.mxClient;
    static mxCodecRegistry = mx.mxCodecRegistry;

}

/**
 * Exports for all classes we need extending mxgrah, you can extend, overwrite methods and so on
 * 
 */
export class MxGraphModel extends mx.mxGraphModel {}
export class MxOutline extends mx.mxOutline { }
export class MxKeyHandler extends mx.mxKeyHandler { }
export class MxCompactTreeLayout extends mx.mxCompactTreeLayout { }
export class MxLayoutManager extends mx.mxLayoutManager { }
export class MxDivResizer extends mx.mxDivResizer { }
export class MxCellOverlay extends mx.mxCellOverlay { }
export class MxImage extends mx.mxImage { }
export class MxEdgeHandler extends mx.mxEdgeHandler { }
export class MxPrintPreview extends mx.mxPrintPreview { }
export class MxWindow extends mx.mxWindow { }
export class MxGraphView extends mx.mxGraphView { }
export class MxGraphHandler extends mx.mxGraphHandler { }
export class MxGraphSelectionModel extends mx.mxGraphSelectionModel { }
export class MxToolbar extends mx.mxToolbar { }
export class MxEventObject extends mx.mxEventObject { }
export class MxCodec extends mx.mxCodec { }
export class MxObjectCodec extends mx.mxObjectCodec { }
export class MxFastOrganicLayout extends mx.mxFastOrganicLayout { }
export class MxGeometry extends mx.mxGeometry { }
export class MxHierarchicalLayout extends mx.mxHierarchicalLayout { }
export class MxStencil extends mx.mxStencil { }
export class MxRubberband extends mx.mxRubberband { }
export class MxCellRenderer extends mx.mxCellRenderer { }
export class MxPoint extends mx.mxPoint { }
export class MxConnector extends mx.mxConnector { }
export class MxLine extends mx.mxLine { }
export class MxArrowConnector extends mx.mxArrowConnector { }
export class MxCell extends mx.mxCell {}
export class MxGraph extends mx.mxGraph {}

Um ein neues Diagramm zu erstellen, verwende ich einen Dienst, der generierte Diagramme speichert und ausgewählte Zellen und neue Diagramme benachrichtigt, die für alle abonnierten Komponenten erstellt wurden

import { Injectable, ElementRef } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { BehaviorSubject, Subject } from 'rxjs';
import { MxCell, MxGraph, MxEventObject, MXUTILITIES, MxGraphSelectionModel } from '../classes/mxgraph.class';


@Injectable({ providedIn: 'root' })
export class GraphsService { 

  private graphsSubject: BehaviorSubject<MxGraph[]> = new BehaviorSubject([]);
  private graphs$: Observable<MxGraph[]>;
  private graphs: MxGraph[] = [];
  
  private selectedCellsSubject: BehaviorSubject<MxCell[]> = new BehaviorSubject([]);
  private selectedCells$: Observable<MxCell[]>;
  private selectedCells: MxCell[];
  
  constructor() {
    this.graphs$ = this.graphsSubject.asObservable();
    this.stamp = Date.now();
  }
 
 /**
   * Generate a new graph into the received container
   *
   * @memberOf GraphsService
   */
  newGraph(graphContainer: ElementRef, name?: string): MxGraph {
    const newGraph: MxGraph = this.initNewGraph(graphContainer, name);
    this.graphs.push(newGraph);
    this.graphsSubject.next(this.graphs);
    return newGraph;
  }

  /**
   * Init new graph
   *
   * @memberOf GraphsService
   */
  private initNewGraph(graphContainer: ElementRef, name: string) {
    let newGraph: MxGraph;
    newGraph = new MxGraph(graphContainer.nativeElement);
    if (!name) name = 'Nuevo gráfico';
    newGraph.getModel().getRoot().setValue(name);
    newGraph.setConnectable(true);
    newGraph.setMultigraph(false);
    newGraph.selectionModel.addListener(MXUTILITIES.mxEvent.CHANGE, (mxGraphSelectionModel: MxGraphSelectionModel, evt: MxEventObject) => {
      this.emitSelectedCell(mxGraphSelectionModel.cells as MxCell[]);

    });

    return newGraph;
  }
  
  /**
   * Emits the selected cells from the graph
   * @memberOf GraphsService
   */
  private emitSelectedCell(cells: MxCell[]) {

    if (!cells) this.selectedCells = [];
    else this.selectedCells = cells;
    this.selectedCellsSubject.next(this.selectedCells);
  }

  
  }
3
Juan Carlos Romero 24 Nov. 2019 im 21:12

Es gibt ein neues mxgraph TypeScripts-Typdefinitionspaket, das weitaus besser funktioniert als alle anderen.

https://www.npmjs.com/package/mxgraph-type-definitions

Hier sind die Schritte, die ich ausgeführt habe, damit dies für ein neues Angular 9-Projekt funktioniert:

Erstellen Sie die Angular 9-App:

ng new graphdemo

Mxgraph hinzufügen:

npm install --save mxgraph

Installieren Sie die mxgraph TypeScript-Typdefinitionen (diese funktionierten besser als alle anderen Typdefinitionen, die ich auf GitHub und NPM gefunden habe):

npm install --save-dev mxgraph-type-definitions

Befolgen Sie dort die Anweisungen, um es zu installieren. Ich bin mir nicht sicher, wie das Angular-Projekt diese Typen am besten finden kann. Aber es hat bei mir funktioniert, die folgende Zeile zur src / main.ts-Datei meiner App hinzuzufügen:

/// <reference path="../node_modules/mxgraph-type-definitions/index.d.ts" />

Fügen Sie die Datei src / assets / js / mxgraph.conf.js mit folgenden Inhalten hinzu:

mxBasePath = 'mxgraph';

In angular.json habe ich hinzugefügt:

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

Und:

"scripts": [
  "src/assets/js/mxgraph.conf.js",
  "node_modules/mxgraph/javascript/mxClient.js"
]

In src / app / app.component.ts:

import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements AfterViewInit {
  @ViewChild('graphContainer') graphContainer: ElementRef;

  ngAfterViewInit(): void {
    const graph = new mxGraph(this.graphContainer.nativeElement);

    try {
      const parent = graph.getDefaultParent();
      graph.getModel().beginUpdate();

      const vertex1: mxCell = graph.insertVertex(parent, '1', 'vertex 1', 0, 0, 70, 30);
      const vertex2: mxCell = graph.insertVertex(parent, '2', 'vertext 2', 0, 0, 70, 30);
      graph.insertEdge(parent, '3', '', vertex1, vertex2);

    } finally {
      graph.getModel().endUpdate();
      new mxHierarchicalLayout(graph).execute(graph.getDefaultParent());
    }
  }
}

Und schließlich in src / app / app.component.html:

<div #graphContainer id="graphContainer"></div>
0
Steve Meierhofer 17 Apr. 2020 im 22:34

Ich konnte auch keine Ressourcen finden, die dieses Problem lösen können. Also habe ich meine eigenen npm-Pakete erstellt, die auch andere verwenden können. Sie können versuchen, eines dieser Pakete für Ihre Anwendung zu verwenden.

ts-mxgraph Typoskriptumhüllte Version der mxgraph-Bibliothek v4.03.
ts-mxgraph-factory Typoskript-Wrapper
ts-mxgraph-typings

Ich habe in meinem Projekt die folgende Methode verwendet.

Schritt 1:
Erstellen Sie die Datei mxgraph.overrides.ts im Projekt

Schritt 2
Importieren Sie mxgraph-Prototypmethoden. Kann auch die ursprünglichen Methoden der Bibliothek selbst erweitern.

import '../../assets/deflate/base64.js'
import '../../assets/deflate/pako.min.js';

import { mxgraph, mxgraphFactory } from "ts-mxgraph";
const mx = mxgraphFactory({
    mxBasePath: 'mxgraph',
    mxLoadResources: false,
    mxLoadStylesheets: false,
});

declare const Base64: any;
declare const pako: any;

let mxActor: any = mx.mxActor;
let mxArrow: any = mx.mxArrow;
let mxArrowConnector: any = mx.mxArrowConnector;
let mxGraph: any = mx.mxGraph;
let mxClient: any = mx.mxClient;
let mxClipboard: any = mx.mxClipboard;
let mxCellMarker: any = mx.mxCellMarker;
let mxCodecRegistry: any = mx.mxCodecRegistry;
let mxDoubleEllipse: any = mx.mxDoubleEllipse;
let mxUtils: any = mx.mxUtils;
...
// extends mxgraph prototypes

mxGraph.prototype.updatePageBreaks = function(visible, width, height) {
    const useCssTranforms = this.useCssTransforms, scale = this.view.scale,
        translate = this.view.translate;

    if (useCssTranforms) {
        this.view.scale = 1;
        this.view.translate = new mxPoint(0, 0);
        this.useCssTransforms = false;
    }

    graphUpdatePageBreaks.apply(this, arguments);

    if (useCssTranforms) {
        this.view.scale = scale;
        this.view.translate = translate;
        this.useCssTransforms = true;
    }
}
// Adds panning for the grid with no page view and disabled scrollbars
const mxGraphPanGraph = mxGraph.prototype.panGraph;
mxGraph.prototype.panGraph = function(dx, dy) {
    mxGraphPanGraph.apply(this, arguments);

    if (this.shiftPreview1 != null) {
        let canvas = this.view.canvas;

        if (canvas.ownerSVGElement != null) {
            canvas = canvas.ownerSVGElement;
        }

        const phase = this.gridSize * this.view.scale * this.view.gridSteps;
        const position = -Math.round(phase - mxUtils.mod(this.view.translate.x * this.view.scale + dx, phase)) + 'px ' +
            -Math.round(phase - mxUtils.mod(this.view.translate.y * this.view.scale + dy, phase)) + 'px';
        canvas.style.backgroundPosition = position;
    }
}
...

export {
    mxClient,
    mxUtils,
    mxRubberband,
    mxEventObject,
    mxEdgeHandler,
    mxEvent,
    mxGraph,
    mxGraphModel,
    mxGeometry,
    mxConstants,
    ...
    }

// and then import these where you want to use them

import {
    mxClient,
    mxUtils,
    mxEvent,
    mxGraph,
    mxGraphModel,
    mxGeometry,
    mxConstants,
    mxCell,
    mxDictionary,
    mxCellEditor,
    mxStyleRegistry
} from './mxgraph.overrides';

import { IMAGE_PATH, STYLE_PATH, STENCIL_PATH, urlParams } from '../config';

declare var Base64: any;
declare var pako: any;

export class Graph extends mxGraph {
...
}
0
rabpeter 24 Apr. 2020 im 20:52