jos*_*iti 187 javascript d3.js
有人可以解释D3.js中datum()和data()之间的区别吗?我看到两个都被使用了,我不确定你为什么要选择一个而不是另一个?
jos*_*iti 156
我从迈克本人那里找到了正确的答案:
如果要将数据绑定到单个SVG元素,请使用
(...).data([data])
Run Code Online (Sandbox Code Playgroud)
要么
(...).datum(data)
Run Code Online (Sandbox Code Playgroud)
如果要将数据绑定到多个SVG元素
(...).data(data).enter().append("svg")
Run Code Online (Sandbox Code Playgroud)
.....
pau*_*sm4 38
这里有一些很好的链接:
关于D3"data()"的良好讨论: 了解D3.js如何将数据绑定到节点
根据后者:
# selection.data([values[, key]])使用当前选择连接指定的数据数组.指定的值是数据值的数组,例如数字或对象的数组,或返回值数组的函数.
...
# selection.datum([value])获取或设置每个选定元素的绑定数据.与selection.data方法不同,此方法不计算连接(因此不计算进入和退出选择).
Ham*_*uey 38
在仔细研究了这个之后,我发现SO上的答案并不完整,因为它们只涉及你调用时的情况selection.data和selection.datum输入data参数.即使在那种情况下,如果选择是单个元素而不是包含多个元素,则两者的行为也不同.此外,这两种方法都可以在没有任何输入参数的情况下调用,以便查询选择中的绑定数据/数据,在这种情况下,它们再次表现不同并返回不同的东西.
编辑 - 我在这里发布了一个稍微更详细的问题答案,但下面的帖子几乎抓住了关于这两种方法的所有关键点以及它们之间的区别.
当 data作为输入参数提供时
selection.data(data)所述的元件之间将尝试执行一个数据连接data与导致产生的选择阵列enter(),exit()和update()选择,可以随后进行操作.最终结果是,如果传入数组data = [1,2,3],则尝试将每个单独的数据元素(即数据)与选择连接起来.选择的每个元素只有一个data绑定到它的基准元素.
selection.datum(data)完全绕过数据连接过程.这简单地将整个data选择中的所有元素全部分配给整个,而不像数据连接那样将其拆分.因此,如果您想将整个数组绑定data = [1, 2, 3]到您的每个DOM元素selection,那么selection.datum(data)将实现此目的.
警告:许多人认为这
selection.datum(data)相当于selection.data([data])但仅当selection包含单个元素时才会出现这种情况 .如果selection包含多个DOM元素,则将selection.datum(data)全部绑定data到选择中的每个元素.相反,selection.data([data])只将整体绑定data到第一个元素中selection.这与数据连接行为一致selection.data.
不提供data输入参数时
selection.data()将获取选择中每个元素的绑定数据,并将它们组合成一个返回的数组.所以,如果你selection包含3个带有数据的DOM元素"a","b"并"c"分别绑定到每个元素,则selection.data()返回["a", "b", "c"].重要的是要注意,如果selection是一个单独的元素(作为示例)"a"绑定到它的数据,那么selection.data()将返回["a"]而不是"a"像某些人所期望的那样.
selection.datum()只对单个选择有意义,因为它被定义为返回绑定到选择的第一个元素的基准.因此,在上面的示例中,选择由DOM元素组成,其边界数据为"a","b"并且"c",selection.datum()将简单地返回"a".
请注意,即使
selection有一个单一的元素,selection.datum()并selection.data()返回不同的值.前者返回选择的绑定数据("a"在上面的示例中),而后者返回数组中的绑定数据(["a"]在上面的示例中).
希望这有助于澄清在提供数据作为输入参数时以及在不提供任何输入参数的情况下查询绑定数据时如何selection.data以及selection.datum()彼此不同.
PS - 了解其工作原理的最佳方法是从Chrome中的空白HTML文档开始,打开控制台并尝试向文档添加一些元素,然后使用selection.data和开始绑定数据selection.datum.有时候,通过阅读而不是通过阅读来"理解"某些事情要容易得多.
我认为 HamsterHuey 给出的解释是迄今为止最好的。为了扩展它并给出差异的直观表示,我创建了一个示例文档,至少说明了data和之间的部分差异datum。
下面的答案更多的是使用这些方法得出的意见,但如果我错了,我很高兴得到纠正。
这个例子可以在下面或这个 Fiddle 中运行。
const data = [1,2,3,4,5];
const el = d3.select('#root');
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node => data: ${d}`);
const join= el
.selectAll('div.b')
.data(data);
join
.enter()
.append('div')
.classed('b', true)
.text((d, i) => `node-${i + 1} => data: ${d}`)
Run Code Online (Sandbox Code Playgroud)
我认为这datum更容易掌握,因为它不进行连接,但这当然也意味着它有不同的用例。
对我来说,一个很大的区别 - 尽管还有更多 - 这data是在 d3 图表上进行(实时)更新的自然方式,因为整个进入/更新/退出模式使它变得简单,一旦你得到它。
datum另一方面,在我看来更适合静态表示。例如,在下面的示例中,我可以在原始数组上循环并按索引访问数据获得相同的结果,如下所示:
data.map((n, i) => {
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node-${n} => data: ${d[i]}`);
});
Run Code Online (Sandbox Code Playgroud)
在这里试试:https : //jsfiddle.net/gleezer/e4m6j2d8/6/
同样,我认为这更容易掌握,因为您可以摆脱进入/更新/退出模式带来的精神负担,但是一旦您需要更新或更改选择,您肯定会更好地求助于.data().
const data = [1,2,3,4,5];
const el = d3.select('#root');
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node => data: ${d}`);
const join= el
.selectAll('div.b')
.data(data);
join
.enter()
.append('div')
.classed('b', true)
.text((d, i) => `node-${i + 1} => data: ${d}`)
Run Code Online (Sandbox Code Playgroud)
data.map((n, i) => {
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node-${n} => data: ${d[i]}`);
});
Run Code Online (Sandbox Code Playgroud)
const data = [1,2,3,4,5];
const el = d3.select('#root');
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node => data: ${d}`);
const join= el
.selectAll('div.b')
.data(data);
join
.enter()
.append('div')
.classed('b', true)
.text((d, i) => `node-${i + 1} => data: ${d}`)Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
75908 次 |
| 最近记录: |