如果在D3.js中指定数据方法第二个参数,则现有元素未定义

时间:2015-03-27 03:35:16

标签: d3.js

如果在D3.js中指定数据方法第二个参数,则现有元素未定义

<div id="hoge">
  <p>C</p>
  <p>A</p>
  <p>Z</p>  
  <p>X</p>
</div>

<script>
dataset = [4,9];
d3.select("#hoge").selectAll("p").data(dataset, function(d,i){
      console.log(d);
      return d;
   })
  .enter()
  .append("p")
  .text(function(d){
   return d;
  })


的console.log

UNDEFINED
UNDEFINED
UNDEFINED
UNDEFINED
4
9


为何不明白?
为什么不跟随?

C
A
Z
X
4
9

3 个答案:

答案 0 :(得分:1)

当我读到@Ben Lyall的答案时,我仍然不清楚(抱歉Ben,不是你,它是我......)而且我当然不清楚从阅读维基(我认为他们倒退了),所以我追查代码,看看发生了什么......

首先,值得记住的是selection是一个groups数组,而group是一个节点数组。如果有多个group,则相同的数据将绑定到所有groups

当将数据绑定到每个group时,d3在两个单独的阶段中调用 函数,首先为所有节点构建一个关联数组。 group,使用 key 函数的返回值作为键,然后使用第二个派生每个数据数组元素的键。然后使用它来查找节点数组,如果查找成功,则将数据元素绑定到其匹配节点,并将该节点添加到更新选择中。

在第一阶段,groupthis的每个节点都会调用 一次上下文设置为节点d参数是节点上的绑定数据i参数是节点的索引group。为每个节点返回的值和节点本身将添加到键值对的集合中,并将节点作为值和返回值 的功能作为键。

在第二阶段,使用{{1}为数据数组的第一维中的每个元素调用 一次} context设置为数据数组。 this参数是数据数组的元素d参数是数据数组中元素的索引。返回的值用于查找集合,如果找到匹配项,则将该节点放入更新选择中。

因此,正如@Ben Lyall所说, 功能中的i,就定义键而言,是先前绑定在节点上的数据。 (d3在节点上添加d成员)。当密钥用于限定数据元素时,__data__是数据数组元素。这就是为什么你看到四个节点d和两个数据元素的期望值的原因。

话虽如此,关键字必须是undefined的函数。

试试这个......

d

在阶段1中,d是未定义的绑定数据,因此key函数返回节点的文本。在阶段2中,d是数据值,因此返回它们。因为phase2中的所有键都不匹配phase1中的键,所以没有更新组。

只是有悖常理,你也可以把它与此混淆......

<div id="hoge">
    <p>C</p>
    <p>A</p>
    <p>Z</p>
    <p>X</p>
</div>

<script>
    dataset = [4, 9];
    d3.select("#hoge").selectAll("p").data(dataset, function (d, i) {
        d = d || this.textContent;
        console.log(d);
        return d;
    })
      .enter()
      .append("p")
      .text(function (d) {
          return d;
      })
</script>

因为 key 函数在两个阶段中返回i = 0和1的相同值,所以前2个节点被视为更新节点,因为所有数据都是根据 功能绑定,输入组为空。

但最有用的情况是你有这样的数据......

        d = d || dataset[i];

这是结果......

dataset = [4, 9, 'X', 'C']; d3.select("#hoge").selectAll("p").data(dataset, function (d, i) { d = d || this.textContent; console.log(d); return d; }).attr('class', 'update') .enter() .append("p").attr('class', 'enter') .text(function (d) { return d; })

在阶段1中,所有节点都包含在集合中,其文本内容为关键字。在阶段2中,数据值用于查找集合,并且C和X上存在匹配,因此它们位于更新集合中,并且没有匹配的数字位于输入选择中。

答案 1 :(得分:0)

因为如果为.data函数指定第二个参数,则该参数的结果将是绑定到该元素的值。没有第二个参数,数据由索引绑定。因为您正在返回d,所以它将受到值的约束。由于没有绑定到现有p元素的数据,因此它们的数据为undefined,与dataset数组中的任何值都不匹配,因此它会处理您的所有数据dataset数组作为新值,为它们创建新的占位符p元素。未定义的将在exit选择中。

有关详细说明,请参阅https://github.com/mbostock/d3/wiki/Selections#data

答案 2 :(得分:0)

您可能应该只使用 .data(dataset) 然后这会将数据绑定到前两段。剩余的两个元素应该在 .exit() 中可用,因此您可以 .remove() 它们或其他东西(可能向它们添加一些其他数据,例如默认数据)。