如何保证旧数据在d3的退出选择中

时间:2018-07-27 01:17:52

标签: javascript d3.js

问题:

我正在尝试了解general update pattern中d3退出选择的行为。

注意:我正在使用d3V5

Fiddle

说我想可视化数字“ 1”。

var results = [];

client.query("SELECT table_1_id AS id FROM table_1", (table_1_error, table_1_data) => {

    client.query("SELECT table_2_id AS id FROM table_2 WHERE table_1_id = " + table_1_data.rows[0].id, (table_2_error, table_2_data) => {

        table_2_data.rows.forEach(function(table_2_row) {

            client.query("SELECT table_3_id AS id FROM table_3_id WHERE table_2_id = " + table_2_row.id, (table_3_error, table_3_data) => {

                table_3_data.rows.forEach(function(table_3_row) {

                    client.query("SELECT table_4_id AS id FROM table_4_id WHERE table_3_id = " + table_3_row.id, (table_4_error, table_4_data) => {

                        results.push({"table_1_id": table_1_data.rows[0].id, "table_2_id": table_2_row.id, "table_3_id": table_3_row.id, "table_4_id": table_4_row.id});

                    });

                });

             });

        });

    });

});

//code below needs to wait until the above is complete

一切顺利。但是现在说我厌倦了“ 1”,并且对可视化“ 2”更感兴趣。

var data = [{id:"1"}];
var text = svg.selectAll('.text').data(data);

text.enter()
    .each((d) => console.log("first append " + d))
    .append('text')
    .text(d => d.id)

控制台不记录data = [{id:"2"}]; text = svg.selectAll('.text').data(data); text.exit().each((d) => console.log("remove " + d)).remove(); 。此项未放置在退出选择中。

{id:"1"}

现在我有一个“ 1”和一个“ 2”彼此堆叠。

假设:

我曾想过,当我执行text.enter() .each((d) => console.log("now append " + d)) .append('text') .text(d => d.id) 时,d3会在dom和数据之间进行区分,并将没有相应条目的所有旧dom节点放在退出选择的.data(data)中。我以为数据上的data字段可以区分这些数据元素。事实并非如此。

问题:

如何在退出选择中获得'id'

或者如何删除与{id:"1"}关联的dom节点?

1 个答案:

答案 0 :(得分:2)

这里的混乱始于错误的假设。在我见过的大多数d3示例中,数据具有以下格式:

[ {'id': 1, 'info': 'something'}, {'id': 2, 'info': 'something else'}, ...]

我一直假设 selection .data()默认使用数据的'id'字段执行差异。

事实证明并非如此,您需要提供自己的键功能。

来自D3's selection docs

  

如果未指定键功能,则将数据中的第一个数据分配给第一个选定元素,将第二个数据分配给第二个选定元素,依此类推。

所以我添加了一个关键功能:

function idFunc(d) { return d ? d.id : this.id; }

var data = [{id:"1"}];
var text = svg.selectAll('text').data(data, idFunc);

text.enter()
    .append('text')
    .text(d => d.id)

然后,不再与数据数组中的项目相对应的dom节点进入出口选择的方式,我能够将其删除。

结论:

  • (总是)在您.data(data, keyFunc)
  • 时在数据上定义键功能