Published
Edited
May 27, 2020
Insert cell
Insert cell
familyChart = graph(family, {label: d =>d.data.name})
Insert cell
family = d3.hierarchy(
{
name: "root",
children:[
{name: "child #1"},
{
name: "child #2",
children:[
{name: "grandchildren #1"},
{name: "grandchildren #1"},
{name: "grandchildren #1"}
]
}
]
}
)
Insert cell
md`这个约定与 DOM 模型([*element*.children](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/children))相匹配,因此您可以将一个DOM元素传递给d3。等级制度,这是一个巧妙的技巧。这是上面的family tree DOM 对象的可视化。`
Insert cell
graph(d3.hierarchy(familyChart), {label: d=>d.data.tagName})
Insert cell
d3.hierarchy(familyChart)
Insert cell
Insert cell
graph(arrays, ({label: d => d.children ? "": d.data}))
Insert cell
arrays = d3.hierarchy([
[
"leaf #1",
[
"leaf #2",
"leaf #3",
"leaf #4"
]
]
], d => Array.isArray(d) ? d : undefined)
Insert cell
md`下面是另外一个递归地拆分字符串的有趣案例`
Insert cell
graph(parsed, {marginLeft: 200, label: d => d.data})
Insert cell
parsed = d3.hierarchy(
"This is not proper parsing. But certainly fun!",
id => {
for (const split of [/[^\w\s]/, /\s/]) {
const children = id && id.split(split).filter(id => id.length > 0);
if (children.length > 1) return children;
}
}
)
Insert cell
Insert cell
ch = id => {
for (const split of [/[^\w\s]/, /\s/]) {
const children = id.split(split).filter(id => id.length > 0);
if (children.length > 1) return children;
}
}
Insert cell
ch("This is not proper parsing. But certainly fun!")
Insert cell
ch("This is not proper parsing")
Insert cell
ch('This')
Insert cell
md`
如果您有表格数据,例如来自逗号分隔值(CSV)的数据,您可以使用 [d3.stratify](/@d3/d3-stratify) 将其排列成一个层次结构。每个输入对象d表示树中的一个节点,并且必须具有唯一标识符和父标识符(默认情况下为d.id和d.parentId分别)。
`
Insert cell
graph(chaos)
Insert cell
chaos = d3.stratify()([
{id: "Chaos"},
{id: "Gaia", parentId: "Chaos"},
{id: "Eros", parentId: "Chaos"},
{id: "Erubus", parentId: "Chaos"},
{id: "Mountains", parentId: "Chaos"},
{id: "Pontus", parentId: "Gaia"},
{id: "Uranus", parentId: "Gaia"}
])
Insert cell
Insert cell
chaos instanceof d3.hierarchy
Insert cell
Insert cell
chaos.data
Insert cell
Insert cell
graph(chaos, {label: d => `depth ${d.depth}`})
Insert cell
Insert cell
gaia = chaos.children[0]
Insert cell
pontus = chaos.children[0].children[1]
Insert cell
tartarus = chaos.children[3]
Insert cell
Insert cell
tartarus.children
Insert cell
Insert cell
Insert cell
{
const highlight = new Set(gaia.ancestors());
return graph(chaos, {highlight: d => highlight.has(d)})
}
Insert cell
gaia.ancestors()
Insert cell
{
const highlight = new Set(gaia.descendants());
return graph(chaos, {highlight: d => highlight.has(d)})
}
Insert cell
pontus.ancestors()
Insert cell
{
const highlight = new Set(gaia.descendants());
return graph(chaos, {highlight: d => highlight.has(d)});
}
Insert cell
gaia.descendants()
Insert cell
{
const highlight = new Set(gaia.leaves());
return graph(chaos, {highlight: d => highlight.has(d)});
}
Insert cell
gaia.leaves()
Insert cell
{
const highlight = new Set(tartarus.path(pontus));
return graph(chaos, {highlight: d => highlight.has(d)});
}
Insert cell
tartarus.path(pontus)
Insert cell
gaia.links()
Insert cell
graph(gaia.copy())
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
gaia.copy()
Insert cell
md`---
## 附录

感谢 [@clhenrick](/@clhenrick) 对文章的校验。`
Insert cell
d3 = require("d3@5", "d3-array@2")
Insert cell
dx = 12
Insert cell
dy = 120
Insert cell
tree = d3.tree().nodeSize([dx, dy])
Insert cell
Insert cell
Insert cell
// 原作者:https://observablehq.com/@fil
// 翻译:https://observablehq.com/@aptx4869yuyang2017
// 版权声明:自由转载-保持署名-相同方式共享 (CC-BY-SA-4.0)
// https://creativecommons.org/licenses/by-sa/4.0/
LICENSE = "cc-by-sa-4.0"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more