前言
其实插件市场上的也是基于mpvue-echarts
和echarts
来的;
!> 插件中的echarts.js
比较大,建议根据实际需求进行定制,然后替换下;
uniApp plugin
: https://ext.dcloud.net.cn/plugin?id=46
echarts builder
: https://echarts.apache.org/zh/builder.html
内容
?> 只需要修改下echarts.vue
即可
echarts.vue
<template> <canvas v-if="canvasId" class="ec-canvas" :id="canvasId" :canvasId="canvasId" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error"></canvas> </template> <script> import WxCanvas from './wx-canvas' import * as echarts from '@/components/echarts/echarts.simple.min.js' export default { props: { onInit: { required: true, type: Function, default: null }, canvasId: { type: String, default: 'ec-canvas' }, lazyLoad: { type: Boolean, default: false }, disableTouch: { type: Boolean, default: false }, throttleTouch: { type: Boolean, default: false } }, onReady() { this.echarts = echarts if (!this.echarts) { console.warn( '组件需绑定 echarts 变量,例:<ec-canvas id="mychart-dom-bar" ' + 'canvas-id="mychart-bar" :echarts="echarts"></ec-canvas>' ) return } console.log('echarts') console.log(this.onInit) if (!this.lazyLoad) this.init() }, methods: { init() { const version = wx.version.version.split('.').map((n) => parseInt(n, 10)) const isValid = version[0] > 1 || (version[0] === 1 && version[1] > 9) || (version[0] === 1 && version[1] === 9 && version[2] >= 91) if (!isValid) { console.error( '微信基础库版本过低,需大于等于 1.9.91。' + '参见:https://github.com/ecomfe/echarts-for-weixin' + '#%E5%BE%AE%E4%BF%A1%E7%89%88%E6%9C%AC%E8%A6%81%E6%B1%82' ) return } if (!this.onInit) { console.warn('请传入 onInit 函数进行初始化') return } const canvasId = this.canvasId this.ctx = wx.createCanvasContext(canvasId, this) const canvas = new WxCanvas(this.ctx, canvasId) this.echarts.setCanvasCreator(() => canvas) const query = wx.createSelectorQuery().in(this) query .select(`#${canvasId}`) .boundingClientRect((res) => { if (!res) { //setTimeout(() => this.init(), 200); return } this.chart = this.onInit(canvas, res.width, res.height) }) .exec() }, canvasToTempFilePath(opt) { const { canvasId } = this this.ctx.draw(true, () => { wx.canvasToTempFilePath({ canvasId, ...opt }) }) }, touchStart(e) { const { disableTouch, chart } = this if (disableTouch || !chart || !e.mp.touches.length) return const touch = e.mp.touches[0] chart._zr.handler.dispatch('mousedown', { zrX: touch.x, zrY: touch.y }) chart._zr.handler.dispatch('mousemove', { zrX: touch.x, zrY: touch.y }) }, touchMove(e) { const { disableTouch, throttleTouch, chart, lastMoveTime } = this if (disableTouch || !chart || !e.mp.touches.length) return if (throttleTouch) { const currMoveTime = Date.now() if (currMoveTime - lastMoveTime < 240) return this.lastMoveTime = currMoveTime } const touch = e.mp.touches[0] chart._zr.handler.dispatch('mousemove', { zrX: touch.x, zrY: touch.y }) }, touchEnd(e) { const { disableTouch, chart } = this if (disableTouch || !chart) return const touch = e.mp.changedTouches ? e.mp.changedTouches[0] : {} chart._zr.handler.dispatch('mouseup', { zrX: touch.x, zrY: touch.y }) chart._zr.handler.dispatch('click', { zrX: touch.x, zrY: touch.y }) } } } </script> <style scoped> .ec-canvas { width: 100vw; height: 30vh; // 我这就一个饼图所以不做传值了 flex: 1; } </style>
报错
TypeError: t.addEventListener is not a function
!> 使用当前最新版本5.4.1
的时候出现了报错,根据报错内容可以知道是缺少了addEventListener
函数,所以我们在wx-canvas.js
中添加下空函数;
TypeError: t.addEventListener is not a function at Oe (echarts.min.js:1) at gi (echarts.min.js:1) at echarts.min.js:1 at Array.forEach (<anonymous>) at v (echarts.min.js:1) at fi (echarts.min.js:1) at new n (echarts.min.js:8) at new t (echarts.min.js:8) at zi (echarts.min.js:1) at new n (echarts.min.js:11)(env: macOS,mp,1.06.2210310; lib: 2.28.1)
?> 解决后的代码
export default class WxCanvas { constructor(ctx, canvasId) { this.ctx = ctx this.canvasId = canvasId this.chart = null WxCanvas.initStyle(ctx) this.initEvent() } getContext(contextType) { return contextType === '2d' ? this.ctx : null } setChart(chart) { this.chart = chart } addEventListener() { // noop } attachEvent() { // noop } detachEvent() { // noop } static initStyle(ctx) { const styles = [ 'fillStyle', 'strokeStyle', 'globalAlpha', 'textAlign', 'textBaseAlign', 'shadow', 'lineWidth', 'lineCap', 'lineJoin', 'lineDash', 'miterLimit', 'fontSize' ] styles.forEach((style) => { // eslint-disable-next-line accessor-pairs Object.defineProperty(ctx, style, { set: (value) => { if ( (style !== 'fillStyle' && style !== 'strokeStyle') || (value !== 'none' && value !== null) ) { ctx[`set${style.charAt(0).toUpperCase()}${style.slice(1)}`](value) } } }) }) ctx.createRadialGradient = () => ctx.createCircularGradient(arguments) } initEvent() { this.event = {} const eventNames = [ { wxName: 'touchStart', ecName: 'mousedown' }, { wxName: 'touchMove', ecName: 'mousemove' }, { wxName: 'touchEnd', ecName: 'mouseup' }, { wxName: 'touchEnd', ecName: 'click' } ] eventNames.forEach((name) => { this.event[name.wxName] = (e) => { const touch = e.mp.touches[0] this.chart._zr.handler.dispatch(name.ecName, { zrX: name.wxName === 'tap' ? touch.clientX : touch.x, zrY: name.wxName === 'tap' ? touch.clientY : touch.y }) } }) } }
学无止境,谦卑而行.