我使用完全相同的模型两次更新了数据(使用d3)。
在第一次更新期间,我可以看到data()。enter()包含一些元素,而data()。exit()为空。这对我来说是可以理解的。
在第二次更新(使用相同模型)期间,data()。enter()为空(如我所想),但是data()。exit()不为空,因此它在第二次更新期间删除了所有节点。这是我不明白的。
这是简化的代码(和jsfiddle;请看控制台):
// http://jsfiddle.net/24yqteo0/
// http://jsfiddle.net/6du29258/ - example with displaying some data
var model = {
smth: 'test',
rows: [
{
label: 'label1',
series: [
{
test: 'test1_1'
},
{
test: 'test1_2'
}
]
},
{
label: 'label2',
series: [
{
test: 'test2'
}
]
}
]
};
var svg = d3.select("body").append("svg");
updateData(model);
console.log('// ------------- new update');
updateData(model);
function updateData(model) {
var selection = svg.selectAll('g').data(model.rows);
console.log('selection enter size: ' + selection.enter().size());
var rows = selection.enter().append('g');
var rowData = rows.append('g').selectAll('g')
.data(function (d) {
return d.series;
});
console.log('rowdata enter size: ' + rowData.enter().size());
var seriesGroup = rowData.enter().append('g');
console.log('rowdata exit size: ' + rowData.exit().size());
rowData.exit().remove();
console.log('selection exit size: ' + selection.exit().size());
selection.exit().remove();
}
最佳答案
好吧,当您仅使用普通的g
元素用于嵌套的进入和退出时,对调试没有帮助。
我将seriesGroup
附录替换为text
,如下所示fiddle here:
var seriesGroup = rowData.enter()
.append('text')
.text(function (d) { return d.test; });
我很快在您的代码中发现了问题。它实际上是
updateData
的第一行var selection = svg.selectAll('g').data(model.rows);
此选择包括所有
g
元素,包括嵌套元素。 (console.log选择确认)为防止此行为,可以添加更精确的选择器,例如
class
var selection = svg.selectAll('g.row').data(model.rows);
然后
append
var rows = selection.enter()
.append('g')
.classed('row', true);
对于第二级类似:
var rowData = rows.append('g').selectAll('g.series')
然后
var seriesGroup = rowData.enter()
.append('g')
.classed('series', true);
Updated fiddle here。
希望这可以帮助。