Javascript D3 数据与数据有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13728402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference D3 datum vs. data?
提问by josephmisiti
Can someone please explain the difference between datum() and data() in D3.js? I see both being used and I am not sure why you should choose one over the other?
有人可以解释 D3.js 中 datum() 和 data() 之间的区别吗?我看到两者都在使用,但我不确定为什么你应该选择一个而不是另一个?
采纳答案by josephmisiti
I found the correct answer here from Mike himself:
我从迈克本人那里找到了正确的答案:
D3 - how to deal with JSON data structures?
If you want to bind your data to a single SVG element, use
如果要将数据绑定到单个 SVG 元素,请使用
(...).data([data])
or
或者
(...).datum(data)
If you want to bind your data to multiple SVG elements
如果要将数据绑定到多个 SVG 元素
(...).data(data).enter().append("svg")
.....
.....
回答by HamsterHuey
After having looked into this a bit, I've found that the answers here on SO are not complete as they only cover the case when you invoke selection.dataand selection.datumwith an input dataparameter. Even in that scenario, the two behave differently if the selection is a single element versus when it contains multiple elements. Moreover, both of these methods can also be invoked without any input arguments in order to query the bound data/datum in the selection, in which case they once again behave differently and return different things.
在稍微研究了一下之后,我发现 SO 上的答案并不完整,因为它们仅涵盖您调用selection.data并selection.datum使用输入data参数时的情况。即使在这种情况下,如果选择是单个元素与包含多个元素时,两者的行为也会有所不同。此外,这两种方法也可以在没有任何输入参数的情况下调用,以查询选择中的绑定数据/数据,在这种情况下,它们再次表现不同并返回不同的东西。
Edit - I posted a slightly more detailed answer to this question here, but the post below pretty much captures all the key points regarding the two methods and how they differ from each other.
编辑 - 我在这里发布了一个更详细的答案,但下面的帖子几乎涵盖了关于这两种方法的所有关键点以及它们之间的区别。
When supplyingdataas an input argument
当data作为输入参数提供时
selection.data(data)will attempt to perform a data-join between the elements of thedataarray with the selection resulting in the creation ofenter(),exit()andupdate()selections that you can subsequently operate on. The end result of this is if you pass in an arraydata = [1,2,3], an attempt is made to join each individual data element (i.e. datum) with the selection. Each element of the selection will only have a single datum element ofdatabound to it.selection.datum(data)bypasses the data-join process altogether. This simply assigns the entirety ofdatato all elements in the selection as a whole without splitting it up as in the case of data-joins. So if you want to bind an entire arraydata = [1, 2, 3]to every DOM element in yourselection, thenselection.datum(data)will achieve this.
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)将实现这一点。
Warning:Many people believe that
selection.datum(data)is equivalent toselection.data([data])but this is only true ifselectioncontains a single element. Ifselectioncontains multiple DOM elements, thenselection.datum(data)will bind the entirety ofdatato every single element in the selection. In contrast,selection.data([data])only binds the entirety ofdatato the first element inselection. This is consistent with the data-join behavior ofselection.data.
警告:许多人认为这
selection.datum(data)等价于,selection.data([data])但这仅在selection包含单个元素时才成立 。如果selection包含多个 DOM 元素,则将selection.datum(data)整体绑定data到选择中的每个单个元素。相比之下,selection.data([data])只将 的全部绑定data到 中的第一个元素selection。这与 的数据连接行为一致selection.data。
When supplying no datainput argument
不提供data输入参数时
selection.data()will take the bound datum for each element in the selection and combine them into an array that is returned. So, if yourselectionincludes 3 DOM elements with the data"a","b"and"c"bound to each respectively,selection.data()returns["a", "b", "c"]. It is important to note that ifselectionis a single element with (by way of example) the datum"a"bound to it, thenselection.data()will return["a"]and not"a"as some may expect.selection.datum()only makes sense for a single selection as it is defined as returning the datum bound to the first elementof the selection. So in the example above with the selection consisting of DOM elements with bound datum of"a","b"and"c",selection.datum()would simply return"a".
selection.data()将获取选择中每个元素的绑定数据并将它们组合成一个返回的数组。因此,如果您selection在 data 中包含 3 个 DOM 元素"a","b"并"c"分别绑定到每个元素,则selection.data()返回["a", "b", "c"]. 重要的是要注意,如果selection是单个元素(例如)"a"绑定到它的数据,selection.data()则将返回,["a"]而不是"a"像某些人预期的那样。selection.datum()仅对单个选择有意义,因为它被定义为返回绑定到选择第一个元素的数据。因此,在上面的示例中,选择由绑定数据为"a"、"b"和的 DOM 元素组成"c",selection.datum()将简单地返回"a"。
Note that even if
selectionhas a single element,selection.datum()andselection.data()return different values. The former returns the bound datum for the selection ("a"in the example above) whereas the latter returns the bound datum within an array (["a"]in the example above).
注意即使
selection有单个元素,selection.datum()也selection.data()返回不同的值。前者返回选择的绑定数据("a"在上面的例子中),而后者返回数组中的绑定数据(["a"]在上面的例子中)。
Hopefully this helps clarify how selection.dataand selection.datum()differ from each other both when providing data as an input argument and when querying for the bound datum by not providing any input arguments.
希望这有助于阐明如何selection.data与selection.datum()彼此不同既作为输入参数提供数据时和通过不提供任何输入参数查询结合的基准时。
PS - The best way to understand how this works is to start with a blank HTML document in Chrome and to open up the console and try adding a few elements to the document and then start binding data using selection.dataand selection.datum. Sometimes, it's a lot easier to "grok" something by doing than by reading.
PS - 了解其工作原理的最佳方法是从 Chrome 中的空白 HTML 文档开始,然后打开控制台并尝试向文档中添加一些元素,然后使用selection.data和开始绑定数据selection.datum。有时,通过做来“理解”某事比通过阅读容易得多。
回答by paulsm4
Here are some good links:
这里有一些很好的链接:
Good discussion on D3 "data()": Understanding how D3.js binds data to nodes
关于 D3 "data()" 的好讨论: 了解 D3.js 如何将数据绑定到节点
Per the latter:
根据后者:
# selection.data([values[, key]])Joins the specified array of data with the current selection. The specified values is an array of data values, such as an array of numbers or objects, or a function that returns an array of values.
...
# selection.datum([value])Gets or sets the bound data for each selected element. Unlike the selection.data method, this method does not compute a join (and thus does not compute enter and exit selections).
# selection.data([values[, key]])将指定的数据数组与当前选择连接。指定的值是数据值数组,例如数字或对象数组,或返回值数组的函数。
...
# selection.datum([value])获取或设置每个选定元素的绑定数据。与 selection.data 方法不同,此方法不计算连接(因此不计算进入和退出选择)。
回答by Nobita
I think the explanation given by HamsterHuey is the best so far.
To expand on it and give a visual representation of the differences I created a sample document that illustrates at least part of the differences between dataand datum.
我认为 HamsterHuey 给出的解释是迄今为止最好的。为了扩展它并给出差异的直观表示,我创建了一个示例文档,至少说明了data和之间的部分差异datum。
The below answer is more of an opinion derived from using these methods, but I am happy to be corrected if I'm wrong.
下面的答案更多的是使用这些方法得出的意见,但如果我错了,我很高兴得到纠正。
This example can be run below or in this Fiddle.
这个例子可以在下面或这个 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}`)
I think that datumis simpler to grasp since it doesn't do a join, but of course this also mean it has different use cases.
我认为这datum更容易掌握,因为它不进行连接,但这当然也意味着它有不同的用例。
To me one big difference - although there are more - is the fact that datais just the natural way of doing (live) updates on a d3 chart, as the whole enter/update/exit pattern makes it simple, once you get it.
对我来说,一个很大的区别 - 尽管还有更多 - 这data是在 d3 图表上进行(实时)更新的自然方式,因为整个进入/更新/退出模式使它变得简单,一旦你得到它。
datumon the other hand seems to me to be more suited for static representations. In the example below for example I could achieve the same result my looping on the original array and accessing the data by index like so:
datum另一方面,在我看来更适合静态表示。例如,在下面的示例中,我可以在原始数组上循环并按索引访问数据获得相同的结果,如下所示:
data.map((n, i) => {
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node-${n} => data: ${d[i]}`);
});
Try it here: https://jsfiddle.net/gleezer/e4m6j2d8/6/
在这里试试:https: //jsfiddle.net/gleezer/e4m6j2d8/6/
Again, I think this is way easier to grasp as you keep free from the mental burden coming from the enter/update/exit pattern, but as soon you need to update or change the selection you will surely be better off resorting to .data().
同样,我认为这更容易掌握,因为您可以摆脱进入/更新/退出模式带来的精神负担,但是一旦您需要更新或更改选择,您肯定会更好地求助于.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}`)
/* Ignore all the css */
html {
font-family: arial;
}
.l {
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
margin: 10px 0;
}
.l-a {
background: #cf58e4;
}
.l-b {
background: #42e4e4;
}
.a {
border-bottom: 2px solid #cf58e4;
}
.b {
border-bottom: 2px solid #42e4e4;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.6.0/d3.min.js"></script>
<div style="margin-bottom: 20px;">
<span class="l l-a"></span> .datum() <br />
<span class="l l-b"></span> .data()
</div>
<div id="root"></div>

