2015-12-28 53 views
5

Tôi đang cố gắng để có được d3 để vẽ một biểu đồ thanh xếp chồng lên nhau duy nhất, như vậy:d3 làm thế nào để làm cho cột xếp chồng lên nhau đơn vạch

<svg width = '500' height= '100'> 
 
<rect x='0' y='0' width='224' height='30' fill='green'/> 
 
<rect x='224' y='0' width='84' height='30' fill='blue'/> 
 
<rect x='308' y='0' width='29' height='30' fill='darkgray'/> 
 
<rect x='337' y='0' width='3' height='30' fill='#606060'/> 
 
</svg>

Như bạn thấy, vị trí x bắt đầu từ số không, sau đó mỗi vị trí x tiếp theo bằng tổng của chiều rộng trước đó.

Vì vậy, tôi đang cố gắng để có được d3 để vẽ một cái gì đó như thế từ một mảng gọi datavars:

var datavars = [224, 84, 29, 3]; 

... và để đảm bảo rằng d3 gán đúng chiều rộng giá trị cho đúng x có giá trị , tôi tạo ra các biến:

var prev_width0 = 0; 
var prev_width1 = datavars[0]; 
var prev_width2 = datavars[0] + datavars[1]; 
var prev_width3 = datavars[0] + datavars[1] + datavars[2]; 

... và xác định các giá trị x như vậy:

//create SVG element 
var svg = d3.select('body') 
.append('svg') 
.attr('width', w) 
.attr('height', h); 

svg.selectAll('rect') 
.data(datavars) 
.enter() 
.append('rect') 
.attr('width', function(d){ 
    return d;}) 
       .attr('x',function(d, i){ 
       return 'prev_width'+i; }) 
.attr('y',0) 
.attr('height', 30); 

như bạn có thể đã đoán, hàm thụt lề mạnh (dựa trên tổng độ rộng trước đó và được xác định trong biến số prev_width) trả về một chuỗi cho mỗi lần lặp (prev_width0, prev_width1, v.v.) và không các giá trị tôi nghĩ mình đã xác định khi tôi tạo các biến số prev_width.

Tôi rõ ràng là xác định các biến không chính xác. Bất kỳ ý tưởng làm thế nào tôi có thể làm điều này đúng cách?

Trả lời

4

JavaScript không diễn giải chuỗi "datavars1" làm biến số datavars1. Để diễn giải chuỗi dưới dạng biến JavaScript, bạn có thể sử dụng eval(). Vì vậy, thay đổi: return 'prev_width'+i; }) đến return eval('prev_width'+i); }). Mặc dù là một ý tưởng tốt hơn có thể được sử dụng một mảng thay vì như:

var prev_width = [0, 
        datavars[0], 
        datavars[0] + datavars[1], 
        datavars[0] + datavars[1] + datavars[2] 
       ]; 

... 
    .attr('x',function(d, i){ 
    return prev_width[i]; }) 

Fiddle Example

Bạn có thể làm một điều tương tự với các màu sắc:

var colors = ['green','blue','darkgray','#606060']; 

... 
.attr('fill', function(d, i){ return colors[i]; }) 

Bar chart with color

Bạn có thể cũng tạo một mảng các đối tượng để lưu trữ màu, chiều rộng, v.v.


Một ý tưởng có thể mở rộng hơn sẽ là loại bỏ mảng prev_width và có một hàm có thể tính tổng cho một điểm.Chẳng hạn như:

Sau đó, bạn có thể làm:

... 
    .attr('x',function(d, i){ 
    return sum(datavars, 0, i); }) 

Example using summation

+2

ah ... chúng rất đẹp, cảm ơn một triệu. Đề nghị đầu tiên của bạn là những gì tôi đã đấu tranh hướng tới, và một số tiếp theo là thanh lịch hơn rất nhiều. Nhiều đánh giá cao – prokaryote

0

đây là một đoạn (tiếp cận một chút khác biệt bởi tôi)

//this function deals with pairing finding x for each width in the array and add them to a new array called x_and_width_values 
 
//example :[[0,224],[84,224],[29,308],[3,337]] 
 
//   ^^ ^^^^^^ 
 
//   x width x width ............. 
 
function combinations(prev,current,index,arr){ 
 
// This method focus on accummulating results by reference previous and current element 
 
//for the first and second element we need specifically add this 
 
if(index==1){ 
 
x_and_width_values.push([arr[index-1],0]); 
 
x_and_width_values.push([arr[index],prev]) 
 
} 
 
//other elements we use index as follows; 
 
else{ 
 
x_and_width_values.push([arr[index],prev]) 
 
} 
 
return prev+current 
 
} 
 
//after creating an array with all [x,width] combination, we map it to colors to get out final array 
 
//example :[[[0,224],'green'],[[84,224],'blue'],[29,308],[[3,337],'darkgray'] 
 
function colors_with_combination(e, i) { 
 
    return [x_and_width_values[i], colors[i]]; 
 
    } 
 

 
//*******************acutal beef og code*************** 
 
var x_and_width_values=[]; 
 
//this link is needed to creation of svg elements 
 
var link="http://www.w3.org/2000/svg" 
 
//all your widths 
 
var all_widths=[224,84,29,3]; 
 
//all your colors 
 
var colors=['green','blue','darkgray','#606060']; 
 
//sort your width array to be on the safe side 
 
all_widths.sort(function(a,b){return b-a}); 
 
//find all width and x combination 
 
all_widths.reduce(combinations); 
 
//map width and x values to color values 
 
var all = x_and_width_values.map(colors_with_combination); 
 
//create a loop for object creation 
 
for(var i=0;i<all.length;++i){ 
 
var rect=document.createElementNS(link,'rect'); 
 
rect.setAttributeNS(null,'x',all[i][0][1]) 
 
rect.setAttributeNS(null,'width',all[i][0][0]); 
 
rect.setAttributeNS(null,'fill',all[i][1]); 
 
rect.setAttributeNS(null,'height','30'); 
 
rect.setAttributeNS(null,'y','0'); 
 
document.getElementById('svg').appendChild(rect);; 
 
}
<svg id='svg' width = '500' height= '100'> 
 
</svg>

Các vấn đề liên quan