“Vue JS | Create simple bars chart
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