Create.jsで親子関係のツリー図を描く

# 概要
管理画面などで、既存のリストから親子関係のツリーを設定するUIを作ってみたくてやってみる。

有料のライブラリなどは見かけますが、使用料が高い・・・。
また、そこまで高機能なものは必要なかったりしたのでシンプルにする。

## 前提条件
HTML5のCanvasを操作するCreate.jsのライブラリを使っています。

* [CreateJSとは](https://ics.media/tutorial-createjs/basic/)

## ファイル構成
ローカルで動作確認したかったのでdocker使ってます。
※ Github: https://github.com/reflet/flowchart-create.js

```:ファイル構成
├ docker
│  └ nginx
│     └ default.conf
├ src
│  └ html
│    ├ flowchart.js    <- ツリー図を描くスクリプト
│    └ index.html      <- サンプルページ
│
└ docker-compose.yml
```

## サンプルコード
サンプルページのコードはこんな感じです。
※ `create.js` に依存しているので、それはCDNで読み込んでます

```html:src/html/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Create.js - フローチャート</title>
    <style type="text/css">
        body { margin: 0; padding: 0; }
        canvas { background: WhiteSmoke; }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="1024" height="800"></canvas>

    <script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
    <script src="flowchart.js"></script>
    <script>
        window.addEventListener("load", function(){
            var flowchart = new FlowChart('myCanvas');

            // 初期化 (初期データ)
            flowchart.init('佐藤家',[
              {label:'太郎', children:[]},
              ...
              {label: '花子', children: [
                {label: '奈々子', children: []},
                {label: '八重子', children: []},
              ]},
            ]);
        });
    </script>
</body>
</html>
```

`flowchart.js` のコードについては、下記を参照ください。
https://github.com/reflet/flowchart-create.js/blob/master/src/html/flowchart.js

## ローカル環境起動
実際に、ローカルブラウザで、動かしてみます。

```
$ git clone https://github.com/reflet/flowchart-create.js.git .
$ docker-compose up -d
$ open http://localhost:8080
```
こんな感じになりました。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/ee51d1f3-d4d5-a56c-6525-1fdcd7e9f69e.png)

## 追加してみる
「＋」ボタンを押して子要素を追加してみる。

![add1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/a2fa5e25-4934-37e3-94d4-405de68a7729.png)

ラベルを入力し、OKボタンを押すと無事に追加されました。

![add2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/6d69892a-3b08-812e-f585-58deca79198d.png)

## 削除してみる
「✗」ボタンを押して削除してみる。

![remove1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/1daecf01-b7f3-b615-142a-3b600c2b8cc0.png)

無事に削除されました。

![remove2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/fbcd271a-596a-3237-2e7b-315dd950d9ec.png)

## まとめ
カンタンではありますが、とりあえずツリー図を作ることができました。

ドラッグしたり、好きな位置に配置したりもできましたが、
下記のような問題があるため、自動配置するようにしてそのような機能ははずしました。

* 作ったツリーを再度表示する際に個別に座標情報を保存する必要がある
* 重なり合わないようにする計算が面倒だった
* 実際に操作すると複雑で意外と使い難くかった

以上です。

## 参考サイト

- [CreateJSとは](https://ics.media/tutorial-createjs/basic/)
- [公式ドキュメント(英語)](https://createjs.com/docs/easeljs/classes/Graphics.html)
- [フローチャートが作れるミニマルなJavaScriptライブラリ「Flowy」](https://itnews.org/news_contents/oss-flowy)
- [flowchart.js - SVGのフローチャートを生成するJavaScriptライブラリ](https://www.moongift.jp/2015/10/flowchart-js-svg%E3%81%AE%E3%83%95%E3%83%AD%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8Bjavascript%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA/)
- [GoJS](https://www.nwoods.com/products/gojs/)
- [プロ直伝 業務システム開発のためのHTML5攻略ガイド](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E7%9B%B4%E4%BC%9D-%E6%A5%AD%E5%8B%99%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E9%96%8B%E7%99%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEHTML5%E6%94%BB%E7%95%A5%E3%82%AC%E3%82%A4%E3%83%89-%E6%96%B0%E6%97%A5%E9%89%84%E4%BD%8F%E9%87%91%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%BA%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E7%A0%94%E7%A9%B6%E9%96%8B%E7%99%BA%E3%82%BB%E3%83%B3%E3%82%BF%E3%83%BC-hifive%E9%96%8B%E7%99%BA%E3%83%81%E3%83%BC%E3%83%A0/dp/482223763X)
- [CreateJSで、複数の点を滑らかな曲線でつなぐ](https://www.streakimage.jp/createjs/wave_line/index.html)
- [HTML5のcanvasに直線や曲線でパスを描画する](https://kudox.jp/html-css/html5-canvas-path)