我试图弄清楚如何在嵌套大于2级深度的D3应用程序中更新嵌套数据。让我们开始使用我的代码。
这是页面准备就绪时的jQuery处理程序。
parseLine
这是更新功能。
$(function () {
var data = createDataSet();
updateD3(data);
setTimeout(function () {
var dataAgain = createDataSet();
updateD3(dataAgain);
}, 5000);
});
这里是数据创建功能,它还记录了数据的结构。
function updateD3(data) {
var level1 = d3
.select('body')
.selectAll('div.level-1')
.data(data);
// UPDATE existing data.
level1
.text(function (d) { return d.nameLevelOne + '-'; })
.selectAll('div.level-2')
.data(function (d) { return d.valuesLevelOne; })
.text(function (d) { return d.nameLevelTwo + '-'; })
.selectAll('div.level-3')
.data(function (d) { return d.valuesLevelTwo; })
.text(function (d) { return d.nameLevelThree + ' ' + d.count + '-'; });
// CREATE new data.
level1
.enter()
.append('div')
.attr('class', 'level-1')
.text(function (d) { return d.nameLevelOne; })
.selectAll('div')
.data(function (d) { return d.valuesLevelOne; })
.enter()
.append('div')
.attr('class', 'level-2')
.text(function (d) { return d.nameLevelTwo; })
.selectAll('div')
.data(function (d) { return d.valuesLevelTwo; })
.enter()
.append('div')
.attr('class', 'level-3')
.text(function (d) { return d.nameLevelThree + ' ' + d.count; });
// REMOVE deleted data.
level1
.exit()
.selectAll('div')
.transition()
.style('opacity', 0)
.remove();
}
当我在浏览器中运行此代码时,第一个function createDataSet() {
return [
{
nameLevelOne: 'A',
valuesLevelOne: [{
nameLevelTwo: 'AA',
valuesLevelTwo: [
{
nameLevelThree: 'AAA',
count: Math.random() * 100
}
]
}]
},
{
nameLevelOne: 'B',
valuesLevelOne: [{
nameLevelTwo: 'BB',
valuesLevelTwo: [
{
nameLevelThree: 'BBB',
count: Math.random() * 100
}
]
}]
}
];
}
调用是完美的。它显示了这个:
updateD3()
当传递5秒并创建新数据集并将其传递到A
AA
AAA 24.26636815071106
B
BB
BBB 37.17236865777522
的另一个调用时,输出将更改为:
updateD3()
这不是我预期的输出。我没想到DOM的任何部分都会被销毁。从本质上讲,我预计A-
B-
和AAA
的数字会更新为新值。
为什么会这样?如何仅使用更新的数据更新DOM?
我已经查看并浏览了互联网以寻找解决方案,但几乎每个例子都是"嵌套"数据实际上只有2级深度,或者如果数据深度超过2级,则示例中没有代码演示更新数据。
非常感谢任何帮助,特别是在此之后将头撞到墙上大约6个小时之后。
答案 0 :(得分:3)
您需要在每个级别进行一次而不是多次选择,例如
var level1 = selection.data(...);
level1.enter()...
level1.exit()...
level1....
var level2 = level1.selectAll(...).data(...);
level2.enter()...
level2.exit()...
level2...
var level3 = level2.selectAll(...).data(...);
// etc
当您多次进行选择和绑定数据时,选择会相互影响,并且您在选择中会得到错误的元素。