我使用D3渲染数据表,并成功设法使初始渲染工作:
var data = [
[1,2,3],
[1,2,3],
[1,2,3]
];
render(data);
function render(data) {
var container = d3.select('#container');
var table = container.select('table');
if (!table.node()) {
table = container.append('table')
.classed('legend', true);
}
// create the row selection
var tr = table.selectAll('tr')
.data(data);
// append 'tr' on enter
tr.enter()
.append('tr');
// create the cell selection
var td = tr.selectAll('td')
.data(function(d) { return d; });
// append on enter
td.enter()
.append('td');
// update cell text on update
td.text(function(d) {
return d;
});
}
上面的代码创建了一个表(如果没有呈现一个表(为了避免三重嵌套连接!),它会为行创建一个datajoin,然后为单元格创建一个嵌套的datajoin。
使用上面的代码,初始数据渲染就好了。
但是,如果我按如下方式更新数据:
setTimeout(function() {
for (var i = 0; i < 3; i++) {
for(var j = 0; j < 3; j++) {
data[i][j] = data[i][j] + Math.random();
}
}
render(data);
}, 500);
我希望每次调用td更新选择的最后一个语句:
td.text(function(d) {
return d;
});
不幸的是,事实并非如此!
我见过显示简单数据连接的输入/退出/更新的示例(例如http://bost.ocks.org/mike/join/),以及嵌套数据连接的示例。
但是,我没有看到演示嵌套数据连接的进入/退出/更新的示例。任何人都可以看到我的上述代码有什么问题,以及为什么在随后的'渲染'步骤中没有调用td更新选择?
答案 0 :(得分:1)
为了更多地谋杀这个比喻,你不应该在d3中像这样做一个踢踏舞... ...
var table = container.select('table');
if (!table.node()) {
table = container.append('table')
.classed('legend', true);
}
这是惯用的方法......
var data = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
render(data);
render(data);
render(data);
function render(data) {
var container = d3.select('#container');
var table = container.selectAll('table')
.data([data]);
table.enter().append("table").classed("legend", true)
table.exit().remove();
// create the row selection
var tr = table.selectAll('tr')
.data(function(d) {
return d
});
tr.exit().remove();
// append 'tr' on enter
tr.enter()
.append('tr');
// create the cell selection
var td = tr.selectAll('td')
.data(function(d) {
return d;
});
td.exit().remove();
// append on enter
td.enter()
.append('td');
// update cell text on update
td.text(function(d) {
return d3.format(" >8,.3f")(d);
});
}
setInterval(function() {
for (var i = 0; i < 3; i++) {
for(var j = 0; j < 3; j++) {
data[i][j] = data[i][j] + Math.random();
}
}
render(data);
}, 500);
body {
white-space: pre;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="container"></div>