了解D3.js如何将数据绑定到节点

我在阅读D3.js文档,发现很难理解文档中的selection.data方法 。

这是文档中给出的示例代码:

 var matrix = [ [11975, 5871, 8916, 2868], [ 1951, 10048, 2060, 6171], [ 8010, 16145, 8090, 8045], [ 1013, 990, 940, 6907] ]; var tr = d3.select("body").append("table").selectAll("tr") .data(matrix) .enter().append("tr"); var td = tr.selectAll("td") .data(function(d) { return d; }) .enter().append("td") .text(function(d) { return d; }); 

我明白了这一点,但是var td语句的.data(function(d) { return d; })部分是怎么回事呢?

我最好的猜测如下:

  • var tr语句将一个四元素数组绑定到每个tr节点
  • 然后var td语句以某种方式使用这个四元素数组作为它的数据

但是.data(function(d) { return d; })实际上是如何获取这些数据的?

当你写:

 ….data(someArray).enter().append('foo'); 

D3创build了一堆<foo>元素,一个用于数组中的每个条目。 更重要的是,它还将数组中每个条目的数据与该DOM元素相关联,如__data__属性。

尝试这个:

 var data = [ {msg:"Hello",cats:42}, {msg:"World",cats:17} ]; d3.select("body").selectAll("q").data(data).enter().append("q"); console.log( document.querySelector('q').__data__ ); 

你会看到(在控制台中)对象{msg:"Hello",cats:42} ,因为它与第一个创build的q元素相关联。

如果你以后做:

 d3.selectAll('q').data(function(d){ // stuff }); 

d的值原来是__data__属性。 (在这一点上,你要确保你用代码返回一个新的数组值。

下面是另一个示例,显示绑定到HTML元素的数据以及重新绑定下层元素的数据子集的能力:

没有说明

理解这段代码在做什么的关键是要认识到,select是DOM元素数组的数组 。 最外层的数组称为“select”,内层数组称为“组”,这些组包含DOM元素。 你可以通过进入d3js.org的控制台进行testing,并做出如d3.selectAll('p')的select,你会看到一个数组包含一个包含'p'元素的数组。

在你的例子中,当你第一次调用selectAll('tr')时,你会得到一个包含所有'tr'元素的select。 然后matrix每个元素都与每个“tr”元素相匹配。

但是,当您在该select上调用selectAll('td')时,select已经包含一组“tr”元素。 这一次,每一个元素都将成为一组 “td”元素。 一个组只是一个数组,但它也有一个引用旧select的parentNode属性,在本例中是“tr”元素。

现在当你在这个新select的“td”元素上调用data(function(d) { return d; })时, d表示绑定到每个组的父节点的数据。 所以在这个例子中,第一组中的“td”将被绑定到数组[11975,5871,8916,2868]。 第二组“td”与[1951,10048,2060,6171]绑定。

您可以在这里阅读迈克·博斯托克自己对select和数据绑定的绝佳解释: http ://bost.ocks.org/mike/selection/

使用计数器i显示正在使用的数据的索引。

 var tr = d3.select("body").append("table").selectAll("tr") .data(matrix) .enter().append("tr") //create a row for each data entry, first index .text(function(d, i) { return i}); // show the index ie d[0][] then d[1][] etc. var td = tr.selectAll("td") .data(function(d) { return d; }) .enter().append("td") .style("background-color", "yellow") //show each cell .text(function(d,i) { return i + " " + d; }); // ie d[from the tr][0] then d[from the tr][1]...