分层
🌐 Stratify
示例 · 考虑下列表格中的关系:
| 名称 | 父级 |
|---|---|
| 夏娃 | |
| 该隐 | 夏娃 |
| 塞特 | 夏娃 |
| 以挪士 | 塞特 |
| 挪亚姆 | 塞特 |
| 亚伯 | 夏娃 |
| 阿挪 | 夏娃 |
| 以挪 | 阿挪 |
| 阿祖拉 | 夏娃 |
| 🌐 Name | Parent |
|---|---|
| Eve | |
| Cain | Eve |
| Seth | Eve |
| Enos | Seth |
| Noam | Seth |
| Abel | Eve |
| Awan | Eve |
| Enoch | Awan |
| Azura | Eve |
这些名称非常方便,因此我们可以将层次结构清晰地表示为 CSV 文件:
🌐 These names are conveniently unique, so we can unambiguously represent the hierarchy as a CSV file:
name,parent
Eve,
Cain,Eve
Seth,Eve
Enos,Seth
Noam,Seth
Abel,Eve
Awan,Eve
Enoch,Awan
Azura,Eve使用 csvParse 解析 CSV:
🌐 To parse the CSV using csvParse:
const table = d3.csvParse(text);这会返回一个包含 {name, parent} 对象的数组:
🌐 This returns an array of {name, parent} objects:
[
{"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"}
]转换为 层次结构:
🌐 To convert to a hierarchy:
const root = d3.stratify()
.id((d) => d.name)
.parentId((d) => d.parent)
(table);这个层次结构现在可以传递给层次布局,例如 tree,以进行可视化。
🌐 This hierarchy can now be passed to a hierarchical layout, such as tree, for visualization.
分层操作符也可以与分隔路径一起使用,这在文件系统中很常见。
🌐 The stratify operator also works with delimited paths as is common in file systems.
stratify()
来源 · 使用默认设置构建一个新的分层操作符。
const stratify = d3.stratify();分层(数据)
🌐 stratify(data)
来源 · 从指定的表格数据生成新的层次结构。
const root = stratify(data);stratify.id(id)
来源 · 如果指定了 id,则将 id 访问器设置为给定的函数并返回此 stratify 操作符。否则,返回当前的 id 访问器,默认值为:
function id(d) {
return d.id;
}对于传递给stratify operator的输入数据中的每个元素,都会调用 id 访问器,并传入当前数据 (d) 和当前索引 (i)。返回的字符串随后与parent id 一起用于标识节点的关系。对于叶节点,id 可以未定义;否则,id 必须唯一。(Null 和空字符串等同于未定义。)
🌐 The id accessor is invoked for each element in the input data passed to the stratify operator, being passed the current datum (d) and the current index (i). The returned string is then used to identify the node’s relationships in conjunction with the parent id. For leaf nodes, the id may be undefined; otherwise, the id must be unique. (Null and the empty string are equivalent to undefined.)
stratify.parentId(parentId)
来源 · 如果指定了 parentId,则将父 ID 访问器设置为给定的函数并返回此分层操作符。否则,返回当前的父 ID 访问器,默认值为:
function parentId(d) {
return d.parentId;
}对于传递给stratify操作符的输入数据中的每个元素,都会调用父ID访问器,并传递当前数据(d)和当前索引(i)。返回的字符串随后用于与id结合以识别节点的关系。对于根节点,父ID应为未定义。(Null和空字符串等同于未定义。)输入数据中必须恰好有一个根节点,并且不能有循环关系。
🌐 The parent id accessor is invoked for each element in the input data passed to the stratify operator, being passed the current datum (d) and the current index (i). The returned string is then used to identify the node’s relationships in conjunction with the id. For the root node, the parent id should be undefined. (Null and the empty string are equivalent to undefined.) There must be exactly one root node in the input data, and no circular relationships.
stratify.path(path)
来源 · 如果指定了 path,则将路径访问器设置为给定的函数,并返回此 stratify 操作符。否则,返回当前的路径访问器,默认为 undefined。
如果设置了路径访问器,id 和 parentId 访问器将被忽略,并且会根据路径访问器返回的以斜杠分隔的字符串计算类 Unix 的层次结构,必要时推算父节点和 ID。
🌐 If a path accessor is set, the id and parentId accessors are ignored, and a unix-like hierarchy is computed on the slash-delimited strings returned by the path accessor, imputing parent nodes and ids as necessary.
例如,给定 UNIX find 命令在本地目录中的输出:
🌐 For example, given the output of the UNIX find command in the local directory:
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",
];你可以这样写:
🌐 You can say:
const root = d3.stratify().path((d) => d)(paths);