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

时间:2012-02-28 11:59:58

标签: javascript d3.js html-table

我正在阅读D3.js文档,我发现从文档中很难理解the selection.data method

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

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; });

我理解大部分内容,但.data(function(d) { return d; })声明的var td部分发生了什么?

我最好的猜测如下:

  • var tr语句已将四元素数组绑定到每个tr节点
  • var td语句然后使用该四元素数组作为其数据,不知何故

.data(function(d) { return d; })如何实际获取该数据,以及它返回了什么?

3 个答案:

答案 0 :(得分:65)

当你写:

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

D3创建了一堆<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},因为它与第一个创建的q元素相关联。

如果你以后做:

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

d的值原来是__data__属性。 (此时,您可以确保使用返回新数组值的代码替换// stuff。)

Here's another example显示绑定到HTML元素的数据,以及在较低元素上重新绑定数据子集的能力:

no description

答案 1 :(得分:19)

理解这段代码的作用的关键是要认识到选择是 DOM元素的数组。最外面的数组称为“选择”,内部数组称为“&#39; group&#39;这些组包含DOM元素。您可以通过进入d3js.org的控制台并进行d3.selectAll(&#39; p&#39;)之类的选择来测试这一点,您将看到一个包含数组的数组,其中包含&#39; p&#39;元件。

在您的示例中,当您第一次调用selectAll(&#39; tr&#39;)时,您会选择一个包含所有&#39; tr&#39;元素。然后,matrix的每个元素都与每个元素相匹配。元件。

但是当您在该选择上调用selectAll(&#39; td&#39;)时,该选择已包含一组&#39; tr&#39;元素。这一次,每个元素都将成为成为组。元素。一个组只是一个数组,但它也有一个引用旧选择的parentNode属性,在这种情况下是&#39; tr&#39;元件。

现在,当您在这个新选择的&#39; td&#39;上致电data(function(d) { return d; })时元素d表示绑定到每个组的父节点的数据。因此,在该示例中,第一组中的&lt; td&gt;将与数组[11975,5871,8916,2868]绑定。第二组与[1951,10048,2060,6171]绑定。

您可以在此处阅读mike bostock自己对选择和数据绑定的精彩解释:http://bost.ocks.org/mike/selection/

答案 2 :(得分:1)

使用计数器 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 i.e. 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; }); // i.e d[from the tr][0] then d[from the tr][1]...