我认为这更像是一个一般的 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
方法
最佳答案
data
方法接受三件事:
- 一个数组;
- 一个函数;
- 没有。
根据 API,当您使用一个函数时(在您的第一种方法中就是这种情况),该函数...
... will be evaluated for each group in order, being passed the group’s parent datum (d, which may be undefined), the group index (i), and the selection’s parent nodes (nodes), with this as the group’s parent element. (emphasis mine)
因此,此功能取决于父级的数据。这可以在 source code 中看到:
data = value.call(parent, parent && parent.__data__, j, parents)
这里是对您问题的解释:在您的第一种方法中,您的选择没有 parent 的数据。您没有多个组,这些组通常是使用 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>
另一方面,如果你有一个 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
});
<script src="https://d3js.org/d3.v5.min.js"></script>
为了完整起见,这是我制作的表格,其中包含 select
之间的差异和 selectAll
,注意“分组”:
表:select
之间的差异和 selectAll
.
关于javascript - 由 var 分隔的嵌套选择失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50599450/