d3js Nested Selections 读书笔记

select 的不同

看这个插件的html table

<table>
  <thead>
    <tr><td>  A</td><td>  B</td><td>  C</td><td>  D</td></tr>
  </thead>
  <tbody>
    <tr><td>  0</td><td>  1</td><td>  2</td><td>  3</td></tr>
    <tr><td>  4</td><td>  5</td><td>  6</td><td>  7</td></tr>
    <tr><td>  8</td><td>  9</td><td> 10</td><td> 11</td></tr>
    <tr><td> 12</td><td> 13</td><td> 14</td><td> 15</td></tr>
  </tbody>
</table>

要用 d3 选择 td,可以这样

var td = d3.selectAll("td");

如果只要 tbody 里面的 td,可以这样写

var td = d3.selectAll("tbody td");

但是这种是扁平方式的选取,因为把所有的 td 整合合并到了一个 array 里面,选取出来的元素是扁平的,不方便做一些结构性的操作.

比如我要将第一列的td变成红色,就不好弄了.

但是如果改成这样

var td = d3.selectAll("tbody tr").selectAll("td");

看似没有必要的操作:先选取tbody tr,再选取td

实际上这时得到的td就是结构化的了

td.style("color", function(d, i) { return i ? 0 : "red"; });

此时链式操作,不会像扁平的 td,index是从0-15.

  • 而是先遍历第一个tr,index 是 0-3
  • 然后又遍历第二个tr,index 又从 0-3

这时就可以利用 index,选择要将哪一列编程红色了.

这里看结果吧 http://jsbin.com/uTEfixEB/1

nesting and data

嵌套的数据选取,也要用嵌套的数据绑定

var matrix = [
  [ 0,  1,  2,  3],
  [ 4,  5,  6,  7],
  [ 8,  9, 10, 11],
  [12, 13, 14, 15],
];

var td = d3.selectAll("tbody tr")
    .data(matrix)
  .selectAll("td")
    .data(function(d) { return d; }); // d is matrix![pic](i)

data 可以接受一个array或者一个返回array的函数

最后一个 data 的函数

function(d) { return d; }

又把绑定在tr身上的array返回给 tr 进行绑定了.

Nesting and the Parent Node

如果这时要 append 会报错

d3.selectAll("table tr")
    .data(matrix)
  .enter().append("tr"); // error!

因为这时是直接选择了 tr,d3不知道 append 的 tr 要挂在 html 的哪里,自然报错了.

必须要用嵌套选取才行.

d3.select("table").selectAll("tr")
    .data(matrix)
  .enter().append("tr"); // success