D3访问嵌套数据连接

时间:2015-06-15 16:09:42

标签: javascript d3.js

我使用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更新选择?

JSBin:http://jsbin.com/xoqaxayamu/edit?html,output

1 个答案:

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