根据我对D3中enter函数的理解,此代码运行后div的内容:

<body>
    <div>
        <p class="x"></p>
    </div>
    <script>
        d3.select('div')
            .selectAll('p')
            .data([3, 4])
            /**
             * if I uncomment this it works
             * but I don't want to call the
             * same function twice
             */
            // .text(d => d + '')
            .enter()
            .append('p')
            .text(d => d + '');
    </script>
</body>

应该:
    <div>
        <p class="x">3</p>
        <p>4</p>
    </div>

但是我得到了
    <div>
        <p class="x"></p>
        <p>4</p>
    </div>

1)我想念什么吗?根据我的理解,应将3应用于第一个p,并将4应用于后一个enter函数。

2)我也不太了解exit()。remove()的事情,据我了解,它应该删除附加的p,但这样做不那么有好处吗?

最佳答案

执行此操作时:

d3.select('div')
    .selectAll('p')

您正在选择选定div中的所有<p>元素。您只有一个div(没关系,因为select选择了它会得到的第一个div ...),并且里面只有一个 <p>元素。

然后,您绑定(bind)数据:
.data([3, 4])

因此,到目前为止,我们有:
  • 选择
  • 中的1个元素
  • 数据
  • 中的2个数据点

    现在是有关“输入”选择的重要部分:选择中已经有一个<p>元素。该<p>元素获取第一个数据3。剩余的基准将附加到新创建的p元素4

    您的“输入”选择包含所有数据点,而没有相应的元素。如您所见,由于选择中有1个元素和2个数据点,因此“输入”选择中只有1个元素。让我们展示一下(看一下控制台):

    var enterSelection = d3.select('div')
      .selectAll('p')
      .data([3, 4])
      .enter()
      .append('p')
      .text(d=>d);
    
    console.log("Elements in the enter selection: " + enterSelection.nodes().length)
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <div>
      <p class="x"></p>
    </div>


    简而言之,您必须将选择与数据进行比较:如果数据多于元素,则多余的数据将绑定(bind)到属于“输入”选择的元素。如果元素多于数据,则没有相应数据的多余元素属于“退出”选择。在您的情况下,“退出”选择为空。

    最后,如果要更新现有 <p>元素的文本,则必须使用“更新”选择:

    var p = d3.select('div')
      .selectAll('p')
      .data([3, 4]);
    
    p.enter()
      .append('p')
      .merge(p)
      .text(d => d);
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <div>
      <p class="x"></p>
    </div>

    关于d3.js - 了解enter()和exit(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43356213/

    10-12 07:37