uniApp——调整uniApp插件市场上的echarts插件

2024-08-15 13:59:09 浏览数 (3)

前言

其实插件市场上的也是基于mpvue-echartsecharts来的;

!> 插件中的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中添加下空函数;

代码语言:javascript复制
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
                })
            }
        })
    }
}

0 人点赞