Lez
Lez

Reputation: 161

D3 bar chart does not dynamically update y-axis and x-axis properly

I am trying to dynamically update my bar chart from a json data set.

Data look like this :

[{x=a,y=1},{x=b,y=2},{x=c,y=4}],
[{x=d,y=0.1},{x=a,y=1}],{x=b,y=4}]

I used the code to set the dimensions of the canvas (y-axis and x-axis):

var margin = {top: 20, right: 20, bottom: 70, left: 40},
    width = 600 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;

The whole code :

    // set the ranges
    var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);

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

    // define the axis
    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom")


    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")
        .ticks(10);


    // add the SVG element
    var chart = d3.select(".chart")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", 
              "translate(" + margin.left + "," + margin.top + ")");






    // load the data
        data=mydata

        data.forEach(function(d) {
            d.x = d.x;
            d.y = +d.y;
        });

      // scale the range of the data
      x.domain(data.map(function(d) { return d.x; }));
      y.domain([0, d3.max(data, function(d) { return d.y; })]);

      // add axis
      chart.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis)
        .selectAll("text")
          .style("text-anchor", "end")
          .attr("dx", "-.8em")
          .attr("dy", "-.55em")
          .attr("transform", "rotate(-90)" );

      chart.append("g")
          .attr("class", "y axis")
          .call(yAxis)
        .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 5)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Frequency");


      // Add bar chart
      chart.selectAll("bar")
          .data(data)
        .enter().append("rect")
          .attr("class", "bar")
          .attr("x", function(d) { return x(d.x); })
          .attr("width", x.rangeBand())
          .attr("y", function(d) { return y(d.y); })
          .attr("height", function(d) { return height - y(d.y); });


     //Call function to update barchart
      function redraw(data){


          x.domain(data.map(function(d) { return d.x; }));
          y.domain([0, d3.max(data, function(d) { return d.y; })]);

          chart.select(".x.axis").remove();
        chart.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis)
        .selectAll("text")
          .style("text-anchor", "end")
          .attr("dx", "-.8em")
          .attr("dy", "-.55em")
          .attr("transform", "rotate(-90)" );



            // y-axis
            chart.select(".y.axis").remove();
            chart.append("g")
                  .attr("class", "y axis")
                  .call(yAxis)
              .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("Frequency");





            var bar = chart.selectAll(".bar")
                    .data(data, function(d) { 

                        return d.x; });

            // new data:
            bar.enter().append("rect")
               .attr("class", "bar")
               .attr("x", function(d) { return x(d.x); })
               .attr("y", function(d) { return y(d.y); })
               .attr("height", function(d) { return height - y(d.y); })
               .attr("width", x.rangeBand());


            // removed data:
           // bar.exit().remove();
            chart.select(".y.axis").transition().delay(750).call(yAxis)

            // updated data:
            bar
               .transition()
               .duration(750)
                   .attr("y", function(d) { return y(d.y); })
                   .attr("height", function(d) { return height - y(d.y); });
      }

Upvotes: 1

Views: 1866

Answers (1)

Alex
Alex

Reputation: 66

In this case you will have to redefine the xAxis and yAxis to use the new scale values you define in the function, by pretty much copying the declaration into the function scope.

// define the axis
var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")


var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(10);

The primary reason you're getting the old values on the axis is because when you call ".call(xAxis)" inside the function the x scale associated with that axis declaration is the original one.

Hope this helps..

Upvotes: 2

Related Questions