Angular で JointJS を動かすための最初の一歩

Angular に JointJS(https://www.jointjs.com/opensource)を組み込んでグラフ描画を実装しているのですが、日本語の情報がなくて苦労しました。
メモっておいたら役立つかもということで、まずは導入部分での工夫を今回まとめます。

使用しているバージョンはこちら。

パッケージ バージョン
@angular/core 5.2.9
@angular/cli 1.7.4
jointjs 2.0.1

公式サイトのチュートリアルに沿って、動かせる所までやってみます。
https://resources.jointjs.com/tutorial/hello-world

JointJS のパッケージをインストールする

npm install --save jointjs

ここは悩みどころはないはずです。

JointJS を使えるように Component に import する

import { Component, OnInit } from '@angular/core';

import * as joint from 'jointjs';

@Component({
  selector: 'app-simple',
  template: '<div id="myholder"></div>',
  styleUrls: ['./simple.component.css']
})
export class SimpleComponent implements OnInit {
  graph = new joint.dia.Graph;

  constructor() { }

  ngOnInit() {
  }
}

まずは上記のように import * as joint from 'jointjs'; としたいところですが、

node_modules/jointjs/dist/joint.d.ts(1395,34): error TS2503: Cannot find namespace 'JQuery'.

という具合にコンパイルエラーが発生します。

そこで、「import * as joint from 'jointjs';」の代わりに以下のようにして 'jointjs' を使えるようにしました。

declare function require(x: string): any;
const joint = require('jointjs/dist/joint.js');

TypeScript のコンパイラが以下のような require が見つからないとエラーを発生させるので
2行目のように require 関数を宣言してあげる必要があります。

const joint = require('jointjs/dist/joint.js'); ERROR in src/app/simple/simple.component.ts(6,15): error TS2304: Cannot find name 'require'.

Hello World サンプルコード全体

ということで、チュートリアルを動かすサンプルコード全体。
所々で TypeScript 向けに変更してます。

import { Component, OnInit } from '@angular/core';

declare function require(x: string): any;
const joint = require('jointjs/dist/joint.js');

import * as $ from 'jquery';  /* joint.dia.Paper の初期化で $ を使うため */

@Component({
  selector: 'app-simple',
  template: '<div id="myholder"></div>',
  styleUrls: ['./simple.component.css']
})
export class SimpleComponent implements OnInit {

  graph = new joint.dia.Graph;

  paper;

  constructor() { }

  ngOnInit() {
    this.paper = new joint.dia.Paper({
      el: $('#myholder'),
      width: 600,
      heigth: 200,
      model: this.graph,
      gridSize: 1
    });

    const rect = new joint.shapes.basic.Rect({
      position: { x: 100, y: 30 },
      size: { width: 100, height: 30 },
      attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } }
    });

    const rect2 = rect.clone();
    rect2.translate(300);

    const link = new joint.dia.Link({
      source: { id: rect.id },
      target: { id: rect2.id }
    });

    this.graph.addCells([rect, rect2, link]);
  }
}

参考サイト

ここがなかったら無理でした。 github.com