React で JointJs を動かす

React で JointJs (https://www.jointjs.com/) を使う方法がわからなかったので調べた。
https://resources.jointjs.com/tutorial/hello-world のコードが動くようにしたい。


コマンドラインで create-react-app を実行して、雛形からはじめる

> npx create-react-app react-jointjs
> cd react-jointjs

jointjs をインストール

> npm install jointjs --save

アプリケーションを実行する。以後、App.js を編集してセーブすれば自動的にページが更新される

> npm start

App.js を次のように編集する。
追加部分は jointjs の helloworld のコードの var を let にして、ノード(#myholder)への参照を書き換えた。

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
//// ここから追加部分
import joint from 'jointjs';

class JointJs extends Component {
  constructor() {
    super();
    this.jointHolder = React.createRef();
  }

  componentDidMount() {
    let graph = new joint.dia.Graph;

    let paper = new joint.dia.Paper({
      el: this.jointHolder.current,
      model: graph,
      width: 600,
      height: 100,
      gridSize: 1
    });

    let rect = new joint.shapes.standard.Rectangle();
    rect.position(100, 30);
    rect.resize(100, 40);
    rect.attr({
      body: {
        fill: 'blue'
      },
      label: {
        text: 'Hello',
        fill: 'white'
      }
    });
    rect.addTo(graph);
    let rect2 = rect.clone();
    rect2.translate(300, 0);
    rect2.attr('label/text', 'World!');
    rect2.addTo(graph);

    let link = new joint.shapes.standard.Link();
    link.source(rect);
    link.target(rect2);
    link.addTo(graph);
  }

  render() {
    return (
      <div ref={this.jointHolder}></div>
    );
  }
}
//// ここまで追加部分

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
        <JointJs/> // この一行のみ追加
      </div>
    );
  }
}

export default App;

これでとりあえず動く。