D3 how to make a single columnar table

I am trying to get d3 to draw a single histogram, like this:

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

As you can see, the x position starts from zero, then each subsequent x position is equal to the sum of the previous widths.

So, I'm trying to get d3 to draw something like this from an array called datavars:

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

... and so that d3 assigns the correct width value to the correct x value, I created these variables:

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

... and define the value of x as follows:

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

As you might have guessed, a strongly backing function (based on the sum of the previous widths and defined in the prev_width variables) returns a string for each iteration (prev_width0, prev_width1, etc.) and not the values ​​that I thought I determined when i created prev_width variables.

I, obviously, incorrectly define variables. Any idea how I can do this right?

+5
source share
2 answers

JavaScript does not interpret the string "datavars1" as the variable datavars1 . To interpret a string as a JavaScript variable, you can use eval() . Therefore, change: return 'prev_width'+i; }) return 'prev_width'+i; }) to return eval('prev_width'+i); }) return eval('prev_width'+i); }) . Although a better idea might be to use an array, namely:

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

Script example

You can do a similar thing with flowers:

 var colors = ['green','blue','darkgray','#606060']; ... .attr('fill', function(d, i){ return colors[i]; }) 

Color bar graph

You can also create a single array of objects to store color, width, etc.


A more scalable idea would be to get rid of the prev_width array and have a function that can take the sum to a point. For instance:

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

Then you can do:

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

Summarization Example

+4
source

Here is a fragment (approached a little differently)

 //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> 
0
source

Source: https://habr.com/ru/post/1239378/


All Articles