コンテンツへスキップ

階層化

· 次の関係性の表を考えてみましょう。

名前
イブ
カインイブ
セツイブ
エノスセツ
ノアムセツ
アベルイブ
アワンイブ
エノクアワン
アズライブ

これらの名前は都合よく一意なので、階層をCSVファイルとして明確に表現できます。

name,parent
Eve,
Cain,Eve
Seth,Eve
Enos,Seth
Noam,Seth
Abel,Eve
Awan,Eve
Enoch,Awan
Azura,Eve

csvParseを使用してCSVを解析するには

js
const table = d3.csvParse(text);

これにより、{name, parent} オブジェクトの配列が返されます。

json
[
  {"name": "Eve",   "parent": ""},
  {"name": "Cain",  "parent": "Eve"},
  {"name": "Seth",  "parent": "Eve"},
  {"name": "Enos",  "parent": "Seth"},
  {"name": "Noam",  "parent": "Seth"},
  {"name": "Abel",  "parent": "Eve"},
  {"name": "Awan",  "parent": "Eve"},
  {"name": "Enoch", "parent": "Awan"},
  {"name": "Azura", "parent": "Eve"}
]

階層に変換するには

js
const root = d3.stratify()
    .id((d) => d.name)
    .parentId((d) => d.parent)
  (table);

この階層は、可視化のために、treeなどの階層レイアウトに渡すことができるようになりました。

階層化演算子は、ファイルシステムで一般的な区切りパスでも機能します。

stratify()

ソース · デフォルト設定で新しい階層化演算子を構築します。

js
const stratify = d3.stratify();

stratify(data)

ソース · 指定された表形式のdataから新しい階層を生成します。

js
const root = stratify(data);

stratify.id(id)

ソース · idが指定されている場合、idアクセサを指定された関数に設定し、この階層化演算子を返します。それ以外の場合は、現在のidアクセサを返します。これはデフォルトで

js
function id(d) {
  return d.id;
}

idアクセサは、階層化演算子に渡される入力データ内の各要素に対して呼び出され、現在のデータ(d)と現在のインデックス(i)が渡されます。返された文字列は、親idと組み合わせて、ノードの関係を識別するために使用されます。リーフノードの場合、idは未定義の場合があります。それ以外の場合、idは一意である必要があります。(nullと空の文字列は未定義と同等です。)

stratify.parentId(parentId)

ソース · parentIdが指定されている場合、親idアクセサを指定された関数に設定し、この階層化演算子を返します。それ以外の場合は、現在の親idアクセサを返します。これはデフォルトで

js
function parentId(d) {
  return d.parentId;
}

親idアクセサは、階層化演算子に渡される入力データ内の各要素に対して呼び出され、現在のデータ(d)と現在のインデックス(i)が渡されます。返された文字列は、idと組み合わせて、ノードの関係を識別するために使用されます。ルートノードの場合、親idは未定義である必要があります。(nullと空の文字列は未定義と同等です。)入力データにはルートノードが1つだけ存在し、循環関係があってはなりません。

stratify.path(path)

ソース · pathが指定されている場合、パスアクセサを指定された関数に設定し、この階層化演算子を返します。それ以外の場合は、現在のパスアクセサを返します。これはデフォルトで未定義です。

パスアクセサが設定されている場合、idおよびparentIdアクセサは無視され、パスアクセサによって返されるスラッシュで区切られた文字列でUnixライクな階層が計算され、親ノードとidが必要に応じて推測されます。

たとえば、ローカルディレクトリでUNIX findコマンドの出力が得られた場合

js
const paths = [
  "axes.js",
  "channel.js",
  "context.js",
  "legends.js",
  "legends/ramp.js",
  "marks/density.js",
  "marks/dot.js",
  "marks/frame.js",
  "scales/diverging.js",
  "scales/index.js",
  "scales/ordinal.js",
  "stats.js",
  "style.js",
  "transforms/basic.js",
  "transforms/bin.js",
  "transforms/centroid.js",
  "warnings.js",
];

次のように記述できます

js
const root = d3.stratify().path((d) => d)(paths);