前言
其实插件市场上的也是基于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
代码语言:javascript复制<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'
'#微信版本要求'
)
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)
?> 解决后的代码
代码语言:javascript复制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
})
}
})
}
}