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


75

我正在阅读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; });

我了解其中的大部分内容,但是声明的这一.data(function(d) { return d; })部分是怎么回事var td

我最好的猜测如下:

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

但是.data(function(d) { return d; })实际上是如何获取该数据的,它又返回什么呢?


3
通读本教程可能会有所帮助。
Phrogz

谢谢!我现在了解.enter()代码部分的内容。我想我可能需要等待以后的教程才能理解数据键功能的状况。
理查德

4
我希望很快写一个新的教程,其中涵盖关键功能以及层次选择(selectAll.selectAll)。
mbostock 2012年

Answers:


69

当你写:

….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__ );

您将在控制台中看到的是object {msg:"Hello",cats:42},因为它与第一个创建的q元素相关联。

如果以后再做:

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

的价值d原来是该__data__财产。(此时,您必须确保自己替换// stuff为返回新值数组的代码。)

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

  没有说明


20

理解此代码在做什么的关键是要认识到选择是DOM元素数组的数组。最外部的数组称为“选择”,内部的数组称为“组”,这些组包含DOM元素。您可以通过进入d3js.org的控制台并进行类似d3.selectAll('p')的选择来进行测试,您将看到一个包含包含'p'元素的数组的数组。

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

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

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

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


谢谢!我认为这个答案很明确,直截了当;更比其他答案(这也提供了有用的信息,没有犯罪)
电线

感谢链接Kim。足够详细,我可以理解。进一步将我推到了bost.ocks.org/mike/nest
VivekDev'1

2
虽然Phrogz的评论提供了一些很好的信息并且非常有用,但是此答案清楚地解释了所提出的确切问题。我也有同样的困惑,当我看到return d;返回节点的零件时它就单击了。困惑在于某些方法在不同的层次级别上起作用。例如attr,不像,处理单个元素data。谢谢!
Mike Williamson

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]...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.