Unable to transition a D3v4 Stacked Bar Chart on data refresh

Sorvah Source

I currently have a stacked bar chart created in D3V4 based on this example here

The chart is an Ember component and works well but I am unable to add a transition affect when the data changes. Currently, when the data changes the graph redraws correctly but I have been unable to get a smooth transition between the two states.

When adding a transition() item anywhere in the chart construction it either stops rendering completely or stops redrawing the chart.

The charts is produced by three functions inside my componentjs:

didInsertElement:

   didInsertElement() {
        this.buildChart()
        this.set('didRenderChart', true);
      },

didUpdateAttrs:

  didUpdateAttrs() {
    let svg = select(this.$('svg')[0])
        .selectAll("g")
        .remove()
    this.buildChart()
  },

and buildChart (only construction code reproduced, tooltips and legends parsed out)

buildChart() {
    let data = this.get('data')

let series = stack()
      .keys(["count1", "count2", "count3"])
      .offset(stackOffsetDiverging)
      (data);

   let svg = select(this.$('svg')[0]),
      margin = {
        top: 20,
        right: 30,
        bottom: 30,
        left: 60
      },
      width = this.get("width"),
      height = this.get("height");

    let x = scaleBand()
      .domain(data.map(function(d) {
        return d.label;
      }))
      .rangeRound([margin.left, width - margin.right])
      .padding(0.1);

    let y = scaleLinear()
      .domain([min(series, stackMin), max(series, stackMax)])
      .rangeRound([height - margin.bottom, margin.top]);

    let z = scaleOrdinal().range(COLORS[this.get('color')]);

    svg.append("g")
      .selectAll("g")
      .data(series)
      .enter()
      // .merge(svg)
      .append("g")
      .attr("fill", function(d) {
        return z(d.key);
      })
      .selectAll("rect")
      .data(function(d) {
        return d;
      })
      .enter()
      .append("rect")
      .attr("width", x.bandwidth)
      .attr("x", function(d) {
        return x(d.data.label);
      })

      .attr("y", function(d) {
        return y(d[1]);
      })

      .attr("height", function(d) {
        return y(d[0]) - y(d[1]);
      })

    svg.append("g")
      .attr("transform", "translate(0," + y(0) + ")")
      .attr("class", "axisWhite")
      .call(axisBottom(x))

    svg.append("g")
      .attr("transform", "translate(" + margin.left + ",0)")
      .attr("class", "axisWhite")
      .call(axisLeft(y))


    function stackMin(h) {
      return min(h, function(d) {
        return d[0];
      });
    }

    function stackMax(h) {
      return max(h, function(d) {
        return d[1];
      });
    }

I assume the inability to transition is because the chart is not being created correctly in the first place (something to do with everything being appended to 'g') but I have been unable to work out what changes I need to make to correct this.

Note that the D3v4 functions are being imported into the component from an ember add on so do not need the d3.namespace. Unfortunately I have been unable to recreate it in JSFiddle or Ember Twiddle

javascriptd3.js

Answers

comments powered by Disqus