簡體   English   中英

d3如何制作單個堆疊柱形圖

[英]d3 how to make single stacked column chart

我試圖讓d3繪制一個單獨的條形圖,如下所示:

 <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> 

如您所見,x位置從零開始,然后每個后續x位置等於前面寬度的總和。

所以我試圖讓d3從名為datavars的數組中繪制類似的東西:

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

...並確保d3將正確的寬度值分配給正確的x值,我創建了以下變量:

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];

...並像這樣定義x值:

//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);

正如您可能已經猜到的那樣,強縮進函數(基於前面寬度的總和,並在prev_width變量中定義)返回每次迭代的字符串(prev_width0,prev_width1等),而不是我認為我定義的值當我創建prev_width變量時。

我顯然錯誤地定義了變量。 知道我怎么能這樣做嗎?

JavaScript不會將字符串"datavars1"解釋為變量datavars1 要將字符串解釋為JavaScript變量,可以使用eval() 所以改變: return 'prev_width'+i; }) return 'prev_width'+i; }) return eval('prev_width'+i); }) return eval('prev_width'+i); }) 雖然更好的想法可能是使用數組,例如:

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]; })

小提琴示例

你可以用顏色做類似的事情:

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

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

條形圖與顏色

您還可以創建單個對象數組來存儲顏色,寬度等。


一個更具可擴展性的想法是擺脫數組prev_width並擁有一個可以將總和達到某一點的函數。 如:

function sum(array, start, end) {
    var total = 0;
    for(var i=start; i<end; i++) total += array[i];
    return total;
}

然后你可以這樣做:

...
   .attr('x',function(d, i){
   return sum(datavars, 0, 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 ba}); //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> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM