简体   繁体   中英

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); });
      }

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..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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