使用新数据更新d3图表

时间:2017-11-09 07:52:12

标签: javascript d3.js

我想用新数据更新条形图,我查看了这个问题: How to update d3.js bar chart with new data 但这对我不起作用。可能是因为我不知道在我的代码中放置exit()。remove()函数的位置。我试过把这行

svg.selectAll("rect").exit().remove();

在创建栏部分下方,但它只删除所有标签。然后,如果我在创建标签部分之后将其放置,则完全删除图表。如何获取更新按钮用新数据更改图表?

    function draw(data) {
        //Width and height
        var w = 250;
        var h = 250;

        var xScale = d3.scale.ordinal()
                        .domain(d3.range(data.length))
                        .rangeRoundBands([0, w], 0.05);

        var yScale = d3.scale.linear()
                        .domain([0, d3.max(data)])
                        .range([0, h]);

        //Create SVG element
        var svg = d3.select("#chart")
                    .append("svg")
                    .attr("width", w)
                    .attr("height", h);

        //Create bars
        svg.selectAll("rect")
           .data(data)
           .enter()
           .append("rect")
           .attr("x", function(d, i) {
                return xScale(i);
           })
           .attr("y", function(d) {
                return h - yScale(d);
           })
           .attr("width", xScale.rangeBand())
           .attr("height", function(d) {
                return yScale(d);
           })
           .attr("fill", "steelblue");

        //Create labels
        svg.selectAll("text")
           .data(data)
           .enter()
           .append("text")
           .text(function(d) {
                return d;
           })
           .attr("text-anchor", "middle")
           .attr("x", function(d, i) {
                return xScale(i) + xScale.rangeBand() / 2;
           })
           .attr("y", function(d) {
                return h - yScale(d) + 14;
           })
           .attr("font-family", "sans-serif")
           .attr("font-size", "11px")
           .attr("fill", "white");

        };

        function update() {
            var data = [ 25, 22, 18, 15, 13 ];
            draw(data);
        }

        var data = [ 21, 3, 5, 21, 15 ];

        window.onload = draw(data);

1 个答案:

答案 0 :(得分:1)

使用d3v3(我可以从您的代码中看到您使用此版本),您应该以这种方式更新图表:

update函数中设置yScale的新域名:

function update(newData) {
  yScale.domain([0, d3.max(newData)]);

之后,使用selectAll("rect").data(newData)应用新选择,在rects变量中存储选择并为适当的属性设置新值(如果您不想要动画效果,请删除.transition() .duration(300)):< / p>

var rects = d3.select("#chart svg")
  .selectAll("rect")
  .data(newData);

// enter selection
rects
  .enter().append("rect");

// update selection
rects
  .transition()
  .duration(300)
  .attr("y", function(d) {
    return h - yScale(d);
  })
  .attr("height", function(d) {
    return yScale(d);
  })

使用exit方法退出选择:

rects
  .exit().remove();

使用text执行相同的操作。我重写了你的代码,在下面隐藏的代码段中查看示例:

&#13;
&#13;
var myData = [21, 3, 5, 21, 15];
//Width and height
var w = 250;
var h = 250;
var yScale = null;

function draw(initialData) {
  var xScale = d3.scale.ordinal()
    .domain(d3.range(initialData.length))
    .rangeRoundBands([0, w], 0.05);

  yScale = d3.scale.linear()
    .domain([0, d3.max(initialData)])
    .range([0, h]);

  //Create SVG element
  var svg = d3.select("#chart")
    .append("svg")
    .attr("width", w)
    .attr("height", h);

  svg.selectAll("rect")
    .data(initialData)
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
      return xScale(i);
    })
    .attr("y", function(d) {
      return h - yScale(d);
    })
    .attr("width", xScale.rangeBand())
    .attr("height", function(d) {
      return yScale(d);
    })
    .attr("fill", "steelblue");

  svg.selectAll("text")
    .data(initialData)
    .enter()
    .append("text")
    .text(function(d) {
      return d;
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
      return xScale(i) + xScale.rangeBand() / 2;
    })
    .attr("y", function(d) {
      return h - yScale(d) + 14;
    })
    .attr("font-family", "sans-serif")
    .attr("font-size", "11px")
    .attr("fill", "white");
}


function update(newData) {
  yScale.domain([0, d3.max(newData)]);

  var rects = d3.select("#chart svg")
    .selectAll("rect")
    .data(newData);

  // enter selection
  rects
    .enter().append("rect");

  // update selection
  rects
    .transition()
    .duration(300)
    .attr("y", function(d) {
      return h - yScale(d);
    })
    .attr("height", function(d) {
      return yScale(d);
    })

  // exit selection
  rects
    .exit().remove();

  var texts = d3.select("#chart svg")
    .selectAll("text")
    .data(newData);

  // enter selection
  texts
    .enter().append("rect");

  // update selection
  texts
    .transition()
    .duration(300)
    .attr("y", function(d) {
      return h - yScale(d) + 14;
    })
    .text(function(d) {
      return d;
    })

  // exit selection
  texts
    .exit().remove();
}

window.onload = draw(myData);

setInterval(function() {
  var data = d3.range(5).map(function() {
    return parseInt(Math.random() * 20 + 1);
  });

  update(data);
}, 3000)
&#13;
<div id="chart"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
&#13;
&#13;
&#13;