2013-06-21 57 views
2

我在d3.js中實現了一個堆疊條形圖。這是多年來城市中各種類型(人的類別)的人口。儘管我在一些參考文獻的幫助下取得了一些成果,但我還沒有得到我想要的確切結果。d3.js - 如何爲堆疊條形圖進行數據映射和過濾

我想我正面臨數據映射和過濾函數中的一些問題,並將它們分配到顏色域中。

任何幫助將不勝感激。

這裏是我的代碼: -

<!DOCTYPE html> 

<meta charset="utf-8"> 
<style> 

body { 
font: 10px sans-serif; 
} 

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

.bar { 
fill: steelblue; 
} 

.x.axis path { 
display: none; 
} 

</style> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"> 
</script> 
<script> 


var margin = { 
    top: 20, right: 20, bottom: 30, left: 40} 
    , 
    width = 960 - margin.left - margin.right, 
    height = 500 - margin.top - margin.bottom, 
    yAxMin_PA = 0, 
yAxMax_PA = 1500; 

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

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

var color = d3.scale.category20(); 

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

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .tickFormat(d3.format(".2s")); 

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

var data = { 
    "bars": [ 
    { 
     "year": 2004, 
     "population": [ 
     { 
      "category": 1, 
      "strength": 31 
     } 
     , 
     { 
      "category": 2, 
      "strength": 21 
     } 
     , 
     { 
      "category": 3, 
      "strength": 41 
     } 
     ] 
    } 
    , 
    { 
     "year": 2005, 
     "population": [ 
     { 
      "category": 1, 
      "strength": 23 
     } 
     , 
     { 
      "category": 2, 
      "strength": 43 
     } 
     , 
     { 
      "category": 3, 
      "strength": 33 
     } 
     ] 
    } 
    , 
    { 
     "year": 2006, 
     "population": [ 
     { 
      "category": 1, 
      "strength": 29 
     } 
     , 
     { 
      "category": 2, 
      "strength": 41 
     } 
     , 
     { 
      "category": 3, 
      "strength": 55 
     } 
     , 
     { 
      "category": 4, 
      "strength": 69 
     } 
     , 
     { 
      "category": 5, 
      "strength": 89 
     } 
     , 
     { 
      "category": 6, 
      "strength": 75 
     } 
     ] 
    } 
    , 
    { 
     "year": 2007, 
     "population": [ 
     { 
      "category": 1, 
      "strength": 49 
     } 
     , 
     { 
      "category": 2, 
      "strength": 43 
     } 
     , 
     { 
      "category": 3, 
      "strength": 25 
     } 
     ] 
    } 
    , 
    { 
     "year": 2008, 
     "population": [ 
     { 
      "category": 1, 
      "strength": 20 
     } 
     , 
     { 
      "category": 2, 
      "strength": 43 
     } 
     , 
     { 
      "category": 3, 
      "strength": 55 
     } 
     ] 
    } 
    ] 
} 
    ; 



x.domain(data.bars.map(function(d) { 
    return d.year; 
} 
        )); 

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

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

for (k = 0; k < data.bars.length; k++) { 
var state = svg.append("g") 
    .attr("class", "g") 
    .attr("transform", function (d) { 
     return "translate(" + x(data.bars[k].year) + ",0)"; 
    }); 

state.selectAll("rect") 
    .data(data.bars[k].population) 
    .enter().append("rect") 
//.attr("width", x.rangeBand()) 
.attr("class", "rect_grp" + k) 
    .attr("id", function (d, i) { 
     return "rect" + i; 
    }) 
    .attr("width", function() { 
     return x.rangeBand(); 
    }) 
    .attr("y", function (d, i) { /*console.log("hiii");*/ 
     if (i != 0) { 

      var prevHgt = d3.select(".rect_grp" + k + "#rect" + (i - 1)).attr("height"); // Select height of previous rectangle 
      var ylimit = d3.select(".rect_grp" + k + "#rect" + (i - 1)).attr("y"); // Select y of previous rectangle 
      console.log("prevHgt=>" + prevHgt); 

      return ((parseFloat(ylimit)) - (parseFloat(prevHgt))); 
     } else { 
      return y(d.strength); 
     } 
    }) 
    .attr("height", function (d, i) { 

     return (Math.round(y(yAxMin_PA)) - Math.round(y(d.strength))); 

    }) 
    .style("fill", function (d, i) { 
     console.log(i); 
     return color(i); 
    }); 

}

</script> 
+0

那麼你的問題是什麼?你想達到什麼目標?你目前的解決方案在哪裏不足? –

+0

嗯,我沒有得到顏色領域的類別。例如,我需要每年在色域中的所有類別(例如2004年,我們有三類人員「類別」:1,「類別」:2,「類別」:3)。 如果您運行此代碼,您將看到問題。 – user2339182

+0

您可能會發現從[NVD3]開始更容易(http://nvd3.org/ghpages/multiBar.html)。 –

回答

1

我發現它是有用的給人們,而不是讓他們運行它自己的例子。看到這裏:http://tributary.io/inlet/5835233

圍繞線157,它說

d.population.forEach (function(d){ 
    color.domain(d3.keys(d).filter(function(name) { 
    return name; 
} 

name始終爲"category""strength"。這是因爲你的數據是如何安排的。我想你想要的是讓你的數據是

{year: 2008, 
population: { 
    category1: 20, 
    category2: 43, 
    category3: 55} 
} 

如果你把你的數據就是這樣,你必須惹你究竟是如何設置你color實例的域周圍,因爲只有forEach作品在數組上,我們現在已經將數據設置在一個對象中。類似於color.domain(d3.keys(d.population))。把我的示例放在支流上,嘗試幾件事情。看看d3.keys()文檔,看看它是如何工作的。

+0

謝謝..你的回答很有幫助。請在編輯的代碼中幫助我。我得到除「高度」以外的矩形的每個屬性的值。爲什麼這樣? – user2339182

+0

好的..我明白了,只是錯過了一個DOM概念。 – user2339182