简体   繁体   中英

D3 updating data but not axis

I am creating an interactive bar chart in D3. When a button is pressed the data changes.

Here's simplified code for the bar chart:

<svg class="cex"></svg>
<script>
var margin = {top: 20, right: 20, bottom: 60, left: 35},
    width = 650 - margin.left - margin.right,
    height =  300- margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .2);

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

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .outerTickSize(0)
    .orient("left");

  var cex = d3.select(".cex")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.csv("/input.csv", function(error, data) {
  x.domain(data.map(function(d) { return d.City; }));
  y.domain([0, d3.max(data, function(d) { return d.EatIn; })]);

  cex.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .selectAll("text")
      .attr("y", 0)
      .attr("x", 9)
      .attr("dy", ".35em")
      .attr("transform", "rotate(60)")
      .style("text-anchor", "start");;

  cex.append("g")
      .attr("class", "y axis")
      .call(yAxis);

  var bar=cex.selectAll(".bar")
    .data(data)
    .enter()
    .append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.City); })
      .attr("y", function(d) { return y(d.EatIn); })
      .attr("height", function(d) { return height - y(d.EatIn); })
      .attr("width", x.rangeBand());

});
function type(d) {
  d.EatIn = +d.EatIn;
  return d;
}

When a button is selected the following update code runs:

function EatOutData() {
        d3.csv("/input.csv", function(error, data) {
          x.domain(data.map(function(d) { return d.City; }));
          y.domain([0, d3.max(data, function(d) { return d.EatOut; })]);
        var sel = cex.selectAll("rect")
             .data(data);
        sel.exit().remove();
        sel.enter().append("rect")
          sel.attr("class", "bar")
          sel.attr("x", function(d) { return x(d.City); })
          sel.attr("y", function(d) { return y(d.EatOut); })
          sel.attr("height", function(d) { return height - y(d.EatOut); })
          sel.attr("width", x.rangeBand());

             sel.selectAll("g.y.axis")
              .call(yAxis);

            sel.selectAll("g.x.axis")
              .call(xAxis);
  function type(d) {
  d.EatOut = +d.EatOut;
  return d;
}
  }
    )};

The update changes the Y variable. So the height of the bar changes but the axis doesn't change and the scale of the two variables are quite different.

There have been a couple other SO posts on this but none seemed to fix it for me. I'm not sure why the y.domain in the update doesn't adjust them. Would really appreciate any suggestions.

You will have to remove the axis (or the text) and draw it again just like you are removing the bars and plotting them again to update data on the axis. Check the working plnkr here .

function EatOutData() {

    d3.csv("input2.csv", function(error, data) {

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


    var sel = cex.selectAll("rect")
         .data(data);
    sel.exit().remove();
    d3.select(".x.axis").remove();

    sel.enter().append("rect")
      sel.attr("class", "bar")
      sel.attr("x", function(d) { return x(d.City); })
      sel.attr("y", function(d) { return y(d.EatOut); })
      sel.attr("height", function(d) { return height - y(d.EatOut); })


      sel.attr("width", x.rangeBand());

    cex.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .selectAll("text")
    .attr("y", 0)
    .attr("x", 9)
    .attr("dy", ".35em")
    .attr("transform", "rotate(60)")
    .style("text-anchor", "start");;


         sel.selectAll("g.y.axis")
          .call(yAxis);

        sel.selectAll("g.x.axis")
          .call(xAxis);
function type(d) {
d.EatOut = +d.EatOut;
return d;
}
}
)};

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