每次更新数据时,我想更新散点图的图例。将调用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”,应该将其删除。
答案 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
选择将为空。