了解 D3.js 如何将数据绑定到节点
Posted
技术标签:
【中文标题】了解 D3.js 如何将数据绑定到节点【英文标题】:Understanding how D3.js binds data to nodes 【发布时间】:2012-03-17 21:34:03 【问题描述】:我正在阅读 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; );
我了解大部分内容,但var td
语句的.data(function(d) return d; )
部分是怎么回事?
我的最佳猜测如下:
var tr
语句已将一个四元素数组绑定到每个 tr 节点
var td
语句然后以某种方式使用该四元素数组作为其数据
但是.data(function(d) return d; )
是如何实际获取该数据的,它返回了什么?
【问题讨论】:
通读this tutorial可能会有所帮助。 谢谢!我现在了解代码的.enter()
部分发生了什么。不过,我想我可能需要等待未来的教程才能了解数据键功能的情况。
我希望尽快写一个新教程,涵盖关键功能和分层选择(selectAll.selectAll)。
【参考方案1】:
当你写作时:
….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 元素的数据以及在较低元素上重新绑定数据子集的能力:
【讨论】:
【参考方案2】:理解这段代码在做什么的关键是要认识到选择是数组的数组 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/
【讨论】:
谢谢!我认为这个答案很清楚,直截了当;比其他答案更重要(它也提供有用的信息,没有冒犯) 感谢链接金。说的够详细了,我看懂了。进一步推动我去bost.ocks.org/mike/nest 虽然 Phrogz 的评论有一些很好的信息并且非常有用,但这个答案清楚地解释了所提出的确切问题。我也有同样的困惑,当我看到return d;
返回 parent 节点的部分时,它点击了。令人困惑的是,某些方法在不同的层级上工作。例如,attr
作用于单个元素,与 data
不同。谢谢!【参考方案3】:
使用计数器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]...
【讨论】:
以上是关于了解 D3.js 如何将数据绑定到节点的主要内容,如果未能解决你的问题,请参考以下文章