更新嵌套数据

时间:2015-08-31 13:49:31

标签: d3.js

我试图弄清楚如何在嵌套大于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个小时之后。

1 个答案:

答案 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

当您多次进行选择和绑定数据时,选择会相互影响,并且您在选择中会得到错误的元素。