DEV Community

Cover image for Stacked Bar Chart using a JSON Data Source, Plain Vanilla Javascript, Plain CSS and no chart libraries
Rick Delpo
Rick Delpo

Posted on • Edited on

Stacked Bar Chart using a JSON Data Source, Plain Vanilla Javascript, Plain CSS and no chart libraries

First, thank you Kevin at https://dev.to/kevtiq for getting us started on this bar chart. Here is what we are working on.

stacked bar chart

I have re formatted and populated Kevin's original chart with JSON data.

Here are some changes I made to his first pass.

  1. I put html code in a script so we could use a for loop because he repeats the same code many times. For javascript it is necessary to create a new html div on the fly in order for the loop to work in a script.
  2. I added grid lines to the background and used z-index in my css so lines appear behind the bars.
  3. I liked the way Kevin used nth child so I kept this and am using it for the 3 section children in each bar.
  4. I populated the stacked bars from a real json data source found in the program. Also optionally u can save this json file in AWS s3 and call it from there using the js fetch api. Currently I have this section commented out but it is there to show the user how to load from a remote source.
  5. I used mainly CSS and html to build the bars and used array.reduce on my original json array to sum up the product lines. Then I used moment.js to group the sums for each month found in the timestamps of the original data.

some issues
For those who have read this far into the article thanks for reading but I propose a challenge:

  1. I would like to know how to group by date without having to use Moment.js if anyone can help

update, see this link for the answer
https://dev.to/rickdelpo1/how-to-populate-a-stacked-bar-chart-in-plain-javascript-12p9

  1. also would like to group by product name instead of putting products in 3 data keys. If anyone can help with this see the 2 unused fields in my original json data array.

Feel free to copy and paste my entire code from codepen at https://codepen.io/rickdelpo/pen/yLRbEJR , or see below.
For beginners, copy and paste to notepad then save with .html extension and doubleclick to view. There are lots of comments in my code to guide the beginner. Please copy my code because it is also a tutorial. The code is loaded with useful, instructional comments.

