【问题标题】:update d3 chart with new data用新数据更新 d3 图表
【发布时间】:2017-11-09 19:26:26
【问题描述】:

我想用新数据更新条形图,我查看了这个问题: 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);

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

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

    update 函数中为yScale 设置新域:

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

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

    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 执行相同的操作。我重写了你的代码,看下面隐藏的sn-p中的例子:

    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)
    <div id="chart"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>

    【讨论】:

    • 米哈伊尔非常感谢您!感谢 Gerardo 的提示!
    猜你喜欢
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 2013-02-02
    • 2016-03-13
    • 1970-01-01
    • 2020-11-24
    • 2022-01-06
    相关资源
    最近更新 更多