|
|
@@ -1,258 +0,0 @@
|
|
|
-<template>
|
|
|
- <!-- #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO -->
|
|
|
- <canvas type="2d" class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" />
|
|
|
- <!-- #endif -->
|
|
|
- <!-- #ifndef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO -->
|
|
|
- <canvas class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" />
|
|
|
- <!-- #endif -->
|
|
|
-</template>
|
|
|
-<script setup>
|
|
|
-/**
|
|
|
- * vue3 echarts 兼容uni-app
|
|
|
- * @description vue3 echart兼容uni-app
|
|
|
- * @property {Object} options 图表配置数据
|
|
|
- * @property {String} canvasId 画布id
|
|
|
- * @example <vue3-echarts ref="echarts" :options="options" canvasId="echarts"></vue3-echarts>
|
|
|
- */
|
|
|
-import WxCanvas from './wx-canvas.js';
|
|
|
-// import echarts from "./echarts" //按需引入
|
|
|
-import * as echarts from 'echarts';
|
|
|
-import { ref, watch, nextTick, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue';
|
|
|
-const instance = getCurrentInstance();
|
|
|
-const exposeObj = {}; // 导出组件方法、echart实例
|
|
|
-var chartInstance;
|
|
|
-const props = defineProps({
|
|
|
- canvasId: {
|
|
|
- type: String,
|
|
|
- default: 'echarts'
|
|
|
- },
|
|
|
- options: {
|
|
|
- type: Object,
|
|
|
- default: () => {
|
|
|
- return {};
|
|
|
- }
|
|
|
- }
|
|
|
-});
|
|
|
-const emits = defineEmits(['click']);
|
|
|
-let ctx = null;
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- echarts.registerPreprocessor(options => {
|
|
|
- if (options && options.series) {
|
|
|
- if (options.series.length > 0) {
|
|
|
- options.series.forEach(series => {
|
|
|
- series.progressive = 0;
|
|
|
- });
|
|
|
- } else if (typeof options.series === 'object') {
|
|
|
- options.series.progressive = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-onBeforeUnmount(() => {
|
|
|
- chartInstance && chartInstance.dispose();
|
|
|
-});
|
|
|
-
|
|
|
-// #ifdef H5
|
|
|
-//H5绘制图表
|
|
|
-const initChart = options => {
|
|
|
- ctx = uni.createCanvasContext(props.canvasId, instance);
|
|
|
- chartInstance = echarts.init(document.getElementById(props.canvasId));
|
|
|
- chartInstance.clear();
|
|
|
- chartInstance.setOption(options ? options : props.options);
|
|
|
- chartInstance.on('click', function(params) {
|
|
|
- emits('click', params);
|
|
|
- });
|
|
|
- exposeObj.chart = chartInstance;
|
|
|
-};
|
|
|
-//H5生成图片
|
|
|
-const canvasToTempFilePath = opt => {
|
|
|
- const base64 = chartInstance.getDataURL();
|
|
|
- opt.success && opt.success({ tempFilePath: base64 });
|
|
|
-};
|
|
|
-exposeObj.canvasToTempFilePath = canvasToTempFilePath;
|
|
|
-// #endif
|
|
|
-// #ifndef H5
|
|
|
-//绘制图表
|
|
|
-const initChart = async options => {
|
|
|
- // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
|
|
- const canvasAttr = await getCanvasAttr2d();
|
|
|
- // #endif
|
|
|
- // #ifndef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
|
|
- const canvasAttr = await getCanvasAttr();
|
|
|
- // #endif
|
|
|
- const { canvas, canvasWidth, canvasHeight, canvasDpr } = canvasAttr;
|
|
|
- chartInstance = echarts.init(canvas, null, {
|
|
|
- width: canvasWidth,
|
|
|
- height: canvasHeight,
|
|
|
- devicePixelRatio: canvasDpr // new
|
|
|
- });
|
|
|
- canvas.setChart(chartInstance);
|
|
|
- chartInstance.clear();
|
|
|
- chartInstance.setOption(options ? options : props.options);
|
|
|
- chartInstance.on('click', function(params) {
|
|
|
- emits('click', params);
|
|
|
- });
|
|
|
- exposeObj.chart = chartInstance;
|
|
|
-};
|
|
|
-//生成图片
|
|
|
-const canvasToTempFilePath = opt => {
|
|
|
- // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
|
|
- var query = uni
|
|
|
- .createSelectorQuery()
|
|
|
- // #ifndef MP-ALIPAY
|
|
|
- .in(instance);
|
|
|
- // #endif
|
|
|
- query
|
|
|
- .select('#' + props.canvasId)
|
|
|
- .fields({ node: true, size: true })
|
|
|
- .exec(res => {
|
|
|
- const canvasNode = res[0].node;
|
|
|
- opt.canvas = canvasNode;
|
|
|
- uni.canvasToTempFilePath(opt, instance);
|
|
|
- });
|
|
|
- // #endif
|
|
|
- // #ifndef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
|
|
- if (!opt.canvasId) {
|
|
|
- opt.canvasId = props.canvasId;
|
|
|
- }
|
|
|
- ctx.draw(true, () => {
|
|
|
- uni.canvasToTempFilePath(opt, instance);
|
|
|
- });
|
|
|
- // #endif
|
|
|
-};
|
|
|
-exposeObj.canvasToTempFilePath = canvasToTempFilePath;
|
|
|
-// #endif
|
|
|
-
|
|
|
-const getCanvasAttr2d = function() {
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- const query = uni.createSelectorQuery().in(instance);
|
|
|
- query
|
|
|
- .select('#' + props.canvasId)
|
|
|
- .fields({
|
|
|
- node: true,
|
|
|
- size: true
|
|
|
- })
|
|
|
- .exec(res => {
|
|
|
- const canvasNode = res[0].node;
|
|
|
- const canvasDpr = uni.getSystemInfoSync().pixelRatio;
|
|
|
- const canvasWidth = res[0].width;
|
|
|
- const canvasHeight = res[0].height;
|
|
|
- ctx = canvasNode.getContext('2d');
|
|
|
-
|
|
|
- const canvas = new WxCanvas(ctx, props.canvasId, true, canvasNode);
|
|
|
- echarts.setCanvasCreator(() => {
|
|
|
- return canvas;
|
|
|
- });
|
|
|
- resolve({
|
|
|
- canvas,
|
|
|
- canvasWidth,
|
|
|
- canvasHeight,
|
|
|
- canvasDpr
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-const getCanvasAttr = function() {
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- ctx = uni.createCanvasContext(props.canvasId, instance);
|
|
|
- var canvas = new WxCanvas(ctx, props.canvasId, false);
|
|
|
- echarts.setCanvasCreator(() => {
|
|
|
- return canvas;
|
|
|
- });
|
|
|
- const canvasDpr = 1;
|
|
|
- var query = uni
|
|
|
- .createSelectorQuery()
|
|
|
- // #ifndef MP-ALIPAY
|
|
|
- .in(instance);
|
|
|
- // #endif
|
|
|
- query
|
|
|
- .select('#' + props.canvasId)
|
|
|
- .boundingClientRect(res => {
|
|
|
- const canvasWidth = res.width;
|
|
|
- const canvasHeight = res.height;
|
|
|
- resolve({
|
|
|
- canvas,
|
|
|
- canvasWidth,
|
|
|
- canvasHeight,
|
|
|
- canvasDpr
|
|
|
- });
|
|
|
- })
|
|
|
- .exec();
|
|
|
- });
|
|
|
-};
|
|
|
-const touchStart = e => {
|
|
|
- if (chartInstance && e.touches.length > 0) {
|
|
|
- var touch = e.touches[0];
|
|
|
- var handler = chartInstance.getZr().handler;
|
|
|
- handler.dispatch('mousedown', {
|
|
|
- zrX: touch.x,
|
|
|
- zrY: touch.y
|
|
|
- });
|
|
|
- handler.dispatch('mousemove', {
|
|
|
- zrX: touch.x,
|
|
|
- zrY: touch.y
|
|
|
- });
|
|
|
- handler.processGesture(wrapTouch(e), 'start');
|
|
|
- }
|
|
|
-};
|
|
|
-const touchMove = e => {
|
|
|
- if (chartInstance && e.touches.length > 0) {
|
|
|
- var touch = e.touches[0];
|
|
|
- var handler = chartInstance.getZr().handler;
|
|
|
- handler.dispatch('mousemove', {
|
|
|
- zrX: touch.x,
|
|
|
- zrY: touch.y
|
|
|
- });
|
|
|
- handler.processGesture(wrapTouch(e), 'change');
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const touchEnd = e => {
|
|
|
- if (chartInstance) {
|
|
|
- const touch = e.changedTouches ? e.changedTouches[0] : {};
|
|
|
- var handler = chartInstance.getZr().handler;
|
|
|
- handler.dispatch('mouseup', {
|
|
|
- zrX: touch.x,
|
|
|
- zrY: touch.y
|
|
|
- });
|
|
|
- handler.dispatch('click', {
|
|
|
- zrX: touch.x,
|
|
|
- zrY: touch.y
|
|
|
- });
|
|
|
- handler.processGesture(wrapTouch(e), 'end');
|
|
|
- }
|
|
|
-};
|
|
|
-const wrapTouch = function(event) {
|
|
|
- for (let i = 0; i < event.touches.length; ++i) {
|
|
|
- const touch = event.touches[i];
|
|
|
- touch.offsetX = touch.x;
|
|
|
- touch.offsetY = touch.y;
|
|
|
- }
|
|
|
- return event;
|
|
|
-};
|
|
|
-
|
|
|
-watch(
|
|
|
- () => props.options,
|
|
|
- (newValue, oldValue) => {
|
|
|
- if (newValue.series) {
|
|
|
- nextTick(() => {
|
|
|
- initChart(newValue);
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- deep: true,
|
|
|
- immediate: true
|
|
|
- }
|
|
|
-);
|
|
|
-defineExpose(exposeObj); //导出组件方法、echart实例
|
|
|
-</script>
|
|
|
-<style lang="scss" scoped>
|
|
|
-.echarts {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
-}
|
|
|
-</style>
|