DEV Community

Cover image for Inspecting the code of a stacked CSS Bar Chart data visualization (with no chart libraries)
Rick Delpo
Rick Delpo

Posted on

Inspecting the code of a stacked CSS Bar Chart data visualization (with no chart libraries)

In data analytics we use bar charts all the time. Here we construct a product sales stacked bar chart in plain javascript and css with no chart libraries (no chart.js, lodash or moment)

  1. html bars are a for loop, 1 bar done 5 times, using css flexbox layout. This is how we build the chart.
  2. grid lines using css after selector and css z index
  3. section colors using css nth child
  4. data source is json file saved in aws s3
  5. data populated using array.indexOf() and array.reduce() . This is the plain js part where we do all our calcs
  6. we use 2 methods in our JS, 1 to transform the data and 2 to build and populate the chart using array.push on an empty array to populate the final array

Our overall html div structure starts with the barchart-wrapper class inside where we construct the y axis and then the barchart class for grid lines. Then we drop the chart class inside a chart container which is inside the barchart class. It is the chart class that uses flexbox layout and contains our javascript to build everything.

<div class="barchart-Wrapper">
<div class="barChart-Container"> 
<div class="barchart">
<div class="chart" id="navContainer" style='width: 500px; height: 500px;'>

flexbox plus script goes here, this is where we drop in the chart class which uses css flexbox layout to give life to a bar 

</div> <!-- closing tag of chart class-->
     </div> <!--end barchart div-->
   </div> <!--end bar chart container-->
    </div> <!--end bar chart wrapper-->


Enter fullscreen mode Exit fullscreen mode

Here is a more detailed view

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

the chart and script go here

</div> <!-- closing tag of chart class-->
     </div> <!--end barchart div-->
   </div> <!--end bar chart container-->
    </div> <!--end bar chart wrapper-->

Enter fullscreen mode Exit fullscreen mode

Once inside the chart class div we use javascript to create a for loop which then repeats one bar five times. In order to make our for loop work we need to create a new div on the fly. This new div contains multiple html tags used in the for loop. Here we are getting the inner html from the new div to construct one bar.

var div = document.getElementById('navContainer'); //a wrapper div to be appended by 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

let dates = ["jan", "feb", "mar", "apr", "may"];  //x axis labels
for(var i = 0; i < 5; i++) {            
                         //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
Enter fullscreen mode Exit fullscreen mode

Now that we have the chart built we need to run the transform_original_array method in our javascript. This method traverses our JSON dataset objects and transforms the result into a new array which we then make some calculations on, group the result by month and reduce (sum the data) for each month. These calcs are pushed into interim arrays which are then used to populate the final bar chart.

For Grouping and Summing click this link https://dev.to/rickdelpo1/group-by-month-and-sum-values-for-each-month-explained-in-plain-english-and-done-in-plain-javascript-with-example-4o9k

Find the Full Code here at my codepen https://codepen.io/rickdelpo/pen/KKGQrQv which is fully commented for easier understanding.

Top comments (0)