D3.js v4/v5 hierarchy データ構造と使い方

2018-02-10

D3.js hierarchy(v4/v5対応)の使い方について説明します。

hierarchyは、階層データを視覚化するためのライブラリで以下の5つの描画が可能です。

それぞれの描画は各ページを参照ください。ここではすべてに共通するデータ構造について解説していきたいと思います。

データ構造

まず、一つのノードに対するデータは以下のフォーマットで準備します。

子、孫ノードを追加したい場合は”children”配列に同じフォーマットのオブジェクトを追加していきます。末端のノードの場合は”children”を省略します。例えば、下の構造のツリーを描画したいときは、

こちらのデータ構造になります。

 

データ構造の変換

用意した上記データを描画するために、2回データ構造を変換する必要があります。

用意した階層データ (上記) → hierarchy用のデータ構造 → 描画種類ごとのデータ構造

といっても、2回とも関数を一つ呼び出すだけです。同じデータ構造で異なる描画に変換できる仕組みになっています。

まず、hierarchy用のデータ構造への変換は下の関数を使います。

rootには、用意したデータと同じ構造のオブジェクトが作成され、以下の変数が追加されます。

node.data ノードに関連する元データへの参照。
node.depth 先頭を0とした深さ方向の位置。整数。
node.height 末端から自ノードまでの最大位置。末端は0。整数。
node.parent 親ノードへの参照。先頭の場合はnull。
node.children 子ノードへの参照。末端の場合は未定義。

root変数自体には先頭のnodeに対応するオブジェクトが格納されており、先ほどと同じ下の構造の場合、

とすれば、ノード”B”のオブジェクトにアクセスできます。

ノードには、次に説明する関数が準備されています。詳細を下に記載します。それぞれのデモと相互参照しながらご覧下さい。

描画種類ごとのデータ構造への変換はそれぞれのデモページを参照ください。

 hierarchyノード用の関数一覧

node.ancestors() 自ノードを含む、親をたどるルートの配列を返します。
node.descendants() 自ノードを含む子、孫をたどる配列を返します。
node.leaves() 自ノードに関連する、末端の(子要素を持たない)ノード配列を返します。
node.path(target) ノードから指定されたターゲットノードへの最短パスをノードを格納した配列で返します。
node.links() ノード間をつなぐリンク配列を次の形式で返します。
[{“source”: 親ノード, “target”:子ノード}, …]
node.sum() 子孫ノードに設定した値の合計値を算出します。function(d) { return d.value; }のように引数に関数を設定します。treemap、partition、packで親の大きさを決定する際に使用します。
node.count() このノード下にある末端のノード数を計算してnode.valueに割り当てます。このノードが末端の場合、1を返します。
node.sort(compare) 指定された比較関数compareを使用して、兄弟間をソートします。
node.each(function) 指定したノードの子、孫要素を順番に、functionの指定に基づいて処理します。
node.eachAfter(function) 指定したノードの子、孫要素を順番に、functionの指定に基づいて処理します。末尾が優先して呼び出されます。子ノードがあるノードは必ず子ノードの後に処理されます。
node.eachBefore(function) 指定したノードの子、孫要素を順番に、functionの指定に基づいて処理します。先頭が優先して呼び出されます。親ノードがあるノードは必ず親ノードの後に処理されます。
node.copy() 指定したノードから始まるサブツリーのディープコピーを返します。コピーしたツリーの先頭要素の親はnullになります。

まとめ

入れ子になった構造から、ノードだけを配列で再構成してくれるなど、便利な関数が用意されています。具体的な使い方はデモを参照ください。