简体   繁体   English

D3条形图不能正确动态更新y轴和x轴

[英]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. 我正在尝试从json数据集动态更新我的条形图。

Data look like this : 数据如下所示:

[{x=a,y=1},{x=b,y=2},{x=c,y=4}], [{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}] [{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): 我使用代码来设置画布的尺寸(y轴和x轴):

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. 在这种情况下,您必须通过将声明复制到函数范围中来重新定义xAxis和yAxis以使用在函数中定义的新比例值。

// 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. 获得轴上旧值的主要原因是因为在函数内部调用“ .call(xAxis)”时,与该轴声明关联的x比例尺是原始的。

Hope this helps.. 希望这可以帮助..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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