为什么在d3 v5中不会调用exit()函数?

时间:2019-04-10 09:20:06

标签: angular d3.js

每次更新数据时,我想更新散点图的图例。将调用enter()方法,但不会调用exit()方法。现在,我仅使用两个数组,并在它们之间来回切换。

我有一个initSG(),在其中初始化全局变量。 drawSVG()函数,在其中绘制包括图例的图。还有一个updateData()方法,在这里我用新数据重绘。

legend; legendG;

initSVG(){
    this.legendG = this.svg.append('g')
      .attr('class', 'legend-g')
      .attr('transform', 'translate(' + 130 + ',0)');
}

drawSVG() {
...
    this.legend = this.legendG.selectAll('.legend')
      .data(this.color.domain())
      .enter().append('g')
...
}

updateData() {
...
    this.legend = this.legendG.selectAll('.legend')
      .data(this.color.domain())
      .enter().append('g')
        .attr('class', 'legend');

    this.legend.exit().remove(); 
... 
}

这种方式enter()起作用,但是如果我确实以这种方式更改了updateData()方法,如我在这里看到的:https://bl.ocks.org/mbostock/3808218 不是在我第一次调用updateData()方法时附加“ g”,而是在第二次附加:

updateData() {
...
    this.legend = this.legendG.selectAll('.legend')
      .data(this.color.domain());

    this.legend.exit().remove(); 

    this.legend.enter().append('g')
        .attr('class', 'legend');

... 
}

即使我省略了exit()方法。我不明白为什么会有所不同。而且它仍然没有退出“ g”,应该将其删除。

1 个答案:

答案 0 :(得分:0)

通常,没有理由拆分初始图形和重新绘制。只需1)应用数据并保存update选择,2)在选择更新时调用enter,追加新元素并设置与初始数据无关的属性,3)合并输入和更新选择(看起来像您忘记了这个),4)设置数据相关属性5)删除退出选择项。

我不知道为什么要保存legend,它应该足以作为函数局部变量。

请勿使用attr('class', 'legend'),而应使用classed('legend', true)。 Classed具有一个优点,因为它一次只能对一个类进行操作-如果您使用attr,它将覆盖所有类。与风格相同;使用style代替attr

这段代码

this.legend = this.legendG.selectAll('.legend')
  .data(this.color.domain())
  .enter().append('g')
    .attr('class', 'legend');

this.legend.exit().remove();

不起作用,因为this.legend指的是输入选择 -它不包含任何过时的元素(因为它的工作是只有新元素),因此什么也没有已移除。

这段代码

this.legend = this.legendG.selectAll('.legend')
  .data(this.color.domain());

this.legend.exit().remove(); 

this.legend.enter().append('g')
    .attr('class', 'legend');

可能不起作用,因为d3重用了相同的dom元素(默认情况下,如果未指定id,则仅使用顺序),但是您没有使用更新选择。如果新数据的长度与旧数据的长度相同,则enter选择将为空。