我认为这更像是一个普通的JS问题而不是D3特定的问题。当我在D3中研究如何进行嵌套选择时,我最初有:
var main = d3.select('#main');
main.selectAll('div')
.data(data)
.enter().append('div').classed("parent", true)
var child = main.selectAll('.parent')
.data(function(d) { return d.children }) //=> can not read property 'children' of undefined
.enter().append('div').classed("child", true)
阅读some of the selection docs后,我重构了以下内容:
const main = d3.select('#main').selectAll('div')
.data(data)
.enter().append('div').classed("parent", true)
const child = main.selectAll('.parent')
.data(function(d) { return d.children })
.enter().append('div').classed("child", true)
我工作并产生了预期的效果。我的问题是,为什么第二次调用数据时,第一种方式是在main
中对数据的引用?
编辑:我用以下方法做了一些额外的测试:
const main = d3.select('#galaxy');
main.selectAll('div').data(data);
console.log(main); //=> ut {_groups: Array(1), _parents: Array(1)}
const main2 = d3.select('#galaxy').selectAll('div').data(data);
console.log(main2); //=> ut {_groups: Array(1), _parents: Array(1), _enter: Array(1), _exit: Array(1)}
所以第一种方式似乎没有获得_enter
和_exit
方法。
答案 0 :(得分:1)
data
方法接受三件事:
根据API,当你使用一个函数时(第一种方法就是这种情况),这个函数......
...将按顺序评估每个组,传递组的父数据(d,可能是未定义的),组索引(i)和选择的父节点( nodes),将其作为组的父元素。 (强调我的)
因此,此功能取决于父母的数据。这可以在source code:
中看到data = value.call(parent, parent && parent.__data__, j, parents)
以下是您的问题的解释:在您的第一种方法中,您的选择没有父母的数据。您没有多个组,这些组通常使用selectAll
后跟另一个selectAll
创建。第一种方法中的所有内容都是select
后跟selectAll
。
让我们在一个简单的演示中展示:
var data = [{
name: "foo",
value: 10
},
{
name: "bar",
value: 17
},
{
name: "baz",
value: 42
}
];
var main = d3.select("body");
var parent = main.selectAll(null)
.data(data)
.enter()
.append('div')
.classed("parent", true)
main.selectAll('.parent')
.data(function(d) {
console.log("parent's datum is: " + JSON.stringify(d))
return 0;
});

<script src="https://d3js.org/d3.v5.min.js"></script>
&#13;
另一方面,如果您有selectAll
后跟另一个selectAll
,则您有多个群组:
var data = [{
name: "foo",
value: 10
},
{
name: "bar",
value: 17
},
{
name: "baz",
value: 42
}
];
var main = d3.select("body");
var parent = main.selectAll(null)
.data(data)
.enter()
.append('div')
parent.selectAll(null)
.data(function(d) {
console.log("parent's datum is: " + JSON.stringify(d))
return d
});
&#13;
<script src="https://d3js.org/d3.v5.min.js"></script>
&#13;
为了完整起见,这是我使用select
和selectAll
之间的差异制作的表格,请注意&#34;分组&#34;:
表格:select
与selectAll
之间的差异。
+-----------------+----------------------------------+----------------------------+
| Method | select() | selectAll() |
+-----------------+----------------------------------+----------------------------+
| Selection | selects the first element | selects all elements that |
| | that matches the selector string | match the selector string |
+-----------------+----------------------------------+----------------------------+
| Grouping | Does not affect grouping | Affects grouping |
+-----------------+----------------------------------+----------------------------+
| Data propagation| Propagates data | Doesn't propagate data |
+-----------------+----------------------------------+----------------------------+