简体   繁体   English

D3:堆积的条形图exit()。remove()不删除条形

[英]D3: Stacked bar chart exit().remove() not removing bars

I have the following enter / update / exit phases defined. 我定义了以下进入/更新/退出阶段。

// this.x = my x time scale
// this.y = my y scale
// this.c = a color scale with 2 colors (red,blue)
// this.chart = D3.select() element

let series = D3.stack().keys(['point', 'topPoint'])(<any[]>this.barData);
    this.chart
      .append('g')
      .selectAll('g')
      .data(series)
      .enter().append('g')
        .attr('class', (d) => {return d.key + ' layer';})
        .attr('fill', (d) => {return this.c(d.key);})
      .selectAll('.bar')
      .data((d) => {return d;})
      .enter()
        .append('rect')
        .attr('class', 'bar');

    // Update Phase
    this.chart.selectAll('.bar').transition()
      .attr('x',    (d) => {return this.x(this._parseTime(d.data.date));})
      .attr('y',      (d) => {return this.y(d[1]); })
      .attr('height', (d) => {return this.y(d[0]) - this.y(d[1]);})
      .attr('width', 15);

    // Exit phase
    this.chart.selectAll('.point.layer').selectAll('.bar').exit().remove();
    this.chart.selectAll('.topPoint.layer').selectAll('.bar').exit().remove();

When the data changes, the new bars are drawn, but they are drawn over the old bars. 数据更改时,会绘制新的条形,但会在旧条形上绘制。

if you use d3 v4 try this: 如果您使用d3 v4,请尝试以下操作:

let series = D3.stack().keys(['point', 'topPoint'])(<any[]>this.barData);
const elements = this.chart
            .append('g')
            .selectAll('g')
            .data(series);
    elements.enter().append('g')
            .attr('class', (d) => {return d.key + ' layer';})
            .attr('fill', (d) => {return this.c(d.key);})
            .each(function(d){
                d3.select(this)
                        .append('rect')
                        .attr('class', 'bar');
            })
            .merge(elements)  // updatePhase
            .each(function(d){
                d3.select(this).select(".bar")
                    .transition()
                    .attr('x',    (d) => {return this.x(this._parseTime(d.data.date));})
                    .attr('y',      (d) => {return this.y(d[1]); })
                    .attr('height', (d) => {return this.y(d[0]) - this.y(d[1]);})
                    .attr('width', 15);
            }

    // Exit phase
    elements.exit().remove(); 

So the problem was my selecting of the elements I wish to bind and unbind. 所以问题是我要绑定和取消绑定的元素的选择。

this.chart
      .selectAll('.layer')
      .data(series)
      .enter()
        .append('g')
          .attr('class', (d) => {return d.key + ' layer';});

    // Set the enter phase for the bars within the groups, with the data derived from the layer data binding
    this.chart.selectAll('.layer')
      .selectAll('.bar')
        .data((d) => {return d;})
        .enter()
          .append('rect')
          .attr('class', 'bar');

    // Set the update phase for the layers to fill the groups with the relevant color
    let layers = this.chart.selectAll('.layer').attr('fill', (d) => {return this.c(d.key);});

    // Update Phase
    let bars;
    if(this.animate) {
      // Set the update phase of the bar data based on the data derived from the layer update phase
      bars = layers.selectAll('.bar').data((d) => {return d;}).transition();
    } else {
      bars = layers.selectAll('.bar').data((d) => {return d;});
    }

    // Set the update phase of the bar data based on the data derived from the layer update phase
    bars.attr('x',    (d) => {return this.x(this._parseTime(d.data.date));})
      .attr('y',      (d) => {return this.y(d[1]); })
      .attr('height', (d) => {return this.y(d[0]) - this.y(d[1]);})
      .attr('width', 15);

    // Exit phase
    this.chart.selectAll('.layer').data(series).exit().remove();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM