2015-11-22 4 views
0

Я столкнулся с этой проблемой, когда я, хотя у меня был d3 undercontrol ... Я не могу узнать, почему мой код сбой, когда я обновляю свой barChart с помощью пустого массива данных ...Ошибка обновления моего barchart с помощью d3

вот мой код:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Simple tables in D3</title> 
    <meta charset="utf-8"> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> 
    <style type="text/css"> 

     .chart rect { 
      fill: steelblue; 
     } 

     .axis path, 
     .axis line { 
      fill: none; 
      stroke: #000; 
      shape-rendering: crispEdges; 
     } 

     .x.axis path { 
      display: none; 
     } 

     .axis { 
      font: 10px sans-serif; 
     } 

    </style> 
</head> 
<body> 

    <svg class="chart"> 
    </svg> 

    <script> 
     var scanCounters = JSON.parse("[{\"scan\":\"111\",\"repetition\":3},{\"scan\":\"222\",\"repetition\":2},{\"scan\":\"333\",\"repetition\":4},{\"scan\":\"123\",\"repetition\":2},{\"scan\":\"456\",\"repetition\":1},{\"scan\":\"789\",\"repetition\":1}]"); 

     var scanCounters2 = JSON.parse("[{\"scan\":\"111\",\"repetition\":8},{\"scan\":\"222\",\"repetition\":6},{\"scan\":\"333\",\"repetition\":5},{\"scan\":\"123\",\"repetition\":3}]"); 

     var scanCounters3 = JSON.parse("[]"); 

     var columns = ["scan", "repetition"]; 

     var margin = {top: 20, right: 30, bottom: 30, left: 40}; 

     var width = 960; 
     var height = 500; 

     var innerWidth = width - margin.left - margin.right; 
     var innerHeight = height - margin.top - margin.bottom; 

     var bcScan = barChart(600, 400, "chart"); 
     bcScan.update(scanCounters); 

     setTimeout(function(){ 
      bcScan.update(scanCounters2); 
      }, 1000); 

     setTimeout(function(){ 
      bcScan.update(scanCounters3); 
      }, 2000); 

    function barChart(w, h, node) { 

     var bC = {}; 

     var margin = {top: 20, right: 20, bottom: 30, left: 40}, 
       width = w - margin.left - margin.right, 
       height = h - margin.top - margin.bottom; 

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

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

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

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

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

     svg.append("g") 
       .attr("class", "x axis") 
       .attr("transform", "translate(0," + height + ")"); 

     svg.append("g") 
       .attr("class", "y axis") 
       .append("text") 
       .attr("transform", "rotate(-90)") 
       .attr("y", -40) 
       .attr("dy", ".71em") 
       .style("text-anchor", "end") 
       .text("Frequency"); 

     bC.update = function(data) { 

      x.domain(data.map(function (d) { 
       return d[Object.keys(d)[0]]; 
      })); 
      y.domain([0, d3.max(data, function (d) { 
       return d[Object.keys(d)[1]]; 
      })]); 

      svg.select(".x.axis") 
        .transition() 
        .duration(300).call(xAxis) 
        .selectAll("text") 
        .style("text-anchor", "end") 
        .attr("dx", "-.8em") 
        .attr("dy", ".15em") 
        .attr("transform", "rotate(-65)"); 

      svg.select(".y.axis") 
        .transition() 
        .duration(300) 
        .call(yAxis); 

      var bars = svg.selectAll(".bar").data(data, function (d) { 
       return d[Object.keys(d)[0]]; 
      }); 

      bars.exit() 
        .transition() 
        .duration(300) 
        .attr("y", y(0)) 
        .attr("height", height - y(0)) 
        .style('fill-opacity', 1e-6) 
        .remove(); 

      bars.enter() 
        .append("rect") 
        .attr("class", "bar") 
        .attr("y", y(0)) 
        .attr("height", height - y(0)); 

      var trans = bars.transition().duration(300).attr("x", function (d) { 
       return x(d[Object.keys(d)[0]]); 
      }); 

      trans.attr("width", x.rangeBand()) 
        .attr("y", function (d) { 
         return y(d[Object.keys(d)[1]]); 
        }) 
        .attr("height", function (d) { 
         return height - y(d[Object.keys(d)[1]]); 
        }); 

     }; 

     return bC; 
    } 

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

проблема заключается в том, когда я звоню bcScan.update(scanCounters3); где scanCounters3 является пустым массивом.

Это сообщение об ошибке:

Error: Invalid value for attribute height="NaN"

Error: Invalid value for attribute y="NaN"

Queston: Может кто-то помочь мне понять, почему это происходит сбой?

благодаря

+3

Я предполагаю, что проблема в том, что если нет данных, ваш домен y будет пуст? Поместите проверку в начале вашей функции обновления. Если данные пустые, просто залог? –

ответ

1

@EthanJewett, является правильным, если вы посмотрите на y.domain() на каждой итерации вы получите:

[0, 4] 
[0, 8] 
[0, NaN] 

Так на последней итерации, ваш выход переход делает математику на NaN:

.attr("y", y(0)) 
.attr("height", height - y(0)) 

Я бы просто отбросить эти линии в целом и сделать переход выхода:

 bars.exit() 
     .transition() 
     .duration(300) 
     .style('fill-opacity', 1e-6) 
     .remove(); 
Смежные вопросы