<!DOCTYPE html> <html> <!--example of stacked bar chart showing product sales over 5 months, 3 products in each bar--> <head> <meta charset="UTF-8"> <!--use moment.js only for time series data, ie sales for jan, feb, mar etc--> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>  <style> /* used below for section coloring, each section has 3 siblings*/ :nth-child(1) { --nth-child: 1 } :nth-child(2) { --nth-child: 2 } :nth-child(3) { --nth-child: 3 } body { font-family: sans-serif; } .chart { width: 100%; max-width: 800px; height: 400px; display: flex; flex-direction: row; align-items: flex-end; /*gap: 2px;*/ gap: 12px; /*space between bars*/ z-index: 1; /*this is so chart class overlaps barchart class so grid lines are behind the bars in the background*/ } .bar { display: flex; flex-direction: column; height: var(--bar-height, 100%); flex-grow: 1; transition: all 300ms ease; } .section { /* border-bottom: 3px solid black; */ display: flex; flex-grow: var(--section-value, 1); /*transition: all 300ms ease;*/ /*using nth child for 3 children sections of each bar*/ background-color: hsl(calc(100 * var(--nth-child)) 100% 40%); /*background-color: hsl(calc(100 * var(--nth-child)) 80% 70%);*/ /*align-items: flex-end*/ } .section::after { content: attr(data-value); //pulls in values for 3 products per bar /*opacity: 100;*/ /*was 0, meaning default val was hidden*/ color: black; /*color of text*/ margin: auto; text-align: center; /* transition: opacity 300ms ease; */ } .label { text-align: center; } /* below is css for grid lines and Y axis*/ .barchart-Wrapper { display: table; position: relative; margin: 20px 0; height: 252px; } .barChart-Container { display: table-cell; width: 100%; height: 100%; padding-left: 45px; /*width of y axis, this is where first bar begins*/ } /*barchart class has gridlines*/ .barchart { display: table; table-layout: fixed; height: 100%; width: 100%; /*border-bottom: 3px solid tomato;*/ } /* this is needed for bars to appear*/ .barchart-Col { position: relative; vertical-align: bottom; display: table-cell; height: 100%; } .barchart-Col + .barchart-Col { border-left: 4px solid transparent; } /* width and spacing of bars*/ .barchart-Bar { position: relative; height: 0; transition: height 0.5s 2s; width: 66px; /*actual bar width*/ margin: auto; } /*needed for y axis spacing top to bottom */ .barchart-YCol { /* y axis was originally called the time column*/ position: absolute; top: 0; height: 100%; width: 100%; } /* the y axis*/ .barchart-Y { height: 25%; /*each grid is 25% of total height*/ vertical-align: middle; position: relative; } .barchart-Y:after { /*this part does lines across = grid lines using css after selector*/ /*border-bottom: 3px solid black;*/ border-bottom: 1px solid black; /*showing bottom border as a grid line after the time element*/ content: ""; position: absolute; width: 100%; left: 0; top: 0em; } /* allows y axis vals to be centered at grids plus white back */ .barchart-YText { position: absolute; top: -8px; z-index: 1; /*text on y axis is on top of the grid line, otherwise line cuts thru number text*/ background: white; padding-right: 5px; color: #4d4d4d; font-size: 15px; font-family: 'Avenir Medium'; } </style> </head> <body> <!--construct html for stacked bar chart then below run 2 methods in javascript to collect json data and populate chart--> <div class="barchart-Wrapper"> <div class="barchart-YCol"> <!-- this is y axis bar, we are populating y axis--> <div class="barchart-Y"> <span class="barchart-YText">$1000</span>  </div>  <div class="barchart-Y"> <span class="barchart-YText">$ 750</span>  </div>  <div class="barchart-Y"> <span class="barchart-YText">$ 500</span>  </div>  <div class="barchart-Y"> <span class="barchart-YText">$ 250</span>  </div>  </div> <!--end YCol-->  <div class="barChart-Container"> <!--need container so width is applied to y axis--> <div class="barchart"> <!--this is the class with grid lines across--> <!-- below dropped chart class inside barchart class which is in separate container--> <div class="chart" id="navContainer" style='width: 500px; height: 500px;'> <!--this is the chart container--> <script> <!--this script has 2 methods--> var product_1_total = []; //need to declare these as global for final use in bar chart var product_2_total = []; //is an array for purpose of feeding into sections of one bar for one month, i is 5 months here var product_3_total = []; var percent_of_bar_height = []; //bar height as percent of total y axis var percent_of_section_height_1 = []; //percent of total section height per section of each bar for product 1 var percent_of_section_height_2 = []; //percent of total section height per section of each bar for product 2 var percent_of_section_height_3 = []; //percent of total section height per section of each bar for product 3 //first we transform our json data, then feed results to bar chart in the applyData method transform_original_array(); //run this method first then at end of first method run the applyData method //applyData(); //dont run applyData here, run at end of transform method function applyData() { /* //only use this part for live data otherwise json source is below, my live data is stored in aws s3 bucket const response = await fetch('https://xxxxx.s3.us-east-2.amazonaws.com/orders2.json'); const data = await response.json(); console.log(data); var length = data.length; */ let dates = ["jan", "feb", "mar", "apr", "may"]; //x axis labels var div = document.getElementById('navContainer'); //to be passed into new div // create a new div (with id and classes 'new div'): must be done to work in script below using i variable var new_div = document.createElement('div'); //pass in div var so our new div behaves like old div new_div.style.width = "500px"; new_div.style.height = "500px"; //needs height attribute new_div.setAttribute("id", "navContainer"); //adding these id and class atts here displays bars from bottom and not upside down or backwards new_div.setAttribute("class", "chart"); //adding, below fixed here plus above line, also done so bars display vertically and not horizontal //for(var i = 0; i< dates.length; i++) { //use this line with live data for(var i = 0; i < 5; i++) { //use this line when importing local json data // i represents jan, feb, mar, apr, may //we are constructing 1 bar here to be used 5 times using above constructed new_div new_div.innerHTML +="<div class='bar' style='--bar-height: "+percent_of_bar_height[i]+"%"+";'>"+ //setting bar height as percent of tot dollars on y axis //next 3 lines represent 1 bar with 3 sections, each bar has 3 data vals, 3 section heights and 1 bar height  "<div class='section' style='--section-value: "+percent_of_section_height_3[i]+";' data-value='"+product_3_total[i]+"'></div>"+ "<div class='section' style='--section-value: "+percent_of_section_height_2[i]+";'data-value='"+product_2_total[i]+"'></div>"+ "<div class='section' style='--section-value: "+percent_of_section_height_1[i]+";'data-value='"+product_1_total[i]+"'></div>"+ //setting section percentage of product1 total dollars "<div class='label'>"+dates[i]+"</div></div>"; //add month names to x axis // now append the element (as a whole) to wrapper div.appendChild(new_div); //appends newly created div to original div.. needed for script to work } //end for loop } //end apply data function  //below is starting function function transform_original_array() { //note that product_line and dollar_amt are not used until we find a grouping solution var original_array = [{"order_date":"01-03-22","product_line":"prod1","dollar_amt":100,"product1":200,"product2":0,"product3":0}, {"order_date":"01-02-22","product_line":"prod2","dollar_amt":50,"product1":0,"product2":50,"product3":0}, {"order_date":"1-16-22","product_line":"prod3","dollar_amt":50,"product1":0,"product2":200,"product3":50}, {"order_date":"1-17-22","product_line":"prod1","dollar_amt":100,"product1":100,"product2":0,"product3":0}, {"order_date":"1-15-22","product_line":"prod2","dollar_amt":50,"product1":0,"product2":50,"product3":0}, {"order_date":"2-5-22","product_line":"prod1","dollar_amt":100,"product1":100,"product2":0,"product3":0}, {"order_date":"2-6-22","product_line":"prod3","dollar_amt":20,"product1":0,"product2":30,"product3":20}, {"order_date":"2-7-22","product_line":"prod1","dollar_amt":100,"product1":100,"product2":0,"product3":0}, {"order_date":"3-23-22","product_line":"prod2","dollar_amt":200,"product1":0,"product2":200,"product3":0}, {"order_date":"3-5-22","product_line":"prod3","dollar_amt":20,"product1":0,"product2":100,"product3":20}, {"order_date":"3-29-22","product_line":"prod1","dollar_amt":100,"product1":100,"product2":0,"product3":0}, {"order_date":"3-25-22","product_line":"prod1","dollar_amt":100,"product1":100,"product2":0,"product3":0}, {"order_date":"4-23-22","product_line":"prod1","dollar_amt":500,"product1":500,"product2":50,"product3":50}, {"order_date":"4-24-22","product_line":"prod2","dollar_amt":100,"product1":0,"product2":100,"product3":50}, {"order_date":"5-10-22","product_line":"prod3","dollar_amt":50,"product1":0,"product2":0,"product3":50}, {"order_date":"5-15-22","product_line":"prod1","dollar_amt":500,"product1":100,"product2":0,"product3":0}, {"order_date":"5-25-22","product_line":"prod2","dollar_amt":50,"product1":0,"product2":50,"product3":150}] ; //end of array //first transform original array into product sums for each month array, then used to populate bar chart const groupTimelineData = (elements, type) => { //for all elements in original array reduce them down to a sum for each month //first we need to reduce the current values so we can use them in a resultant array to populate our monthly bar chart // since our bar chart is by the month we need our original data transformed to 'by the month' format  result = elements.reduce((original_array, value) => { //reduce above array to sums of each product line monthNumber = moment(value.order_date, 'MM/DD/YYYY')[type]() + (type === 'month' ? 1 : 0); //declaring and formatting monthNumber where moment/type =month, starting at month 1 for index 0, we use moment.js for this res = original_array.find(e => e[type] === monthNumber); //declaring interim result object and finding all timestamps in orig array where month is 1,2,3 etc if (!res) { //since array starts as empty initialize the array, in next line, first add then push res = { [type]: monthNumber, product1: 0, product2: 0, product3: 0 }; //add elements original_array.push(res); //then push vals into new array we are constructing } //end if res.product1 += value.product1; //then for each month accumulate our sum for each subsequent pass res.product2 += value.product2; res.product3 += value.product3; return original_array; }, []); // The initial value is an empty object return result; // result is the final interim array }; //end of groupTimelineData console.log(groupTimelineData(original_array, 'month')); //this is the result object, 3 product sums for each month, original array is now transformed console.log(JSON.stringify(result, null, 1)); //returns new resultant array in readable json format //part 2 //now that result is name of new array we can operate on it and do some math //iterating over resultant array in new json format for (let getProductTotal of result) { let total1 = getProductTotal.product1; let total2 = getProductTotal.product2; let total3 = getProductTotal.product3; let total =total1+total2+total3; //need new var for total let z1 = (total/1000)*100; //new var for percent let z2 = (total1/total)*100; //percent of section prod1 let z3 = (total2/total)*100; //percent of section prod2 let z4 = (total3/total)*100; //percent of section prod3 percent_of_section_height_1.push(z2); percent_of_section_height_2.push(z3); percent_of_section_height_3.push(z4); //console.log("sub2 "+z2); //running incremented percent_of_bar_height array //console.log(percent_of_section_height_1); //section percent array, running increments //console.log("sec3 "+percent_of_section_height_3); //section percent array, running increments //push all calcs into arrays in order to populate bar chart for 5 passes (jan,feb,mar,apr,may) product_1_total.push(total1); //pushing total1 into bar chart, need to do same for others product_2_total.push(total2); product_3_total.push(total3); percent_of_bar_height.push(z1); //console.log ("total = "+total); //total for first pass etc //console.log ("pcct = "+z1); } //end for loop console.log(percent_of_bar_height); //total bar as percent of total dollars in y axis //object of above method is to produce array for each product key so ultimate for loop can use the array vals for each month applyData(); //now run this method found above to populate bar chart } //end of transform_original_array method </script>  </div> <!-- closing tag of chart class-->  </div> <!--end barchart div-->  </div> <!--end bar chart container-->  </div> <!--end bar chart wrapper-->  <!--chart keys--> <b>dollar sales by product line per month</b>  <p>magenta = product 1</p> <p>blue = product 2</p> <p>green = product 3</p>  </body>  </html>  
Enter fullscreen mode Exit fullscreen mode

Below is a much more simplified version of the above code where we do not need to use reduce or the moment library. This is the pure js version where we use a simple forEach loop to iterate our array. Just copy and paste and save to dot html then double click.

<!DOCTYPE html> <html> <!--example of stacked bar chart showing product sales over 5 months with 3 products in each bar--> <head> <meta charset="UTF-8"> <style> /* used below for section coloring, each section has 3 siblings*/ :nth-child(1) { --nth-child: 1 } :nth-child(2) { --nth-child: 2 } :nth-child(3) { --nth-child: 3 } body { font-family: sans-serif; } .chart { width: 100%; max-width: 800px; height: 400px; display: flex; flex-direction: row; align-items: flex-end; gap: 12px; /*space between bars*/ z-index: 1; /*this is so chart class overlaps barchart class so grid lines are behind the bars in the background*/ } .bar { display: flex; flex-direction: column; height: var(--bar-height, 100%); flex-grow: 1; transition: all 300ms ease; } .section { display: flex; flex-grow: var(--section-value, 1); /*using nth child for 3 children sections of each bar*/ background-color: hsl(calc(100 * var(--nth-child)) 100% 40%); } .section::after { content: attr(data-value); //pulls in values for 3 products per bar color: black; /*color of text*/ margin: auto; text-align: center; } .label { text-align: center; } /* below is css for grid lines and Y axis*/ .barchart-Wrapper { display: table; position: relative; margin: 20px 0; height: 252px; } .barChart-Container { display: table-cell; width: 100%; height: 100%; padding-left: 45px; /*width of y axis, this is where first bar begins*/ } /*barchart class has gridlines*/ .barchart { display: table; table-layout: fixed; height: 100%; width: 100%; } /* this is needed for bars to appear*/ .barchart-Col { position: relative; vertical-align: bottom; display: table-cell; height: 100%; } .barchart-Col + .barchart-Col { border-left: 4px solid transparent; } /* width and spacing of bars*/ .barchart-Bar { position: relative; height: 0; transition: height 0.5s 2s; width: 66px; /*actual bar width*/ margin: auto; } /*needed for y axis spacing top to bottom */ .barchart-YCol { /* y axis was originally called the time column*/ position: absolute; top: 0; height: 100%; width: 100%; } /* the y axis*/ .barchart-Y { height: 25%; /*each grid is 25% of total height*/ vertical-align: middle; position: relative; } .barchart-Y:after { /*this part does lines across = grid lines using css after selector*/ border-bottom: 1px solid black; /*showing bottom border as a grid line after the time element*/ content: ""; position: absolute; width: 100%; left: 0; top: 0em; } /* allows y axis vals to be centered at grids plus white back */ .barchart-YText { position: absolute; top: -8px; z-index: 1; /*text on y axis is on top of the grid line, otherwise line cuts thru number text*/ background: white; padding-right: 5px; color: #4d4d4d; font-size: 15px; font-family: 'Avenir Medium'; } </style> </head> <body> <!--construct html for stacked bar chart then below run 2 methods in javascript to collect json data and populate chart--> <div class="barchart-Wrapper"> <div class="barchart-YCol"> <!-- this is y axis bar, we are populating y axis--> <div class="barchart-Y"> <span class="barchart-YText">$1000</span>  </div>  <div class="barchart-Y"> <span class="barchart-YText">$ 750</span>  </div>  <div class="barchart-Y"> <span class="barchart-YText">$ 500</span>  </div>  <div class="barchart-Y"> <span class="barchart-YText">$ 250</span>  </div>  </div> <!--end YCol-->  <div class="barChart-Container"> <!--need container so width is applied to y axis--> <div class="barchart"> <!--this is the class with grid lines across--> <!-- below dropped chart class inside barchart class which is in separate container--> <div class="chart" id="navContainer" style='width: 500px; height: 500px;'> <!--this is the chart container--> <script> <!--this script has 2 methods--> //creating empty arrays to be populated after original array transformation var product_1_total = []; //need to declare these as global for final use in bar chart var product_2_total = []; //is an array for purpose of feeding into sections of one bar for one month, i is 5 months here var product_3_total = []; var percent_of_bar_height = []; //bar height as percent of total y axis var percent_of_section_height_1 = []; //percent of total section height per section of each bar for product 1 var percent_of_section_height_2 = []; //percent of total section height per section of each bar for product 2 var percent_of_section_height_3 = []; //percent of total section height per section of each bar for product 3 //first we transform our json data, then feed results to bar chart in the applyData method transform_original_array(); //run this method first see below then at end of first method run the applyData method in next line function applyData() { let dates = ["jan", "feb", "mar", "apr", "may"]; //x axis labels var div = document.getElementById('navContainer'); //to be passed into new div // create a new div (with id and classes 'new div'): must be done to work in script below using i variable var new_div = document.createElement('div'); //pass in div var so our new div behaves like old div new_div.style.width = "500px"; new_div.style.height = "500px"; //needs height attribute new_div.setAttribute("id", "navContainer"); //adding these id and class atts here displays bars from bottom and not upside down or backwards new_div.setAttribute("class", "chart"); //adding, below fixed here plus above line, also done so bars display vertically and not horizontal for(var i = 0; i < dates.length; i++) { //for each of the 5 months populate the stacked bars from data calculated in our first method // i represents jan, feb, mar, apr, may, so for each month do below //next we are constructing 1 bar here to be used 5 times using above constructed new_div new_div.innerHTML +="<div class='bar' style='--bar-height: "+percent_of_bar_height[i]+"%"+";'>"+ //setting bar height as percent of tot dollars on y axis //next 3 lines represent 1 bar with 3 sections, each bar has 3 data vals, 3 section heights and 1 bar height  "<div class='section' style='--section-value: "+percent_of_section_height_3[i]+";' data-value='"+product_3_total[i]+"'></div>"+ "<div class='section' style='--section-value: "+percent_of_section_height_2[i]+";'data-value='"+product_2_total[i]+"'></div>"+ "<div class='section' style='--section-value: "+percent_of_section_height_1[i]+";'data-value='"+product_1_total[i]+"'></div>"+ //setting section percentage of product1 total dollars "<div class='label'>"+dates[i]+"</div></div>"; //add month names to x axis // now append the element (as a whole) to wrapper div.appendChild(new_div); //appends newly created div to original div.. needed for script to work } //end for loop } //end apply data function  //below is starting function function transform_original_array() { //new array enables order to have multiple products on it vs old way, took out tot dollars and product_line from prev version //program figures tot follars so does not need to be in orig data and prod_line restricted each order to only 1 product  //so now with mult products per order we can use invoicing to pdf capability  //orders with mult products will be customer ordering an array of products so order detail will be a nested array inside json array  var original_array = [{"order_date":"01-03-22","product1":200,"product2":20,"product3":30}, {"order_date":"01-02-22","product1":0,"product2":50,"product3":0}, {"order_date":"1-16-22","product1":0,"product2":200,"product3":50}, {"order_date":"1-17-22","product1":100,"product2":0,"product3":0}, {"order_date":"1-15-22","product1":0,"product2":50,"product3":0}, {"order_date":"2-5-22","product1":100,"product2":100,"product3":0}, {"order_date":"2-6-22","product1":0,"product2":30,"product3":20}, {"order_date":"2-7-22","product1":100,"product2":0,"product3":150}, {"order_date":"3-23-22","product1":0,"product2":200,"product3":0}, {"order_date":"3-5-22","product1":0,"product2":100,"product3":20}, {"order_date":"3-29-22","product1":100,"product2":0,"product3":0}, {"order_date":"3-25-22","product1":100,"product2":0,"product3":0}, {"order_date":"4-23-22","product1":500,"product2":50,"product3":50}, {"order_date":"4-24-22","product1":0,"product2":100,"product3":50}, {"order_date":"5-10-22","product1":0,"product2":0,"product3":50}, {"order_date":"5-15-22","product1":100,"product2":0,"product3":0}, {"order_date":"5-25-22","product1":0,"product2":50,"product3":150}] ; //end of array //or instead of above do below and comment out above array /* //only use this part to get array from aws s3 bucket instead of local data above, my array is stored as orders2.json const response = await fetch('https://xxxxx.s3.us-east-2.amazonaws.com/orders4.json'); const original_array = await response.json(); */ //first transform original array into product sums for each month array, then used to populate bar chart in second method var monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; var result = []; //this resultant array shows summation of each month sales var dateArr = []; //this is a control array that keeps track of the months so when a new month happens we start the summing again //this is like grouping months so we can sum while iteration is in each month console.log ("below shows each pass with its index value"); //this function iterates over each record in original array above, groups the months and sums orders per product per month original_array.forEach(function(currValue) { date = new Date(currValue['order_date']); //for js date to work must be inside a function, needs valid data format yyyy etc //next 3 lines converts non conforming date on the fly so conforming/valid date can be used in date object var dateString = new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )) .toISOString() .split("T")[0]; console.log(dateString); //showing date, press ctrl+shift+j after double clicking html file, then arrow up to see entire console date = monthNames[date.getMonth()]; //gets month names from above array to be grouped below, var date now becomes month name console.log(date); //shows month name after getting month name from date string var index = dateArr.indexOf(date); //equaling -1 on first pass, because january is not in datearr yet //in JavaScript, the indexOf() method for arrays returns -1 if the value being searched for is not present in the array //when first record in feb comes around index will be -1 again because month is not in our control array yet console.log("index value = "+index); if (index == -1) { //is equal to -1 only for first pass of each month, above forces -1 so we can initialize first pass dateArr.push(date); //when month is not found push it into control array, then on next pass else condition will execute var obj = {month: date, product1: currValue.product1, product2: currValue.product2, product3: currValue.product3}; //we are grabbing the keys and their initial values here result.push(obj); //then push object with keys and values into the resultant array called result } else { //else sum vals when month is now found in ctrl array, index -1 now becomes 0, press ctrl+shift+j for index at each iteration //while in each month accumulate the vals as we go, getting a running total //as we iterate when new month is encountered the above if condition kicks in result[index].product1 += currValue.product1; //increment sum on each pass starting index =0 result[index].product2 += currValue.product2; //no need to push, result val updates each time using += operator result[index].product3 += currValue.product3; //+= is adding the curr val to the accumulated val for each pass //this is what is acting similar to the reduce accumulator } }); //end of simple forEach loop instead of using reduce to loop console.log("below is the result array showing sums of sales for each month by product line"); console.log(JSON.stringify(result, null, 1)); //shows each month with summed totals //part 2 //now that the result array is populated we can operate on it and do some math //below we iterate over the resultant array which was transformed into json format above for (let getProductTotal of result) { let total1 = getProductTotal.product1; let total2 = getProductTotal.product2; let total3 = getProductTotal.product3; let total =total1+total2+total3; //need new var for total let z1 = (total/1000)*100; //new var for percent let z2 = (total1/total)*100; //percent of section prod1 let z3 = (total2/total)*100; //percent of section prod2 let z4 = (total3/total)*100; //percent of section prod3 percent_of_section_height_1.push(z2); //push method populates empty arrays created above for each pass percent_of_section_height_2.push(z3); percent_of_section_height_3.push(z4); //push all calcs into arrays in order to populate bar chart for 5 passes (jan,feb,mar,apr,may) product_1_total.push(total1); //pushing total1 into array then into bar chart, need to do same for others product_2_total.push(total2); product_3_total.push(total3); percent_of_bar_height.push(z1); } //end for loop applyData(); //now run this method #2 found above to populate the stacked bars } //end of transform_original_array method </script>  </div> <!-- closing tag of chart class-->  </div> <!--end barchart div-->  </div> <!--end bar chart container-->  </div> <!--end bar chart wrapper-->  <!--chart keys--> <b>dollar sales by product line per month</b>  <p>magenta = product 1</p> <p>blue = product 2</p> <p>green = product 3</p>  </body> </html>  
Enter fullscreen mode Exit fullscreen mode

Thanks for reading. For more about Rick Delpo click https://javasqlweb.org/about.html

Top comments (0)