🌲

【D3.js】トーナメント型の線形ツリーUI開発

2021/09/13に公開

以前、D3.jsのhierarchyAPIを使って、階層構造UIの開発を行いました。
前回の記事では、親子ノードが曲線で繋がっていましたが、今回は折れ線で親子ノードを繋げていきたいと思います。

hierarchyを使った、階層UIの開発は以下の記事を御覧ください。
https://zenn.dev/yuji/articles/a4af2b32e99a42

それでは、線形ツリー描画の仕組みを説明していきます。

ノード位置の取得

今回はsvgで線を描いていくため、pathプロパティに渡す座標位置を取得する必要があります。
d3のAPIを介したチェーンメソッドは、引数にノード情報を持つので、そこからノードの座標位置を取得します。

.attr("d", d => { /** d = ノードオブジェクト **/ }

対象ノードはd.xd.yで座標位置を取得します。
※四角のグレーノード作成はここでは割愛
ノードオブジェクト(対象ノード=晴れ)が持つノード位置は以下の赤丸。

上記の赤丸のx、yを基準に親ノードとの線形を描いていく

親ノード位置の取得

親ノードはd.parent.xd.parent.yで座標位置を取得します。
親ノードのノード位置は以下の青丸。

pathプロパティに描画位置を設定する

折れ線を描画するためには、今回、4地点が必要。以下の緑丸地点を取得してpathプロパティに設定します。
※今回のノードの幅を140px、高さを60pxとする

.attr("d", d => `M${A地点} L${B地点} ${C地点} ${D地点}`);
.attr(
        "d",
        (d) => `
          M${d.x + 140 / 2}, ${d.y} // A地点
          L${d.x + 140 / 2}, ${d.y - 30} // B地点
          ${d.parent.x + 140 / 2}, ${d.y - 30} // C地点
          ${d.parent.x + 140 / 2}, ${d.parent.y + 60} // D地点
        `
      );

以上で、親子ノードが折れ線で繋がった線形ツリーが作成できました。
全ソースをご覧になりたい場合は以下のデモを御覧ください。

Discussion