我们有时候会有这样的需求绘制一个环形图百度的Echart太重,又不想在vue的package.json中引入依赖
经过对vue-schart的研究将其精简为一个组件放入项目中引用,分享一下经验希望对大家有帮助
我们新建一个vue组件
在template中
<canvas :id="canvasId" :width="width" :height="height"></canvas>
data,此处我将圆环ring 柱状图bar 折线图line 饼状图pie 的所有数据都填入了,下面只展示绘制圆环的代码
return { canvas: '', ctx: '', totalValue: '' }prop验证
props: { canvasId: { type: String, default: '' }, width: { type: [String, Number], default: '' }, height: { type: [String, Number], default: '' }, type: { type: String, default: 'ring' // 圆环ring 柱状图bar 折线图 line 饼状pie }, data: { // 存放图表数据 type: Array, default: [] }, options: { type: Object, required: false }
在mounted函数中调用绘制函数
mounted () {在methods中绘制this.sChart(this.canvasId, this.type, this.data, this.options)}
sChart (canvas, type, data, options) { this.canvas = document.getElementById(canvas) this.ctx = this.canvas.getContext('2d') this.type = type this.data = data // 存放图表数据 this.dataLength = this.data.length // 图表数据的长度 this.totalValue = this.getTotalValue() // 获取饼图数据总和 this.init(options) }, init: function (options) { if (this.dataLength === 0) { return false } if (options) { for (var key in options) { if (key === 'colorList' && Array.isArray(options[key])) { this[key] = options[key].concat(this[key]) } else { this[key] = options[key] } } } this.drawPieUpdate() },
此处我去掉了原有的折线
/** * 绘制完整的饼状图或环形图 */ drawPieUpdate: function () { this.ctx.fillStyle = this.bgColor this.ctx.fillRect(0, 0, this.width, this.height) this.drawPieChart() },核心代码
drawPieChart: function () { let x = this.width / 2 let y = this.height / 2 for (var i = 0; i < this.dataLength; i++) { this.ctx.beginPath() this.ctx.fillStyle = this.colorList[i] this.ctx.moveTo(x, y) this.data[i].start = i === 0 ? -Math.PI / 2 : this.data[i - 1].end this.data[i].end = this.data[i].start + this.data[i].value / this.totalValue * 2 * Math.PI // 绘制扇形 this.ctx.arc(x, y, this.radius, this.data[i].start, this.data[i].end) this.ctx.closePath() this.ctx.fill() this.data[i].middle = (this.data[i].start + this.data[i].end) / 2 this.ctx.strokeStyle = this.colorList[i] } // 如果类型是环形图,绘制一个内圆 if (this.type === 'ring') { this.ctx.beginPath() this.ctx.fillStyle = this.bgColor this.ctx.arc(x, y, this.innerRadius, 0, Math.PI * 2) this.ctx.fill() } },
/** * 获取饼状或环形图的数据总和 * @return {Number} total */ getTotalValue () { var total = 0 for (var i = 0; i < this.dataLength; i++) { total += this.data[i].value } return total }至此绘制一个环形图核心代码完成
调用方法
import引入
import schart from './drawRing.vue'调用
<schart :canvasId="canvasData.canvasId" :type="canvasData.type" :width="canvasData.width" :height="canvasData.height" :data="canvasData.data" :options="canvasData.options" ></schart>初始数据
canvasData: { canvasId: 'myCanvas', type: 'ring', width: 84, height: 84, data: [ { name: 'availableLimit', value: 2000 }, { name: 'creditLimit', value: 2000 } ], options: { bgColor: '#e3e3e3', // 默认背景颜色 #e3e3e3 titlePosition: 'top', // 图表标题位置: top / bottom colorList: ['#666666', '#ad2500'], // 环形图颜色列表 radius: 42, // 环形图外圆半径 innerRadius: 26 // 环形图内圆半径 }
如果你想绘制折线图饼图柱状图可参考http://open.omwteam.com/sChart/