【问题标题】:d3 graph size not updatingd3 图形大小未更新
【发布时间】:2016-08-14 05:57:21
【问题描述】:

我正在尝试制作我从this example 修改的实时更新分组条形图。我希望图表能够随着数组大小的变化反映我的数据数组的大小,但是在我当前的代码中,d3 图表停留在数据数组的初始长度上并且不会随着数组一起增长,这将是达到一定长度时受到限制。

为什么我可以更新图表中条形的值,但不能随着数据集大小的变化而改变条形的数量?

我的代码在下面,在这个fiddle

    <html>
    <body>
    <div id="disp"></div> 
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <script>

    var main = function () {
        console.log(dataset.toString())
        var a  = { a: 'temp', b: 50+Math.floor(Math.random() * 30)}
        var b = { a: 'hum', b: 20+Math.floor(Math.random() * 20)}

        // add new elements
        dataset.push(a);    
        dataset.push(b);

       // limit to 8 elements
        if(dataset.length > 8){ 
        dataset.shift(); 
        dataset.shift();
        }
        //update graph
        update(dataset); 

    }

      // dataset below will show 6 bars animating
     // var dataset = [{ a: 'temp', b: 5},{ a: 'hum', b: 8},{ a: 'temp', b: 4},
     // { a: 'hum', b: 9},{ a: 'temp', b: 15},{ a: 'hum', b: 12}];

    var dataset = [{ a: 'temp', b: 5},{ a: 'hum', b: 8}];


    var w = 600;
    var h = 250;

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

    var rectw = 20;
    var yScale = d3.scale.linear()
            .domain([0, 80])
            .range([0, h]);

    var svg = d3.select("body")
            .append("svg")
            .attr("width", w)
            .attr("height", h);

    var bars = svg.selectAll("g")
            .data(dataset);

    barsenter = bars.enter()
            .append('g')
            .attr('class', 'bars');


    barsenter
       .append("rect")
           .attr('class', 'temp')
       .filter(function(d){ return d.a == 'temp'})
       .attr("x", function(d, i) {
            return (rectw+2)*i*2;
       })
       .attr("y", function(d) {
            return h - yScale(d.b);
       })
       .attr("width", rectw)
       .attr("height", function(d) {
            return yScale(d.b);
       })
       .attr("fill", function(d) {
            return "rgb(" + (d.b * 4) +",0, 0)";
       });

    barsenter
       .append("rect")
           .attr('class', 'hum')
       .filter(function(d){ return d.a == 'hum'})
       .attr("x", function(d, i) {
            return rectw+2+(rectw+2)*i*2;
       })
       .attr("y", function(d) {
            return h - yScale(d.b);
       })
       .attr("width", rectw)
       .attr("height", function(d) {
            return yScale(d.b);
       })
       .attr("fill", function(d) {
            return  "rgb(0, 0, " + (d.b * 5) + ")";
       });


    // update function
    var update = function(dataset) {  

    bars.select(".temp")
       .data(dataset)
           .filter(function(d){ return d.a == 'temp'})
       .transition()
       .delay(function(d, i) {
           return i / dataset.length * 1000;
       })
       .duration(500)
       .attr("y", function(d) {
            return h - yScale(d.b);
       })
       .attr("height", function(d) {
            return yScale(d.b);
       })
       .attr("fill", function(d) {
            return "rgb(" + (d.b * 4) +",0, 0)";
       });

    bars.select(".hum")
       .data(dataset)
           .filter(function(d){ return d.a == 'hum'})
       .transition()
       .delay(function(d, i) {
           return i / dataset.length * 1000;
       })
       .duration(500)
       .attr("y", function(d) {
            return h - yScale(d.b);
       })
       .attr("height", function(d) {
            return yScale(d.b);
       })
       .attr("fill", function(d) {
            return  "rgb(0, 0, " + (d.b * 5) + ")";
       });

    }


    main();
    window.setInterval(function(){ main() }, 1000);

    </script>
    </body>
    </html>

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    看了thesetwo的描述,看来理解d3的enter()和exit()函数是关键。

    我制作了这个 sn-p 来演示具有更新功能的条形图。

    //main code
    // init data
    var dataset = [];
    function fillArray(arr){
     arr.push({'value' : Math.floor(Math.random()*50)});
    }
    for (var i = 0; i < 4; i++) {
    fillArray(dataset);
    }
    
    // add 
    var btnfunc = function(){
    fillArray(dataset);
     //update graph
     update();
    }
    
    // remove 
    var btnfunc2 = function(){
     dataset.pop()
    //update graph
     update();
    }
    
    // randomize
    var btnfunc3 = function(){
    for (var i = 0; i < dataset.length; i++) { 
    dataset[i].value = Math.floor(Math.random()*50);
    }
    //update graph 
    update();
    }
    
    
    //d3 code
    //init graph
    var width = 700, height = 120;
    
    var canvas = d3.select('#disp')
        .append('svg')
        .attr('width', width)
        .attr('height', height);
    
    var x = d3.scale.linear()
            .domain([0, 10]) 
            .range([0, 700]);
    
    var h = d3.scale.linear()
            .domain([0, 110])
            .range([0, height]); 
    
    var y = d3.scale.linear()
            .domain([0, 80])
            .range([200, 0]);
    //create selection
    var bars = canvas.selectAll("rect");
    
    //update function
    function update(){
    //update selection
    bars = canvas.selectAll("rect").data(dataset);
    //append new bars      
    bars.enter().append("rect");
    //bar attributes
    bars
      .attr('width', 20)  
      .attr('height', function(d){ return h(d.value); }) 
      .attr('y', function(d){ return height - h(d.value); } )
      .attr('x', function (d, i) { return i*14*2; })
      .style('fill', 'red');
    //remove bars
    bars.exit().remove();
    
    }
    
    //1st display
    update();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <div id="disp"></div> 
    <button onclick="btnfunc()">add</button>
    <button onclick="btnfunc2()">remove</button>
    <button onclick="btnfunc3()">random</button>

    【讨论】:

      【解决方案2】:

      问题: 不会随着数据集大小的变化而改变柱的数量?

      当数据集只有两个值时,您只创建一次矩形的原因。

      barsenter
             .append("rect")
      

      在更新部分,您不是在创建,而只是使用值更新矩形。

      所以解决方法是在更新部分也执行附加操作。

      【讨论】:

      • 到目前为止我还不能让它工作,你能详细说明一下更新功能应该改变什么吗?。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      相关资源
      最近更新 更多