d3js version 3 to 4 for toggling barcharts

Viewed 111

I am trying to get this old version barchart toggle to work with version 4. I'm also looking to reduce its reliance on underscore - is there a vanilla js version to handle the filtering/sorting of the data for the toggling of the legend?

enter image description here

version 3 https://jsfiddle.net/shashank2104/xhgew00y/16/

version 4 - current migration https://jsfiddle.net/q6vu27w3/2/

The current example isn't rendering though.

I've changed d3.scale.ordinal().rangeRoundBand, but the conversion may not be correct.

v3

var x0 = d3.scale.ordinal()
  .rangeRoundBands([0, width], .1);

var x1 = d3.scale.ordinal();

var y = d3.scale.linear()
  .range([height, 0]);

v4

var x0 = d3.scaleBand()
        .domain([0, width])

var x1 = d3.scaleBand();

var y = d3.scaleLinear()
    .range([height, 0]);
1 Answers

These are the changes in your code for it to work in version 4.

  1. scaleBand() works for numeric range only.For Strings range(colour), we should use d3.scaleOrdinal() instead of d3.scaleBand().

     var colorScale = d3.scaleOrdinal().range(["#f7b363", "#448875", "#c12f39", "#2b2d39", "#f8dd2f", "#8bf41b"]); 
    
  2. Next, in x0 declaration, it is not domain that you're specifying, that is range and also the rangeRoundBand() is converted to rangeRound().padding() in version 4. So x0 declaration becomes

    var x0 = d3.scaleBand()
        .rangeRound([0, width])
        .padding(0.1);
    
  3. Then barGroups variable should be changed from

    var barGroups = chartHolder.selectAll("g.bars")
    .data(data);
    

    to

    var barGroups = chartHolder.selectAll("g.bars")
            .data(data)
            .enter().append("g")
            .attr("class", "bars")
            .attr("transform", function(d) {
                return "translate(" + x0(d.label) + ",0)";
            });
    
  4. Then barEnter variable also should be changed from

    var barEnter = barGroups.selectAll("rect")
            .data(function(d) {
                return d.valores.filter(function(k) { return !k.hidden; }) ;
            });
    

    to

    var barEnter = barGroups.selectAll("rect")
            .data(function(d) {
                return d.valores.filter(function(k) { return !k.hidden; }) ;
            })
            .enter().append("rect").attr('height', 0).attr('y', height).attr('x', 0).attr('width', 0).style('fill',function(d, i) {
            return colorScale(d.name); //colores_google(i);
        });
    

    to apply animation to all appended rect elements.

If these changes are done,Then Bar chart in version 4 will work properly.

_.findWhere() can be replaced by

Array.prototype.getIndexBy = function (name, value) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][name] == value) {
            return i;
        }
    }
    return -1;
}

Then in toggleBar() function you can just do:

data.forEach(function(d) { 
   var d.filteredValores = d.valores[d.valores.getIndexBy("hidden", state)];
});

Now filteredValores property consists of valores that satisfies the given state.We can then retreive name from that filtered property.Hope this helps.

Related