D3基准与数据有何区别?

2020/10/17 00:21 · javascript ·  · 0评论

有人可以解释一下D3.js中datum()和data()之间的区别吗?我看到两者都被使用了,我不确定为什么要选择一个?

我从迈克本人那里找到了正确答案:

D3-如何处理JSON数据结构?

如果要将数据绑定到单个SVG元素,请使用

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

要么

(...).datum(data)

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

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

.....

在对此进行了仔细研究之后,我发现SO上的答案并不完整,因为它们仅涵盖调用selection.dataselection.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"分别绑定到每个DOM元素,则selection.data()返回["a", "b", "c"]重要的是要注意,如果selection是单个元素(例如)"a"绑定了基准,则selection.data()它将返回,["a"]而不是"a"某些预期的结果。

  • selection.datum()仅对单个选择有意义,因为将其定义为返回绑定到选择的第一个元素的基准因此,在上面的示例中,选择由具有"a""b"和的绑定基准的DOM元素组成"c"selection.datum()将简单地返回"a"

注意,即使selection只有一个元素,selection.datum()selection.data()返回不同的值。前者返回选择的绑定数据("a"在上面的示例中),而后者返回数组内的绑定数据(["a"]在上面的示例中)。

希望这有助于阐明如何selection.dataselection.datum()彼此不同既作为输入参数提供数据时和通过不提供任何输入参数查询结合的基准时。

PS-了解其工作原理的最佳方法是从Chrome中的空白HTML文档开始,打开控制台,尝试向该文档中添加一些元素,然后使用selection.data开始绑定数据selection.datum有时候,通过做事“读书”比读书更容易。

这里有一些很好的链接:

对于后者:

# selection.data([values[, key]])

将指定的数据数组与当前选择连接在一起。指定的值是数据值的数组,例如数字或对象的数组,或者是返回值的数组的函数。

...

# selection.datum([value])

获取或设置每个选定元素的绑定数据。与selection.data方法不同,此方法不计算联接(因此不计算输入和退出选择)。

我认为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}`)

我认为这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()

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>
本文地址:http://javascript.askforanswer.com/d3jizhunyushujuyouhequbie.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!