2013-04-15 45 views
2

我正在尋找我如何能解決我的數據是如何被形象化爲條形圖一些指點。我創建了一個隨時間推移出現的小數倍可視化數據。由於數據收集方式的性質,數據共享某些屬性。舉例來說,你可以看到groupdate下面的.csv的摘錄重複:我是否正確映射或嵌套這些數據?

group,date,totals 
acid,1641,8438 
acid,1641,0 
acid,1641,0 
beef,1641,977.85 
beef,1641,0 
beef,1641,0 
beef,1641,164 
beef,1641,5.25 
bird,1641,121 
bird,1641,0 
bird,1641,12 
bird,1641,1558 
bird,1641,729 
bird,1641,1680 
bird,1641,0 
bird,1641,343 
bird,1641,3 
bird,1641,2092 
bird,1641,0 
bird,1641,0 
bird,1641,107 
bird,1641,2679 
bird,1641,167 
bird,1641,649 
boar,1641,41 
boar,1641,13 
cheese,1641,13 
cheese,1641,22 
cheese,1641,1071 
cheese,1641,17195 

(你可以看到entire dataset here

這個問題我運行到是無論一個date是共享的,而不是總結了totals柱它堆疊在彼此的頂部上的數據。例如,參見:

Bar charts

我有是有顯示爲一個柱狀圖數據掙扎什麼。 (我有一個第二個問題,y軸不能正確縮放)。我試圖用nest修復歲月的問題(這工作了groups),但我似乎無法與date得到它。

這裏是我的代碼,迄今:

var margin = {top: 20, right: 30, bottom: 30, left: 50}, 
    width = 400 - margin.right - margin.left, 
    height = 150 - margin.top - margin.bottom, 
    parse = d3.time.format("%Y").parse; 

// scales 
var x = d3.time.scale().range([0, width]), 
    y = d3.scale.linear().range([0, height]), 
    yscaled = d3.scale.linear().range([height, 0]); 

// load data 
d3.csv("revised.csv", function(error, data) { 

    // nest values by group 
    var groups = d3.nest() 
     .key(function(d) { return d.group; }) 
     .entries(data); 

    // parse dates and numbers, assume values are sorted by date 
    // compute the maximum totals per group 
    groups.forEach(function(s) { 
    s.values.forEach(function(d) { d.date = parse(d.date); d.totals = +d.totals; }); 
    s.maxtotals = d3.max(s.values, function(d) { return d.totals; }); 
    }); 

    // compute the minimum and maximum date across groups 
    x.domain([ 
    d3.min(groups, function(s) { return s.values[0].date; }), 
    d3.max(groups, function(s) { return s.values[s.values.length - 1].date; }) 
    ]); 
    // y.domain([0, d3.max(data, function(d) { return d.totals; })]); 

    // add an SVG element for each group 
    var svg = d3.select("body").selectAll("g") 
     .data(groups) 
    .enter().append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom); 

    var canvas_g = svg.append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
     .each(function(d) { 
      var g = d3.select(this); 
      g.append("g"); 
     // .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     y.domain([0, d3.max(d.values, function(r) { return r.totals; })]); 
     yscaled.domain([0, d3.max(d.values, function(r) { return r.totals; })]); 

     // Draw the charts. 

     g.selectAll("rect.aevents") 
      .data(d.values) 
     .enter().append("rect") 
      .attr("height", function(p) {return y(p.totals)}) 
      .attr("width", 5) 
      .attr("x", function(p, q) {return x(p.date)}) 
      .attr("y", function(p) {return height - y(p.totals)}) 
      // .on("click", function(p) {console.log(p.date)}) 
      .attr("class", "bar"); 
     }); 

    // draw x axis 
    canvas_g.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(d3.svg.axis().scale(x).orient("bottom")); 

    // draw y axis 
    canvas_g.append("g") 
     .attr("class", "y axis") 
     .call(d3.svg.axis().scale(yscaled).orient("left")); 

    // add a small label for the group name 
    svg.append("text") 
     .attr("x", width + 40) 
     .attr("y", height + 15) 
     .attr("text-anchor", "end") 
     .text(function(d) { return d.key; }); 

}); 

是否有不同的方式,我應該通過數據循環?或者,我是否需要以某種方式重構數據?先謝謝你!

+0

如何在酒吧碰撞日期時表示酒吧?你希望他們有一樣的大小,並往右走,與去在未來的日期數據的風險或你想做些別的事情?這個可視化的問題是,你使用x座標作爲另一個比例的時間尺度。這種用法可能有更好的可視化。 –

+0

如果數據在某個日期發生衝突,我希望將數據彙總在一起。所以在上面的'beef'的例子,而不是三個酒吧堆疊在另一個之上的1641年,它會改爲返回'1147.1'。 –

+0

你能安裝一個jsfiddle嗎?這將使它更容易... –

回答

4

首先,你可以閱讀this的答案,如果你想知道更多關於d3.nest()這將幫助你。

對於您的問題,一個良好的方法可以是第一窩使用d3.nest()然後向組映射到其期望的形式的元素。這給:

function formatData(inputData){ 
    var array = d3.nest() 
     .key(function(d){return d.group}) 
     .key(function(d){return d.date}) 
     .entries(inputData) 
     .map(function(d){ 
      var group = d.key 
      var values = d.values.map(function(dd){ 
       var date = dd.key 
       var total = 0 
       dd.values.forEach(function(ddd){ 
        total = total + ddd.totals   
       }) 
       return {date:date, totals:total} 
      }) 
      return {'group':group, 'values':values} 
     }) 
    obj = {} 
    array.forEach(function(d){ 
     obj[d.group] = d.values 
    }) 
    return obj 
} 

inputData是使用d3.csv()加載的數據。這樣你可以得到最好的nest()和'圖()``

如果你想畫條形圖只爲你的牛肉現在可以這樣做:

VAR beefData = FormatData將(myInput).beef

jsFiddle:http://jsfiddle.net/chrisJamesC/FJmMD/3/

+0

感謝您的建議!我想我越來越近了,但我收到了奇怪的數據。它或多或少準確,但我得到了零並附加到「totals」,如下所示: {「acid」:[{「date」:「1641」,「totals」:「0843800」}, { 「日期」: 「1644」, 「總計」: 「0435200」},{ 「日期」: 「1645」, 「總計」: 「0551800」},{ 「日期」: 「1648」, 「總計」:」 0700 「},{」 日期 「:」 1656" , 「總計」: 「0000」},{ 「日期」: 「1657」, 「總計」: 「0000」},{ 「日期」: 「1659」,」總計 「:」 04800 「},{」 日期 「:」 1662" , 「總計」: 「0000」},{ 「日期」: 「1663」, 「總計」: 「01205300」},{ 「日期」:」 1664「,」totals「:」0192000「},{」date「:」1665「,」totals「:」0000「} –

+0

我訪問CSV的方式有問題嗎?當我用你的示例數據集運行一切時,它似乎工作正常:http://jsfiddle.net/hepplerj/7jgqW/。 –

+1

問題是,您不會將字符串轉換爲整數。只需將我計算總數的行替換爲:'total = total + parseFloat(ddd.totals)'。這裏是相應的[jsFiddle](http://jsfiddle.net/chrisJamesC/7jgqW/2/) –