vis.jsでグラフ描写

vis.jsの使い方をメモしておきます。

#基本的なグラフ
公式のexampleの[basic](http://visjs.org/examples/network/basicUsage.html)グラフに幾つかのオプションを設定して描写してみます。


<p data-height="265" data-theme-id="0" data-slug-hash="EQeeZY" data-default-tab="html,result" data-user="NomuraS" data-embed-version="2" data-pen-title="vis.js example1" class="codepen">See the Pen <a href="https://codepen.io/NomuraS/pen/EQeeZY/">vis.js example1</a> by NomuraS (<a href="https://codepen.io/NomuraS">@NomuraS</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

コードの各部分を説明しておきます。


###htmlにグラフのidを配置する


```html:html
<div id="mynetwork"></div>
```

###ノードとエッジの定義

```js:javascript
  // ノードの定義
var nodes = new vis.DataSet([
      { id: 1, label: 'Node 1' },
      // ノードにfont: { multi: true }を追加することで<i></i>、<b></b>、<code></code>タグが使えて、また個々のフォントカラーが設定できる
      { id: 2, font: { multi: true }, label: '<b>Node 2</b>' },
      { id: 3, font: { multi: true }, label: '<code>Node 3</code>' },
      { id: 4, font: { multi: true }, label: '<i>Node 4</i>' },
      { id: 5, font: { multi: true }, label: '<i><b>Node 5</b></i>' }
]);

  // エッジの定義
  var edges = new vis.DataSet([
    {from: 1, to: 3},
    {from: 1, to: 2},
    {from: 2, to: 4},
    {from: 2, to: 5},
    {from: 3, to: 3}
  ]);

// グラフの定義(ノードとエッジ)
  var data = {
    nodes: nodes,
    edges: edges
  };
```

###オプション設定
基本的なオプションを幾つか設定しています。もっと詳細に設定できるので、[公式ドキュメント](http://visjs.org/docs/network/)を参照してください。

```js
var options = {
      physics: false, // 物理シミュレーションをオフにする
      nodes: {
            shape: 'box', // ノードの形をellipseからboxに
            size: 20, //　ノードの大きさ
            font: {
              boldital: { color: 'pink' }, // <i><b>aaa</b></i>タグのカラー
              ital: { color: 'orange' },  // <i>aaa</i>タグのカラー
              mono: { color: 'blue' }, // <code>aaa</code>タグのカラー
              bold: { color: 'purple' }, // <b>aaa</b>タグのカラー
              color: 'yellow', // タグなしのノードの文字の色
            },
            color: "skyblue" // ノードカラー
      },
      edges: {
            arrows: 'to', // エッジに矢印を付けて有向グラフにする
            smooth: false // falseにするとエッジが直線になる
      },
};
```


###グラフの描写
次のコードでhtmlの id="mynetwork"の場所にグラフが出現します。

```js
  // create a network
  var container = document.getElementById('mynetwork');
  var network = new vis.Network(container, data, options);
```

#グラフの動的な操作
グラフの物理シミュレーションの操作パネルとノード・エッジの追加/削除のパネルを追加します。両方共公式で用意されているものを使います。

<p data-height="265" data-theme-id="0" data-slug-hash="jZeVBg" data-default-tab="js,result" data-user="NomuraS" data-embed-version="2" data-pen-title="vis.js example2" class="codepen">See the Pen <a href="https://codepen.io/NomuraS/pen/jZeVBg/">vis.js example2</a> by NomuraS (<a href="https://codepen.io/NomuraS">@NomuraS</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

##JSのoption
細かい記述はCodePenのサンプルを見てもらえば良いとして、vis.jsのオプションだけ再掲しておきます。オプションは次のようになっています。

```js

            var options = {
                // ノード・エッジ追加/削除ポップアップパネル
                manipulation: {
                    addNode: function (data, callback) {
                        // filling in the popup DOM elements
                        document.getElementById('operation').innerHTML = "Add Node";
                        document.getElementById('node-id').value = data.id;
                        document.getElementById('node-label').value = data.label;
                        document.getElementById('saveButton').onclick = saveData.bind(this, data, callback);
                        document.getElementById('cancelButton').onclick = clearPopUp.bind();
                        document.getElementById('network-popUp').style.display = 'block';
                    },
                    editNode: function (data, callback) {
                        // filling in the popup DOM elements
                        document.getElementById('operation').innerHTML = "Edit Node";
                        document.getElementById('node-id').value = data.id;
                        document.getElementById('node-label').value = data.label;
                        document.getElementById('saveButton').onclick = saveData.bind(this, data, callback);
                        document.getElementById('cancelButton').onclick = cancelEdit.bind(this, callback);
                        document.getElementById('network-popUp').style.display = 'block';
                    },
                    addEdge: function (data, callback) {
                        if (data.from == data.to) {
                            var r = confirm("Do you want to connect the node to itself?");
                            if (r == true) {
                                callback(data);
                            }
                        } else {
                            callback(data);
                        }
                    }
                },
                // 物理変更パネル
                configure: {
                    filter: function (option, path) {
                        if (path.indexOf('physics') !== -1) {
                            return true;
                        }
                        if (path.indexOf('smooth') !== -1 || option === 'smooth') {
                            return true;
                        }
                        return false;
                    },
                    container: document.getElementById('config')
                }

            };
```
clearPopUp、cancelEdit、saveDataという関数は別に定義しておきます。

```js
    function clearPopUp() {
            document.getElementById('saveButton').onclick = null;
            document.getElementById('cancelButton').onclick = null;
            document.getElementById('network-popUp').style.display = 'none';
        }

        function cancelEdit(callback) {
            clearPopUp();
            callback(null);
        }

        function saveData(data, callback) {
            data.id = document.getElementById('node-id').value;
            data.label = document.getElementById('node-label').value;
            clearPopUp();
            callback(data);
        }
```