web-dev-qa-db-ja.com

mxGraphをAngular 4と統合する方法は?

私はAngular 4に取り組んでおり、プロジェクトにmxGraphを統合したいと思っています。グーグルで検索しましたが、完全に機能する例を取得できていません。

私は次の方法を試しましたが、それもうまくいきません。

私が従った手順:

  1. インストールされたmxgraph:_npm install mxgraph --save_

    mxgraphのnpmパッケージ: https://www.npmjs.com/package/mxgraph

  2. インストールされたmxgraph-typings:_npm install lgleim/mxgraph-typings --save_

    Mxgraph-typingsのGithubリポジトリ- https://github.com/lgleim/mxgraph-typings

  3. これで、コンポーネントにインポートしました:_import {mxgraph} from 'mxgraph';_

  4. MxGraphアセットを使用できるようにするために、.angular-cli.jsonアセット配列に次の行を追加しました。

    _{"glob":"**/*", "input":"node_modules/mxgraph/javascript/src", "output": "./mxgraph"}
    _
  5. 次のように使用しようとすると:const graph: mxgraph.mxGraph = new mxgraph.mxGraph(document.getElementById('graphContainer'));

    そして、私が_ng serve_を実行すると

    次に、次のような問題/エラーが発生します。
    _Module not found: Error: Can't resolve 'mxgraph' in 'path to my file where I have imported and used mxgraph'_

  6. MxBasePathを設定してみると、次のようになります。

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

    そしてこのように使用されます:

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

    そして、私が_ng serve_を実行すると

    今回も同じ問題/エラーが発生しています:
    _Module not found: Error: Can't resolve 'mxgraph' in 'path to my file where I have imported and used mxgraph'_

誰かが私がここで何が欠けているのかについて何か考えがありますか?またはなぜそれが機能しないのですか?

誰かがmxGraphをAngular 4と統合する他の/より良い方法を知っているなら、私に知らせてください。

前もって感謝します !!

6
viks

Angular 4/5/6でmxGraphの統合にまだ苦労している人がいる場合は、完全な解決策があります。

さまざまなmxGraphリポジトリに関する詳細:

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.

ステップ:

  1. クローンレポ-4。また、公式リポジトリ(Repo-2など)のリモートを追加して、最新のmxGraphの更新/リリース/修正を取得します。

  2. ディレクトリをmxgraph2に変更し、npminstallを実行します

    $ cd mxgraph2
    $ npm install

  3. 次に、angularプロジェクトリポジトリに移動し、mxGraph(つまり、ローカルでビルドしたmxgraph2)をインストールします。

    $ npm install /path/to/mxgraph2

    例えばnpm install /home/user/workspace/mxgraph2

    これにより、package.jsonファイルに以下と同様のエントリが追加されます。

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

  4. 通常のnpmインストールを1回実行します。不足している/依存関係のパッケージを追加するため。

    $ npm install

  5. 次に、mxgraphタイピングをインストールします

    注-TypeScriptの最小必要バージョンは2.4.0です

    $ npm install lgleim/mxgraph-typings --save

  6. これで、アプリでmxGraphを使用できます。

    私。 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. それでおしまい !!

お役に立てば幸いです。

5
viks

私はまったく同じ問題を抱えています。 'lgleim'によると、問題はmxgraphnpmパッケージにあります。この問題については、ここで説明します: https://github.com/jgraph/mxgraph/issues/169

私はその問題を解決できません。ただし、次の記事に従ってmxgraphをangular 7と正常に統合しました: https://itnext.io/how-to-integrate-mxgraph-with-angular-6-18c3a2bb8566

ステップ1

まず、最新バージョンのmxgraphをインストールします。

npm install mxgraph

ステップ2

次に、 https://github.com/gooddaytoday/mxgraph-TypeScript-definitions.git から入力をダウンロードします。ファイルをangularプロジェクトの 'src'フォルダーに抽出します

ステップ3

Angle.jsonファイルに以下を追加します。

  1. アセット配列に以下を追加します。

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

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

  2. スクリプト配列に以下を追加します。

    "node_modules/mxgraph/javascript/mxClient.js"

2つのスクリプトとアセット配列があります。 「ビルド」に1回、「テスト」に1回。両方を追加します。

それをすべて行った後、あなたは行ってもいいです。 :)

サンプルコード:

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());
    }
  }

}

mxPerimeterおよびmxConstantsを宣言するためにdeclareステートメントを使用したことに注意してください。その理由は、型の定義が不完全であるためです。したがって、クラス名のいくつかを自分で宣言する必要がありました。これは、コンパイラエラーを回避するためのちょっとしたハックです。宣言ステートメントを使用することにより、私は基本的にコンパイラーにこのクラスを許可するように指示しています。ただし、さまざまなテキストエディタで使用されるインテリセンスには役立ちません。

4
Haseeb Awan

これは、AngularでmxGraphの使用を実装する方法です。これが他の人の役に立つことを願っています。

重要:これはangular/cli --prodbuildでは機能しませんでした。 angle.jsonの最適化オプションを無効にする必要があります

"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

まず、依存関係とdev-dependencyとしてnpmからmxgraphとtypinsをインストールします

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

これにより、プロジェクトのpackage.jsonに両方のエントリが生成される必要があります

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

その後、同じファイルでmxgraphを拡張する必要なすべてのクラスを宣言します。これにより、mxgraphを使用するすべてのクラスでconstmxを宣言するコストを節約できます。

Mxgraphクラスを拡張するファイルは次のようなものです。

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 {}

新しいグラフを作成するには、生成されたグラフを保存し、選択したセルと作成された新しいグラフをすべてのサブスクライブされたコンポーネントに通知するサービスを使用します

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);
  }

  
  }
2

他のどのパッケージよりもはるかにうまく機能する新しいmxgraphTypeScriptsタイプ定義パッケージがあります。

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

これを新しいAngular 9プロジェクトで機能させるために私が従った手順は次のとおりです。

Angular 9アプリを作成します:

ng new graphdemo

Mxgraphを追加します。

npm install --save mxgraph

Mxgraph TypeScriptタイプ定義をインストールします(これらは、GitHubとNPMで見つけた他のタイプ定義のどれよりもうまく機能しました):

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

そこにある指示に従ってインストールしてください。 Angularプロジェクトがこれらのタイプを見つけるための最良の方法はわかりませんが、アプリのsrc /main.tsファイルに次の行を追加することでうまくいきました。

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

次の内容のファイルsrc/assets/js /mxgraph.conf.jsを追加します。

mxBasePath = 'mxgraph';

Angle.jsonに、次を追加しました。

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

そして:

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

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());
    }
  }
}

そして最後に、src/app/app.component.htmlで:

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