mercredi 28 mars 2018

Receiving 'bar.transition is not a function' error in d3 animated stacked bar chart

I am trying to create a stacked bar chart in D3v4 for my Ember project that can transition and uses the General update Pattern. I using this bl.ock example as a template base

I am failing at the last hurdle by struggling to draw the bars on the graph. The axis are fine and render correctly. When I try to draw the bars I get an error in the console to say that bars.transition is not a function.

The bars method is being imported correctly and if I comment out the transition and just try to draw the bars straight on, I receive a new error that bars.enter is not a function. I am guessing this is because somewhere I am referencing something incorrectly.

Any help greatly appreciated.

Chart code:

buildChart(){
let data = this.get('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 color = scaleOrdinal(["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f"]);
let y = scaleLinear()
        .rangeRound([height - margin.bottom, margin.top]);

var x_axis = axisBottom(x);
var y_axis = axisLeft(y)
svg.append("g")
            .attr("transform", "translate(0," + y(0) + ")")
            .attr("class", "axisWhite")
            .call(x_axis)

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

let columnKeys = ["count1", "count2", "count3"]

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

function stackMin(h) {
            return min(h, function(d) {
              return d[0];
            });
          }
function stackMax(h) {
            return max(h, function(d) {
              return d[1];
            });
          }
          var x_var = "label";

redraw(data)

function redraw(data) {
 //update Y scale
 y.domain([min(stacks, stackMin), max(stacks, stackMax)])

 svg.select(".y")
        .transition()
          .call(customYAxis);

          // each data column (a.k.a "key" or "series") needs to be iterated over
          // the variable columnKeys represents the unique keys of the stacks
          columnKeys.forEach(function(key, key_index){

            var bar = svg.selectAll(".bar" + key)
                        .data(stack(data)[key_index], function(d){ return d.data.label + "-" + key; });
                    bar
                      .transition()
                        .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]); });

                    bar.enter().append("rect")
                        .attr("class", function(d){ return "bar bar-" + key; })
                        .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]); })
                        .attr("width", x.bandwidth())
                        .attr("fill", function(d){ return color(key); })

                  });
}

function customYAxis(g) {
      g.call(y_axis);
      g.selectAll(".tick:not(:first-of-type) line").attr("stroke", "#777").attr("stroke-dasharray", "2,2");
      g.selectAll(".tick text").attr("x", 4).attr("dy", -4);
    }

}

Unfortunately I'm unable to set up a fiddle or a twiddle. I've never been able to set Ember components up in them correctly.

I import the D3 functions from the ember-d3 add on




Aucun commentaire:

Enregistrer un commentaire