了解 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; })实际上是如何获得这些数据的,它返回什么呢?

61106 次浏览

当你写道:

….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。)

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

no description

理解这段代码的关键是要认识到选择是 DOM 元素的 数组的数组。最外面的数组称为“选择”,内部的数组称为“组”,这些组包含 DOM 元素。您可以在 d3js.org 的控制台中进行测试,并选择 d3.selectAll (‘ p’) ,您将看到一个包含包含‘ p’元素的数组。

在您的示例中,当您第一次调用 selectAll (‘ tr’)时,您将获得一个包含所有‘ tr’元素的单个组的选择。然后将 matrix的每个元素与每个“ tr”元素匹配。

但是当您对该选择调用 selectAll (‘ td’)时,该选择已经包含一组‘ tr’元素。这一次,这些元素中的每个元素都将包含‘ td’元素的每个 成为一个团体。组只是一个数组,但是它还具有一个 ParentNode 属性,该属性引用旧的选择,在本例中是‘ tr’元素。

现在,当您对这个新选择的‘ td’元素调用 data(function(d) { return d; })时,d表示绑定到每个组的父节点的数据。因此在本例中,第一组中的‘ td 将与数组[11975,5871,8916,2868]绑定。第二组“ td”与[1951,10048,2060,6171]紧密相连。

您可以在这里阅读 Mike Bostock 自己对选择和数据绑定的出色解释: http://bost.ocks.org/mike/selection/

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

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]...