“Vue JS | Create simple bars chart

October 4th, 2017

I need to create a bar charts, i had developed a jQuery versions before ( see it in action here ), i wants use VUE.JS.

Lets start by create a new project, we need a CSS file ( for style ), a JS file ( for our vue application ) and a HTML/PHP file ( for the templating ).
Open the html/php file, and add this code :

<div class="row">
  <div id="chartbar_componenet" class="chart_wrp column small-12 large-6"> /* id="chartbar_componenet" is the id of the container of our app. */
    <chart-item :barwidth="bar_width" :compwidth="comp_width" :barheight="bar_height" :compheight="comp_height" :charts="chartBars"></chart-item>

  </div>
</div>

And then open the js file.


var gap = 60; /* Define the gap between the bars */
var labels = [
      { id: 0, percentual: 21, label:'Mela', icon:'fa-snowflake-o' },
      { id: 1, percentual: 49, label:'Pera', icon:'fa-superpowers' },
      { id: 2, percentual: 35, label:'Banana', icon:'fa-telegram' },
      { id: 3, percentual: 87, label:'Mandorle', icon:'fa-user-circle-o' },
      { id:4, percentual: 37, label:'Limoni', icon:'fa-telegram' }
    ]; /* The array that we use to pass data to the vue.Js Components */
var wrp_div_width ;
var wrp_div_height ;
var bar_width;
var bar_number = labels.length; /* Variable that contains bars total number */
var bar_number; 
var new_bar_height;


Vue.component('chart-item', {  /* Secondary Component */
  props: ['charts','barwidth','barheight', 'compwidth', 'compheight'], /* Retrieves properties that was declared on the html/php files and use them for populate variables in main component */
  data(){

  },
  computed: { /* Computed properties, They are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain.*/
    calcHeightBar: function(){ /* Create a function that i can call in template : {{calcHeightBar[index]}} */
      var minheight = this.compheight / 100; /* convert percentage in px */
       return this.charts.map(function(item) {
                return Math.round( item.percentual * minheight ) ; /* remove decimals form px */
            });
    }
  },
  mounted(){

  },
   template: `
<div class="general_wrp">
<div v-for="(it, index) in charts" v-bind:id="'el-' + it.id" class="single_bar" :style="{'width': barwidth + 'px'} " ><i v-bind:class=" [ it.icon ]+' single_bar_icon fa' " aria-hidden="true"></i><div class="single_bar_cont" :style="{'height': calcHeightBar[index] + 'px'} "><span class="lable">{{calcHeightBar[index]}}</span></div> </div>
<pre>{{$data}}</pre></div>


   ` /* The template : 
     --> loop - v-for="(it, index) in charts" define the loop 
     -->  :style="{'width': barwidth + 'px'} " set dinamic variable as styleproperties 
     -->  v-bind:class=" [ it.icon ]+' single_bar_icon fa' " set dinamic class 
     --> set dinamicaly height of each bar, retrieve value from Computed properties */
})

var chartbar_componenet = new Vue({ /* Main Components */
  el: '#chartbar_componenet', /* The container of the component declared on html / php file */
  data: {
    chartBars: labels,
    bar_width: '',
    bar_height: 100,
    comp_width:'100',
    comp_height:'400'
    
  }, /* Properties declared on html/php files */
  methods: {
   
  },
  mounted () { /* Hoock that is called after the instance has mounted  */

    this.comp_height = this.$el.clientHeight; /* retrieve height of the container */
    this.comp_width = this.width = this.$el.clientWidth; /* retrieve width of the conteiner */
    this.bar_width = (this.comp_width / bar_number).toString(); /* Calculate the width of the single bar based on the total width divided by the number of the bars */
    this.bar_height =  this.comp_heigh;
    
  }
  
});

and for last open the css file and paste some style :

:root {
  --first-backcolor: #39324b;
  --second-backcolor: #6c4f70;
  --back-gradient: linear-gradient(45deg, var(--first-backcolor) 0%,var(--second-backcolor) 100%);
  --first-barcolor: #6b82a8;
  --second-barcolor: #757081;
  --darkshadow-color: #111;
  --lighttext-color:#d1d3cf;
}

html, body { height: 100%; margin: 0; }
body{background: var(--first-backcolor); background: -moz-var(--back-gradient); background: -webkit-var(--back-gradient); background: var(--back-gradient); }

.chart_wrp{ background-color:transparent; min-height:14rem; display: flex; flex-direction: row; align-content: flex-end; align-items: flex-end; position: relative; left: 50%; margin-left: -28%; border-bottom: 4px solid #ccc; padding-bottom: 6px; margin-top: 0rem;}

.single_bar{ display:flex; background-color:transparent; padding-left:1rem; padding-right:1rem; align-items: flex-end; align-content: flex-end; flex-direction: column-reverse; flex-flow: wrap;}

.single_bar_icon{ width:100%; text-align:center; font-size:2rem !important;
margin-top:.3rem; margin-bottom:.7rem; display: block; overflow: hidden; position: relative; color:var( --lighttext-color); opacity:0; }

.single_bar_cont{background-color:#333; width: 100%; height: 0px; display: block; overflow: hidden; position: relative; -webkit-transition: all 1s ease-in-out; -moz-transition: all 1s ease-in-out; -o-transition: all 1s ease-in-out; transition: all 1s ease-in-out; border-right:2px solid var(--darkshadow-color); -webkit-box-shadow: 0px -2px 18px -5px rgba(0,0,0,1); -moz-box-shadow: 0px -2px 18px -5px rgba(0,0,0,1); box-shadow: 0px -2px 18px -5px rgba(0,0,0,1); }

.single_bar:nth-child(odd) .single_bar_cont{
  background-color:var(--first-barcolor);;
}

.single_bar:nth-child(even) .single_bar_cont{
  background-color:var(--second-barcolor); 
}

.lable{ width:100%; text-align:center; display:block; color:var(--lighttext-color); text-transform:uppercase; font-size:90%; padding-top:1rem; }

Here you can see the final compnent in action :

See the Pen Vue JS | Bar Chart by Pizzi (@Pizzi) on CodePen.0