react-d3-tree使ってみた

はじめに

ツリー表示のチャートを作りたかったので、react-d3-tree を使ってツリーチャートを作成してみました。
ノードのカスタマイズを中心に、備忘録的に使い方を記録しておきます。

使い方

まずはreact-d3-treeをインストールします。

$ npm i react-d3-tree

グラフを描画する

適当にデータを作ってグラフを描画してみましょう。
RawNodeDatum クラスの型でデータを作ります。

import * as React from 'react'
import Tree from 'react-d3-tree'
import { RawNodeDatum } from 'react-d3-tree/lib/types/common'

const IndexTemplate: React.FC = () => {
  const nodes: RawNodeDatum = {
    name: '由仁 太郎',
    children: [
      {
        name: '由仁 次郎'
      },
      {
        name: '由仁 三郎',
        children: [
          {
            name: '由仁 四郎'
          },
          {
            name: '由仁 五郎'
          }
        ]
      }
    ]
  }
  return (
    <>
      <div style={{ width: '100vw', height: '100vh' }}>
        <Tree data={nodes} />
      </div>
    </>
  )
}

export default IndexTemplate

実行するとこんな感じ。

とってもシンプルなツリーチャートが表示されました。

プロパティを変更してみる

プロパティの変更でいろいろとカスタマイズできます。

<Tree
    data={nodes}
    orientation="vertical"
    pathFunc="step"
    collapsible={false}
    separation={{ siblings: 3 }}
    depthFactor={-200}
/>

チャートの向きを設定する orientation プロパティとか
線の形状を変える pathFunc とか
子ノードの折り畳みを設定する collapsible とか
プロパティをあれこれ変更するだけでもそれなりに自分好みのチャートは作れそうな感じです。
ちなみに上の設定にしたチャートがこんな感じ。

だいぶ雰囲気が変わりましたね。
とはいえまだまだかなりシンプルですね。
ん~~~、ノードをもうちょっと小洒落た感じにしたい……。

ノードのデザインを変更してみる

まずはノードの表示名に、名前以外の値を表示してみようと思います。
補足データを attributes に放り込んで……

const nodes: RawNodeDatum = {
    name: '由仁 太郎',
    attributes: {
      age: '87歳'
    },
    children: [
      {
        name: '由仁 次郎',
        attributes: {
          age: '63歳'
        }
      },
      {
        name: '由仁 三郎',
        attributes: {
          age: '59歳'
        },
        children: [
          {
            name: '由仁 四郎',
            attributes: {
              age: '31歳'
            }
          },
          {
            name: '由仁 五郎',
            attributes: {
              age: '29歳'
            }
          }
        ]
      }
    ]
  }

実行してみるとこんな感じ。

表示はされたけど、やっぱり地味だし、見出しに「age」とか表示されているのはちょっと……
ということで、がっつりノードを変更しちゃいましょう!
チャートはSVGで描画されるので、ノードもSVGでごりごり組んで……

interface TreeChartProps {
  nodeDatum: RawNodeDatum
}

const customNodeElement: React.FC<TreeChartProps> = ({ nodeDatum }) => {
  return (
    <g>
      <rect
        x="-75"
        rx="5"
        ry="5"
        style={{
          width: '150',
          height: '85',
          fill: 'turquoise',
          stroke: 'salmon',
          strokeWidth: '3'
        }}
      />
      <text
        x="-60"
        y="38"
        style={{
          fill: 'white',
          strokeWidth: '0',
          fontWeight: 'bold',
          fontSize: '1.4em',
          maxWidth: '280'
        }}
      >
        {nodeDatum.name}
      </text>
      <text
        x="-60"
        y="60"
        style={{
          fill: 'lightcyan',
          strokeWidth: '0',
          fontSize: '0.9em',
          maxWidth: '280'
        }}
      >
        {`年齢:${nodeDatum.attributes?.age}`}
      </text>
    </g>
  )
}

作ったノードをツリーチャートに渡して……

<Tree
    data={nodes}
    renderCustomNodeElement={(rd3tNodeProps) =>
        customNodeElement({
            ...rd3tNodeProps
        })
    }
    orientation="vertical"
    pathFunc="step"
    collapsible={false}
    separation={{ siblings: 3 }}
    depthFactor={-200}
/>

じゃじゃーーーん!

形を変えたり色をつけたり、好き勝手してみました!
(あくまでノードのカスタマイズなのでね、デザインのことには触れないで頂きたい……( ˘ω˘ ))

さいごに

他にもプロパティいろいろあって、かなり好き勝手できそうな感じでした。
あんまりツリーチャートって使う機会がないかもしれませんが、
それゆえあんまり記事も見つからなかったので、この記事がどこかの誰かのお役に立てれば幸いです。

>

株式会社ユニフェイスは製造業向けのシステムを開発している会社です。
紙運用からの脱却やIoTデバイスなどを利用した実績自動収集、リアルタイムな情報共有など製造現場の最適化をご提案しています。


株式会社ユニフェイス
製造実行システムとは?
製造実行システムIB-Mes
見える化システムIB-Skin