はじめに
JointJSを用いるとJavaScript側でフローチャート等の図を簡単に描くことができます。
JointJSの基本的な使用方法は以下が参考になります。
また、本記事で紹介する内容も以下記事のサンプルをほぼそのまま利用させていただいています。
参考記事:インタラクティブに図が書けるJointJsを使ってみた
これを使って、例えば裏で動いているデータ分析やデバイス連携の処理をフローチャートで簡単に設定できるようにする、
といったWebサービスを開発することができます。(例えばNode-REDのような)
そのためにはインタラクティブなフローチャートを描画するだけでなく、
フローチャートの各要素(ブロックやリンク)の属性を抽出し、
POSTしたりajaxしたりでデータをサーバに送信する、という処理が必要になってきます。
そこで本記事ではJointJSのAPIの中から、要素の属性抽出に関連するAPIを紹介していきます。
動作確認環境
- JointJS: Development version 3.0.2
- jQuery: 3.4.1
- Lodash: 4.17.11
- Backbone: 1.4.0
すべてこちらからダウンロードできます。
フローチャートのサンプル
以下の3つのブロック(element)と2本のリンク(link)をもつフローチャートを例に説明していきます。

各ブロックにはdivNameに"mycell1"、"mycell2"、"mycell3"が設定されています。
以降、JavaScriptにて
graph = new joint.dia.Graph;
と定義されているものとしてgraphに対してAPIを使用していきます。
APIの紹介
多数あるAPIの中でもdia.Graph.prototype.getBBoxから始まるdia.Graph.prototype.get~というAPI群がありますが数が多いので一部だけ紹介します。
dia.Graph.prototype.getCells
graph内のすべてのelementとlinkを配列で取得します。
var cells = graph.getCells();
cells.forEach(function(cell){
console.log(JSON.stringify(cell));
});
結果
{"type":"org.Arrow","source":{"selector":".card","id":"0148eff1-ea1b-40b2-afc9-2bc031e586ce"},"target":{"selector":".card","id":"2e8732f3-8b98-4793-a6ea-406dd60ddba2"},"z":-1,"vertices":[{"x":100,"y":120},{"x":150,"y":60}],"id":"276c7e3c-ca4c-4e4c-8e32-0c20b88b3f98","attrs":{}}
{"type":"org.Arrow","source":{"selector":".card","id":"2e8732f3-8b98-4793-a6ea-406dd60ddba2"},"target":{"selector":".card","id":"1d8a053e-98ac-49a9-bab5-758d66759881"},"z":-1,"vertices":[{"x":100,"y":120},{"x":150,"y":60}],"id":"89e965e8-e1c2-4200-ba27-ed3d73fa82aa","attrs":{}}
{"type":"html.Element","position":{"x":80,"y":80},"size":{"width":170,"height":80},"angle":0,"divName":"mycell1","isCompany":true,"id":"0148eff1-ea1b-40b2-afc9-2bc031e586ce","z":1,"attrs":{}}
{"type":"html.Element","position":{"x":490,"y":90},"size":{"width":170,"height":80},"angle":0,"divName":"mycell2","id":"2e8732f3-8b98-4793-a6ea-406dd60ddba2","z":2,"attrs":{}}
{"type":"html.Element","position":{"x":558,"y":344},"size":{"width":170,"height":80},"angle":0,"divName":"mycell3","id":"1d8a053e-98ac-49a9-bab5-758d66759881","z":3,"attrs":{}}
- "type"が"org.Arrow"になっているものがブロックを接続する線です。"source"から"target"に接続されており、それぞれの"id"でどのブロックであるか特定できます。
- "type"がhtml.Element"になっているものがブロックです。描画されている座標("position")やサイズ("size")が取得できます。設定した"diveName"も反映されていることがわかります。こちらの"id"と"org.Arrow"の"source"や"target"の"id"を比較して操作することもできそうです。
dia.Graph.prototype.getElements
getCellsではelementとlinkの全てを取得しましたが、getElementsでは全てのelementのみ取得します。
dia.Graph.prototype.getLinks
同様にgetLinksでは全てのlinkのみ取得します。
dia.Graph.prototype.getConnectedLinks
あるelementに接続されている全てのlinkを取得します。
var elements = graph.getElements();
console.log(JSON.stringify(elements[0]));
var links = graph.getConnectedLinks(elements[0]);
links.forEach(function(link){
console.log(JSON.stringify(link));
});
結果
{"type":"html.Element","position":{"x":80,"y":80},"size":{"width":170,"height":80},"angle":0,"divName":"mycell1","isCompany":true,"id":"1d0d270e-642a-403e-808e-0d63d60dd589","z":1,"attrs":{}}
{"type":"org.Arrow","source":{"selector":".card","id":"1d0d270e-642a-403e-808e-0d63d60dd589"},"target":{"selector":".card","id":"f904240e-92fb-4af0-aef1-97f0422a047a"},"z":-1,"vertices":[{"x":100,"y":120},{"x":150,"y":60}],"id":"f3bd7d00-4697-4f29-acc5-331e857e69ba","attrs":{}}
- getElementsで取得したelementから最初のelementを取得してgetConnectedLinksに入れています。
- element[0]に接続されているlinkのみ取得されていることが"id"からわかります。
- オプションで「外に出ていくlink」や「内に入ってくるlink」を指定することもできます。
dia.Graph.prototype.toJSON
getCellsとほぼ同じ情報が得られるようです。
toJSONが返却するのはJSON文字列ではない点にお気を付けください。
console.log(JSON.stringify(graph.toJSON()));
結果
{"cells":[{"type":"org.Arrow","source":{"selector":".card","id":"26578cbf-aa01-40ab-8752-05c874a64fa9"},"target":{"selector":".card","id":"de7626c7-6cab-48e8-a5c2-8298e6a11483"},"z":-1,"vertices":[{"x":100,"y":120},{"x":150,"y":60}],"id":"cf9a1a1a-234f-43ec-83d6-019e8dc80010","attrs":{}},{"type":"org.Arrow","source":{"selector":".card","id":"de7626c7-6cab-48e8-a5c2-8298e6a11483"},"target":{"selector":".card","id":"b0a28724-1a33-4deb-8877-02c1378f7465"},"z":-1,"vertices":[{"x":100,"y":120},{"x":150,"y":60}],"id":"f5d76d9d-a256-483d-abc0-f1ba228e90a9","attrs":{}},{"type":"html.Element","position":{"x":80,"y":80},"size":{"width":170,"height":80},"angle":0,"divName":"mycell1","isCompany":true,"id":"26578cbf-aa01-40ab-8752-05c874a64fa9","z":1,"attrs":{}},{"type":"html.Element","position":{"x":190,"y":277},"size":{"width":170,"height":80},"angle":0,"divName":"mycell2","id":"de7626c7-6cab-48e8-a5c2-8298e6a11483","z":2,"attrs":{}},{"type":"html.Element","position":{"x":297,"y":483},"size":{"width":170,"height":80},"angle":0,"divName":"mycell3","id":"b0a28724-1a33-4deb-8877-02c1378f7465","z":3,"attrs":{}}]}
おわりに
JointJSはあまり日本語の情報がないため、本家のAPI一覧を見ていくのが基本になります。
一方でAPIの数が多く探しにくいこともあるため、この記事が参考になれば幸いです。