2014-09-11 34 views
0

我試圖用從CSV加載的數據來構建基本的響應式條形圖。我的圖表沒有讀取CSV並給我NaNs。 Here's a screenshot of what my chart looks like.這裏是我當前的代碼:D3條形圖不解析csv

<script type="text/javascript"> 
var url = "data/data.csv", 
    margin = {top: 30, right: 10, bottom: 30, left: 10}, 
    width = parseInt(d3.select('#chart').style('width'), 10), 
    width = width - margin.left - margin.right, 
    height = 200, // placeholder 
    barHeight = 20, 
    spacing = 5, 
    total = d3.format('n'); 

// scales and axes 
var x = d3.scale.linear() 
    .range([0, width]) 
    .domain([0, 4000]); // hard-coding this because I know the data 

var y = d3.scale.ordinal(); 

var xAxis = d3.svg.axis() 
    .scale(x) 
    .ticks(3); 

// create the chart 
var chart = d3.select('#chart').append('svg') 
    .style('width', (width + margin.left + margin.right) + 'px') 
    .append('g') 
    .attr('transform', 'translate(' + [margin.left, margin.top] + ')'); 

d3.csv(url).row(function(d) { 
    d.total = +d.total; 
    d.name = +d.name; 

    return d; 
}).get(function(err, data) { 
    // sort 
    data = _.sortBy(data, 'total').reverse(); 

    // set y domain 
    y.domain(d3.range(data.length)) 
     .rangeBands([0, data.length * barHeight]); 

    // set height based on data 
    height = y.rangeExtent()[1]; 
    d3.select(chart.node().parentNode) 
     .style('height', (height + margin.top + margin.bottom) + 'px') 

    // render the chart 

    // add top and bottom axes 
    chart.append('g') 
     .attr('class', 'x axis top') 
     .call(xAxis.orient('top')); 

    chart.append('g') 
     .attr('class', 'x axis bottom') 
     .attr('transform', 'translate(0,' + height + ')') 
     .call(xAxis.orient('bottom')); 

    var bars = chart.selectAll('.bar') 
     .data(data) 
     .enter().append('g') 
     .attr('class', 'bar') 
     .attr('transform', function(d, i) { return 'translate(0,' + y(i) + ')'; }); 

    bars.append('rect') 
     .attr('class', 'background') 
     .attr('height', y.rangeBand()) 
     .attr('width', width); 

    bars.append('rect') 
     .attr('class', 'total') 
     .attr('height', y.rangeBand()) 
     .attr('width', function(d) { return x(d.total); }) 

    bars.append('text') 
     .text(function(d) { return d.name; }) 
     .attr('class', 'name') 
     .attr('y', y.rangeBand() - 5) 
     .attr('x', spacing); 


    bars.append('line') 
     .attr('class', 'median') 
     .attr('x1', x(median)) 
     .attr('x2', x(median)) 
     .attr('y1', 1) 
     .attr('y2', y.rangeBand() - 1); 
}); 

// resize 
d3.select(window).on('resize', resize); 

function resize() { 
    // update width 
    width = parseInt(d3.select('#chart').style('width'), 10); 
    width = width - margin.left - margin.right; 

    // resize the chart 
    x.range([0, width]); 
    d3.select(chart.node().parentNode) 
     .style('height', (y.rangeExtent()[1] + margin.top + margin.bottom) + 'px') 
     .style('width', (width + margin.left + margin.right) + 'px'); 

    chart.selectAll('rect.background') 
     .attr('width', width); 

    chart.selectAll('rect.total') 
     .attr('width', function(d) { return x(d.total); }); 

    // update axes 
    chart.select('.x.axis.top').call(xAxis.orient('top')); 
    chart.select('.x.axis.bottom').call(xAxis.orient('bottom')); 

} 

// highlight code blocks 
hljs.initHighlighting(); 

</script> 

這裏的數據:

name, total 
Brian, 1514 
Frankie, 1439 
Jeffery, 1615 
Jerry, 685 
Kenneth, 3233 
Michael, 116 
Roy, 817 
Timothy, 2184 

回答

2

我可以看到一對夫婦的問題與您的代碼和數據:

對於問題的數據,你可以通過刪除空格來清理行,例如:

name,total 
Brian,1514 
Frankie,1439 
Jeffery,1615 
Jerry,685 
Kenneth,3233 
Michael,116 
Roy,817 
Timothy,2184 

或者您可以參考他們在您的代碼中使用[]符號,例如:

d[' total'] = +d[' total']; 

d3將前導空格添加到每個記錄的屬性名稱。當你將屬性引用爲d.total時,它將返回undefined,並且undefined被強制爲一個數字爲NaN。

例如,數據[0] ['total']未定義,但數據[0] ['total']具有您所期望的「1514」。從數據中刪除空格是處理這個問題的最簡單方法。

在你的代碼,你這樣做是:

d.name = +d.name; 

這將轉化名義價值爲NaN的,因爲它是用一個字母開頭的文本字符串,所以JavaScript不知道如何強制它到一個數字。

您也引用了一個名爲median的變量,它沒有在您的代碼中聲明。

我創建了一個的jsfiddle的幫助:http://jsfiddle.net/BenLyall/eh1r6j2e/12/

注:我已經改變了d3.csv ...線在DOM與元件的作用,來存儲數據。

+0

d3.csv(url).row(function(d) { d.total = +d.total; d.name = +d.name; return d; }) 

移除的轉化這是我在CSV間距。謝謝你的幫助! – AldoTheApache 2014-09-11 21:53:14

0

你爲什麼讓名字進入數 下面的代碼name.Okay