d3 在数据更新时错误地附加了 dom 个元素

d3 wrongly append dom elements on data update

我正在尝试使用 d3 和他的 enter/exit 模式来更新我的条形图 在这里你可以看到当前的结果 http://jsfiddle.net/k8sftbez/

我的想法是我应该有一个 g 元素,每个数据对象属性都有一个矩形和一个文本,例如:

<g>
  <rect></rect>
  <text></text>
</g>

图表是按方面创建的,但我的问题是当我尝试更新条形颜色(我在鼠标悬停时执行),而不是更新当前矩形和文本标签,它在每次更新时附加 2 个新标签。 在示例中,您可以看到问题 (http://jsfiddle.net/k8sftbez/)

这是因为您的更新函数实际上还包括条形图的创建,为了让它们只改变颜色,您应该有两个独立的函数,一个用于添加对象,一个用于更新(例如,你可以有一个附加没有任何属性的矩形的函数和为它们设置样式的更新函数)

最后,我修改了更新函数,如下所示: http://jsfiddle.net/5ft6uL6k/

我认为是更优雅的方式,使用占位符并更新它们。

基本上是这部分:

var bar = chart.selectAll("g").data(data)
bar.enter().append("g").attr("transform", function(d, i) {
  return "translate(0," + i * barHeight + ")";
})

var valueBar = bar.append("rect");
valueBar
  .attr(valueBarValues.attr)
  .attr("width", function(d){return x(d.value)})
  .style(valueBarValues.style);

bar.append("text")
  .attr(textConfig.attrs)
  .style(textConfig.style)
  .text(function(d) { return d.name; })

bar.exit().remove();

改成这样:

    var bar = chart.selectAll("g").data(data)
    var barEnter = bar.enter().append("g");

    barEnter.attr("transform", function(d, i) {
        return "translate(0," + i * barHeight + ")";
    });

    barEnter.append("rect");
    barEnter.append("text");

    var textBar = bar.selectAll("text")
    textBar
        .attr(textConfig.attrs)
        .style(textConfig.style)
        .text(function(d) { return d.name; })

    var valueBar = bar.selectAll("rect");
    valueBar
    .attr(valueBarValues.attr)
    .attr("width", function(d){return x(d.value)})
    .style(valueBarValues.style);

  bar.exit().remove();