enter() 和 exit() 如何检测 D3 中的更新数据?

How are enter() and exit() detecting updated data in D3?

我正在构建一个小型 UI,用户必须在其中 select 显示的两个 SVG 中的每一个上的一个点。

然后这些点坐标显示在 SVG 下方。我想通过 enter()exit() 方法使用 D3 的数据绑定来实现这一点。然而,即使我在绑定元素上调用 enter() 方法,D3 似乎并不总是更新我显示点坐标的部分。删除数据时,exit() 方法仍然有效。

这是主要代码:

function showPoints() {
  var coordinatesElements = d3.select('#coordinates').selectAll('.point').data(points);
  coordinatesElements.enter().append('div').classed('point', true)
    .text(function (d) {
      var textParts = [];
      if (d.firstSvg) { textParts.push('first : '+JSON.stringify(d.firstSvg)); }
      if (d.secondSvg) { textParts.push('second : '+JSON.stringify(d.secondSvg)); }
      return textParts.join(' - ');
    })
    .append("span")
    .classed('removeCalibrationPoint', true)
    .html(" X")
    .on('click', function(d, i) {
      points.splice(i, 1);
      showPoints();
    });

  coordinatesElements.exit().remove();
}

我创建了一个 JSBin fiddle 来演示问题。

第一个问题是您的 HTML 中有一个空的 div of class point。这将由 .selectAll('.point') 选择并导致数据中的第一个元素不显示。

第二个问题是您没有处理更新选择——在某些情况下,您没有添加新数据,而是修改现有数据。以下代码更新更新选择中数据的文本。

coordinatesElements.text(function (d) {
  var textParts = [];
  if (d.firstSvg) { textParts.push('first : '+JSON.stringify(d.firstSvg)); }
  if (d.secondSvg) { textParts.push('second : '+JSON.stringify(d.secondSvg)); }
  return textParts.join(' - ');
});

完成演示 here。请注意,我通过仅在更新选择中设置文本来稍微简化了代码——从输入选择中添加的元素合并到更新选择中,因此无需执行两次。