d3.js D3数据与数据的区别是什么?

vfh0ocws  于 2022-11-12  发布在  其他
关注(0)|答案(5)|浏览(209)

有人能解释一下D3.js中datum()和data()之间的区别吗?我看到两者都在使用,我不知道为什么要选择其中一个?

0sgqnhkj

0sgqnhkj1#

以下是一些不错的链接:

根据后者:
# selection.data([values[, key]])
联接指定的数据数组与当前所选内容。指定的值是数据值的数组,如数字或对象的数组,或者是返回值数组的函数。
...
# selection.datum([value])
获取或设置每个选定元素的绑定数据。与selection.data方法不同,此方法不计算联接(因此不计算进入和退出选择)。

mtb9vblg

mtb9vblg2#

我认为HamsterHuey给出的解释是目前为止最好的。为了扩展它并给出差异的可视化表示,我创建了一个示例文档,至少说明了datadatum之间的部分差异。
下面的答案更多的是使用这些方法得出的一个观点,但如果我错了,我很高兴被纠正。
此示例可以在下面或in this 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}`)

我认为datum更容易理解,因为它不执行连接,但当然这也意味着它有不同的用例。
对我来说,一个很大的区别--尽管还有更多--是data只是在d3图表上进行(实时)更新的自然方式,因为一旦你得到它,整个进入/更新/退出模式使它变得简单。
另一方面,datum在我看来更适合静态表示。在下面的例子中,我可以像这样在原始数组上循环并通过索引访问数据来实现相同的结果:

data.map((n, i) => {
 el
  .append('div')
  .classed('a', true)
  .datum(data)
  .text(d => `node-${n} => data: ${d[i]}`);
});

请在此处尝试:https://jsfiddle.net/gleezer/e4m6j2d8/6/
同样,我认为这是更容易掌握的方式,因为你保持自由的精神负担来自进入/更新/退出模式,但一旦你需要更新或改变选择,你肯定会更好地诉诸.data()
第一个

yshpjwxd

yshpjwxd3#

基本上,data和datum之间的区别在于绑定的元素数量。Data用于元素列表,而datum仅指定一个元素。例如,d3.selectAll('div').data([1,2,3])表示绑定元素列表(例如,1、2、3)到三个不同的div。然后,您可以将代码与.enter().append('div')链接起来,为每个新元素创建一个新的div。另一方面,d3.select('div').datum(1)表示将元素1绑定到div元素。
你可能注意到我们也可以做d3.select(div).datum([1,2,3])这样的事情。它和d3.selectAll('div').data([1,2,3])不一样。d3.select(div).datum([1,2,3])[1,2,3]当作唯一一个绑定到div元素的元素,就像div => [1,2,3]一样。而d3.selectAll('div').data([1,2,3])[1,2,3]当作一个元素列表,这样它会把数组中的每个元素绑定到每个div元素。就像div => 1; div => 2; div => 3一样。

1u4esq0p

1u4esq0p4#

我从Mike自己那里找到了正确答案:
D3 - how to deal with JSON data structures?
如果要将数据绑定到单个SVG元素,请使用

(...).data([data])

(...).datum(data)

如果要将数据绑定到多个SVG元素

(...).data(data).enter().append("svg")

.....

xggvc2p6

xggvc2p65#

在对此进行了一些研究之后,我发现这里关于SO的答案并不完整,因为它们只涵盖了使用输入data参数调用selection.dataselection.datum的情况。即使在这种情况下,如果选择的是单个元素,与选择的是包含多个元素时,两者的行为也是不同的。此外,这两个方法也可以在没有任何输入参数的情况下被调用,以便查询选择中的绑定数据,在这种情况下,它们再次表现不同并返回不同的内容。
编辑-我发布了一个稍微更详细的回答这个问题here,但下面的帖子几乎抓住了所有的关键点,关于这两种方法,以及他们如何区别彼此。

当提供data作为输入参数时

  • selection.data(data)会尝试在data数组的元素与选取范围之间执行数据链接,结果会建立enter()exit()update()选取范围,您可以在这些选取范围上进行后续的作业。这个动作的最终结果是,如果您传入数组data = [1,2,3],尝试将每个单独的数据元素(即数据)与选择连接。选择的每个元素将仅绑定一个data的数据元素。
  • selection.datum(data)完全绕过了数据连接过程。这只是将整个data作为一个整体分配给选择中的所有元素,而不是像数据连接那样将其拆分。因此,如果你想将整个数组data = [1, 2, 3]绑定到selection中的每个DOM元素,那么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()只对单个选择有意义,因为它被定义为返回绑定到选择的第一个元素的数据。因此,在上面的示例中,选择由绑定数据为"a""b""c"的DOM元素组成,selection.datum()将简单地返回"a"

请注意,即使selection只有一个元素,selection.datum()selection.data()也会传回不同的值。前者会传回选取范围的界限数据(上例中的"a"),而后者则会传回数组内的界限数据(上例中的["a"])。
希望这有助于澄清selection.dataselection.datum()在提供数据作为输入参数时以及在通过不提供任何输入参数来查询绑定数据时的区别。
附言-最好的理解方法是在Chrome浏览器中创建一个空白的HTML文档,打开控制台,尝试在文档中添加一些元素,然后使用selection.dataselection.datum绑定数据。有时候,通过实际操作来“摸索”一些东西比通过阅读要容易得多。

相关问题