2017-02-24 139 views
1

我有一個對象數組:如何使用d3創建堆疊條形圖?

var data = [ 
    {"ORDER": 1, "apples": 3840, "bananas": 1920, "cherries": 960}, 
    {"ORDER": 2, "apples": 1600, "bananas": 1440, "cherries": 960}, 
    {"ORDER": 3, "apples": 640, "bananas": 960, "cherries": 640}, 
    {"ORDER": 4, "apples": 320, "bananas": 480, "cherries": 640} 
]; 

我想創建一個堆積條形圖,使訂單是在x軸上,總蘋果,香蕉,並且櫻桃是y軸。 這是到目前爲止我的代碼:

x = d3.scaleOrdinal().range([0, w-50]) 
y = d3.scaleLinear().range([0, h-50]) 

var stack = d3.stack() 
    .keys(["apples", "bananas", "cherries", "dates"]) 
    .order(d3.stackOrderNone) 
    .offset(d3.stackOffsetNone); 

var series = stack(data); 

x.domain(series.map(function(d) { return d.Order; })); 
y.domain([0, d3.max(data, function(d) { return d; })]).nice(); 

g.append("g") 
    .selectAll("g") 
    .data(d3.stack()(series)) 
    .enter().append("g") 
     .attr("fill", function(d) { return color(d.key); }) 
    .selectAll("rect") 
    .data(function(d) { return d; }) 
    .enter().append("rect") 
     .attr("x", function(d) { return x(d.Order); }) 
     .attr("y", function(d) { return y(d[1]); }) 
     .attr("height", function(d) { return y(d[0]) - y(d[1]); }) 
     .attr("width", x); 

我也追加到一個SVG,但我知道問題出在上面的代碼。任何想法做什麼即時錯誤?

回答

1

存在幾個問題。

一,您的圖表數據已經準備層疊series

var series = stack(data); 

此:d3.stack()(series);會產生一個空數組:

var data = [ 
 
    {"ORDER": 1, "apples": 3840, "bananas": 1920, "cherries": 960}, 
 
    {"ORDER": 2, "apples": 1600, "bananas": 1440, "cherries": 960}, 
 
    {"ORDER": 3, "apples": 640, "bananas": 960, "cherries": 640}, 
 
    {"ORDER": 4, "apples": 320, "bananas": 480, "cherries": 640} 
 
]; 
 
var stack = d3.stack() 
 
    .keys(["apples", "bananas", "cherries"]) 
 
    .order(d3.stackOrderNone) 
 
    .offset(d3.stackOffsetNone); 
 
var series = stack(data); 
 
console.log(d3.stack()(series));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script>


再往下:

.attr("x", function(d) { return x(d.Order); }) 

這將返回undefined。首先,你的財產是ORDER而不是Order,其次,如果你在console.log(d)之前返回,你會注意到物業訂單位於:d.data.ORDER

這也與你的規模問題:

x.domain(series.map(function(d) { return d.Order; })); 

對於你的X尺度域,你應該用你的data變量繪製出X域:x.domain(data.map(function(d) { return d.ORDER; }));


說到秤,你的寬度最好用scaleBand()(documentation),而不是一個scaleOrdinal()定義,這將允許您設置寬度與x.bandwidth()

最後,還在說話的尺度: 爲了您的y縮放比例,您的域名將不能正常工作,如果使用this bl.ock as an example,你會看到一個total屬性,將定義域的上端的創作。因此,您需要找到一種方法來獲取要爲每個ORDER繪製圖表的所有屬性的總和。我用一個任意10 000爲上限,以產生一個工作示例(我也不知道你的顏色的功能,所以我只用一個數組):

var data = [ 
 
    {"ORDER": 1, "apples": 3840, "bananas": 1920, "cherries": 960}, 
 
    {"ORDER": 2, "apples": 1600, "bananas": 1440, "cherries": 960}, 
 
    {"ORDER": 3, "apples": 640, "bananas": 960, "cherries": 640}, 
 
    {"ORDER": 4, "apples": 320, "bananas": 480, "cherries": 640} 
 
]; 
 

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

 

 
var x = d3.scaleBand().rangeRound([0, w-50]); 
 
var y = d3.scaleLinear().range([h-50, 0]).domain([0,10000]); 
 
var color = ['#bae4bc','#7bccc4','#43a2ca']; 
 

 
var stack = d3.stack() 
 
    .keys(["apples", "bananas", "cherries"]) 
 
    .order(d3.stackOrderNone) 
 
    .offset(d3.stackOffsetNone); 
 
    
 
var series = stack(data); 
 

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

 
g.append("g") 
 
    .selectAll("g") 
 
    .data(series) 
 
    .enter().append("g") 
 
     .attr("fill", function(d,i) { return color[i]; }) 
 
    .selectAll("rect") 
 
    .data(function(d) { return d; }) 
 
    .enter().append("rect") 
 
     .attr("x", function(d) { return x(d.data.ORDER); }) 
 
     .attr("y", function(d) { return y(d[1]); }) 
 
     .attr("height", function(d) { return y(d[0]) - y(d[1]); }) 
 
     .attr("width", x.bandwidth());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script>

相關問題