vue-bar-graph
Version:
Simple and lightweight Vue chart svg component without chart library dependencies
2 lines (1 loc) • 8.19 kB
JavaScript
(function(h,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(h=typeof globalThis<"u"?globalThis:h||self,e(h.VueBarGraph={},h.Vue))})(this,function(h,e){"use strict";const m=(t,r)=>{const n=t.__vccOpts||t;for(const[l,s]of r)n[l]=s;return n},g={props:{title:{type:String,default:""},points:{type:Array,default:()=>[]},height:{type:Number,default:100},width:{type:Number,default:300},showYAxis:{type:Boolean,default:!1},showXAxis:{type:Boolean,default:!1},labelHeight:{type:Number,default:12},showTrendLine:{type:Boolean,default:!1},trendLineColor:{type:String,default:"green"},trendLineWidth:{type:Number,default:2},easeIn:{type:Boolean,default:!0},showValues:{type:Boolean,default:!1},maxYAxis:{type:Number,default:0},animationDuration:{type:Number,default:.5},barColor:{type:String,default:"deepskyblue"},textColor:{type:String,default:"black"},textAltColor:{type:String,default:"black"},textFont:{type:String,default:"10px sans-serif"},useCustomLabels:{type:Boolean,default:!1},customLabels:{type:Array,default:()=>[]}},data(){return{dynamicPoints:[],staticPoints:[],extraTopHeightForYAxisLabel:4,extraBottomHeightForYAxisLabel:4,digitsUsedInYAxis:0}},computed:{usingObjectsForDataPoints(){return this.points.every(t=>typeof t=="object")},dataPoints(){return this.usingObjectsForDataPoints?this.points.map(t=>t.value):this.points},dataLabels(){return this.points.map((t,r)=>this.useCustomLabels?this.customLabels[r]:this.usingObjectsForDataPoints?t.label:r+1)},dataColors(){return this.points.map(t=>({barColor:t&&t.barColor?t.barColor:this.barColor,textColor:t&&t.textColor?t.textColor:this.textColor,textAltColor:t&&t.textAltColor?t.textAltColor:this.textAltColor}))},yAxisWidth(){return this.digitsUsedInYAxis*5.8+5},xAxisHeight(){return this.showYAxis?this.labelHeight:this.labelHeight+this.extraBottomHeightForYAxisLabel+this.extraTopHeightForYAxisLabel},fullSvgWidth(){return this.width},fullSvgHeight(){return this.height},innerChartWidth(){return this.showYAxis?this.width-this.yAxisWidth:this.width},innerChartHeight(){let t=this.height;return this.showYAxis&&(t-=this.extraTopHeightForYAxisLabel+this.extraBottomHeightForYAxisLabel),this.showXAxis&&(t-=this.xAxisHeight),t},partitionWidth(){return this.innerChartWidth/this.dataPoints.length},maxDomain(){return this.maxYAxis?this.maxYAxis:Math.ceil(Math.max(...this.dataPoints))},chartData(){return this.dynamicPoints.map((t,r)=>({staticValue:this.staticPoints[r],index:r,label:this.dataLabels[r],width:this.partitionWidth-2,midPoint:this.partitionWidth/2,yLabel:this.innerChartHeight+4,x:r*this.partitionWidth,xMidpoint:r*this.partitionWidth+this.partitionWidth/2,yOffset:this.innerChartHeight-this.y(t),height:this.y(t),barColor:this.dataColors[r].barColor,textColor:this.dataColors[r].textColor,textAltColor:this.dataColors[r].textAltColor}))},trendLine(){const t=this.applySlope(this.dynamicPoints);return{x1:this.partitionWidth/2,y1:this.roundTo(this.innerChartHeight-this.y(t[0]),2),x2:this.innerChartWidth-this.partitionWidth/2,y2:this.roundTo(this.innerChartHeight-this.y(t[t.length-1]),2)}}},watch:{dataPoints:{handler(t){this.tween(t)},deep:!0}},created(){this.easeIn?this.tween(this.dataPoints):(this.dynamicPoints=this.dataPoints,this.staticPoints=this.dataPoints)},methods:{y(t){return t/this.maxDomain*this.innerChartHeight},roundTo(t,r=0){let n=!1,l=t;l<0&&(n=!0,l*=-1);const s=10**r;return l=parseFloat((l*s).toFixed(11)),l=(Math.round(l)/s).toFixed(2),n&&(l=(l*-1).toFixed(2)),l},easeInFunc(t){return 1-Math.cos(t*(Math.PI/2))},tween(t){this.staticPoints=t,this.dynamicPoints=Array(t.length).fill(0);const r=this.dynamicPoints,n=200,l=10;let s=new Date().getTime(),o=setInterval(()=>{if(this.dynamicPoints!==r){clearInterval(o);return}let i=(new Date().getTime()-s)/n;if(i=i<0?1:Math.min(i,1),i>=1){clearInterval(o),this.dynamicPoints=t;return}for(let d=0;d<r.length;d+=1)this.dynamicPoints[d]=this.easeInFunc(i)*t[d]},l)},getTicks(){for(let t=6;t>0;t-=1)if(this.maxDomain%t===0){const r=t<3,n=r?3:t;return this.digitsUsedInYAxis=this.maxDomain.toFixed(r?1:0).replace(".","").length,[...new Array(n+1)].map((l,s)=>{const o=this.maxDomain/n*(n-s),i=this.innerChartHeight/n*s;return{key:s,text:r?o.toFixed(1):o,yText:i<10?10:i+4,x1:this.yAxisWidth-4,y1:i,x2:this.yAxisWidth-1,y2:i}})}return[]},applySlope(t){let r=0,n=0;for(let a=0;a<t.length;a+=1)r+=a,n+=t[a];r/=t.length,n/=t.length;let l=0,s=0;for(let a=0;a<t.length;a+=1)l+=(a-r)*(t[a]-n),s+=(a-r)**2;const o=l/s,i=n-o*r,d=[];for(let a=0;a<t.length;a+=1)d.push(o*a+i);return d}}},f=["width","height"],u={key:0,id:"title"},C=["transform"],A=["transform","width","height"],w=["transform"],k=["width","height","y"],_=["x","y","dy"],p={key:1},b=["x","y"],B=["x1","x2","y1","y2"],V=["x1","y1","x2","y2","stroke-width","stroke"],H={key:0},L=["x1","x2","y1","y2"],P={key:1},S=["x1","x2","y1"],F=["x1","y1","x2","y2"],W=["y"];function N(t,r,n,l,s,o){return e.openBlock(),e.createElementBlock("svg",{width:o.fullSvgWidth,height:o.fullSvgHeight,"aria-labelledby":"title",role:"img"},[n.title?(e.openBlock(),e.createElementBlock("title",u,e.toDisplayString(n.title),1)):e.createCommentVNode("",!0),e.createElementVNode("g",{transform:`translate(0,${n.showYAxis?s.extraTopHeightForYAxisLabel:0})`},[e.createElementVNode("g",{transform:`translate(${n.showYAxis?o.yAxisWidth:0},0)`,width:o.innerChartWidth,height:o.innerChartHeight},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.chartData,i=>(e.openBlock(),e.createElementBlock("g",{key:i.index,transform:`translate(${i.x},0)`},[e.createElementVNode("title",null,[e.renderSlot(t.$slots,"title",{bar:i},()=>[e.createElementVNode("tspan",null,e.toDisplayString(i.staticValue),1)])]),e.createElementVNode("rect",{width:i.width,height:i.height,x:2,y:i.yOffset,style:e.normalizeStyle({fill:i.barColor})},null,12,k),n.showValues?(e.openBlock(),e.createElementBlock("text",{key:0,x:i.midPoint,y:i.yOffset,dy:`${i.height<22?"-5px":"15px"}`,"text-anchor":"middle",style:e.normalizeStyle({fill:i.height<22?i.textColor:i.textAltColor,font:n.textFont})},e.toDisplayString(i.staticValue),13,_)):e.createCommentVNode("",!0),n.showXAxis?(e.openBlock(),e.createElementBlock("g",p,[e.renderSlot(t.$slots,"label",{bar:i,textStyle:{fill:n.textColor,font:n.textFont}},()=>[e.createElementVNode("text",{x:i.midPoint,y:`${i.yLabel+10}px`,"text-anchor":"middle",style:e.normalizeStyle({fill:n.textColor,font:n.textFont})},e.toDisplayString(i.label),13,b)]),e.createElementVNode("line",{x1:i.midPoint,x2:i.midPoint,y1:o.innerChartHeight+3,y2:o.innerChartHeight,stroke:"#555555","stroke-width":"1"},null,8,B)])):e.createCommentVNode("",!0)],8,w))),128)),n.showTrendLine?(e.openBlock(),e.createElementBlock("line",{key:0,x1:o.trendLine.x1,y1:o.trendLine.y1,x2:o.trendLine.x2,y2:o.trendLine.y2,"stroke-width":n.trendLineWidth,stroke:n.trendLineColor},null,8,V)):e.createCommentVNode("",!0)],8,A),n.showXAxis?(e.openBlock(),e.createElementBlock("g",H,[e.createElementVNode("line",{x1:n.showYAxis?o.yAxisWidth-1:2,x2:o.innerChartWidth+o.yAxisWidth,y1:o.innerChartHeight,y2:o.innerChartHeight,stroke:"#555555","stroke-width":"1"},null,8,L)])):e.createCommentVNode("",!0),n.showYAxis?(e.openBlock(),e.createElementBlock("g",P,[e.createElementVNode("line",{x1:o.yAxisWidth-1,x2:o.yAxisWidth-1,y1:o.innerChartHeight,y2:"0",stroke:"#555555","stroke-width":"1"},null,8,S),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.getTicks(),i=>(e.openBlock(),e.createElementBlock("g",{key:i.key},[e.createElementVNode("line",{x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2,stroke:"#555555","stroke-width":"1"},null,8,F),e.createElementVNode("text",{x:"0",y:i.yText,"alignment-baseline":"central",style:e.normalizeStyle({fill:n.textColor,font:n.textFont})},e.toDisplayString(i.text),13,W)]))),128))])):e.createCommentVNode("",!0)],8,C)],8,f)}const y=m(g,[["render",N]]);function c(t){c.installed||(c.installed=!0,t.component("VueBarGraph",y))}const E={install:c};let x=null;typeof window<"u"?x=window.Vue:typeof global<"u"&&(x=global.Vue),x&&x.use(E),h.VueBarGraph=y,h.install=c,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})});