我正在尝试了解general update pattern中d3退出选择的行为。
注意:我正在使用d3V5
说我想可视化数字“ 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节点?
答案 0 :(得分:2)
这里的混乱始于错误的假设。在我见过的大多数d3示例中,数据具有以下格式:
[ {'id': 1, 'info': 'something'}, {'id': 2, 'info': 'something else'}, ...]
我一直假设 selection .data()默认使用数据的'id'
字段执行差异。
事实证明并非如此,您需要提供自己的键功能。
如果未指定键功能,则将数据中的第一个数据分配给第一个选定元素,将第二个数据分配给第二个选定元素,依此类推。
所以我添加了一个关键功能:
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)