You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
6.2 KiB
247 lines
6.2 KiB
2 years ago
|
<template>
|
||
|
<!-- #ifdef MP-WEIXIN || MP-TOUTIAO -->
|
||
|
<canvas type="2d" class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart"
|
||
|
@touchmove="touchMove" @touchend="touchEnd" />
|
||
|
<!-- #endif -->
|
||
|
<!-- #ifndef MP-WEIXIN || MP-TOUTIAO -->
|
||
|
<canvas class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart" @touchmove="touchMove"
|
||
|
@touchend="touchEnd" />
|
||
|
<!-- #endif -->
|
||
|
|
||
|
</template>
|
||
|
<script>
|
||
|
|
||
|
/**
|
||
|
* echartsForUniApp echart兼容uni-app
|
||
|
* @description echart兼容uni-app
|
||
|
* @property {Object} option 图表数据
|
||
|
* @property {String} canvasId 画布id
|
||
|
* @example <echarts ref="echarts" :option="option" canvasId="echarts"></echarts>
|
||
|
*/
|
||
|
import WxCanvas from './wx-canvas.js';
|
||
|
import * as echarts from './echarts.min.js';
|
||
|
|
||
|
var chartList = {}
|
||
|
export default {
|
||
|
props: {
|
||
|
canvasId: {
|
||
|
type: String,
|
||
|
default: 'echarts'
|
||
|
},
|
||
|
option: {
|
||
|
type: Object,
|
||
|
default: () => {
|
||
|
return {}
|
||
|
}
|
||
|
},
|
||
|
},
|
||
|
watch: {
|
||
|
option(newValue, oldValue) {
|
||
|
if(Object.keys(newValue).length){
|
||
|
this.initChart(newValue)
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
data() {
|
||
|
return {
|
||
|
ctx:null
|
||
|
}
|
||
|
},
|
||
|
|
||
|
mounted() {
|
||
|
// Disable prograssive because drawImage doesn't support DOM as parameter
|
||
|
// See https://developers.weixin.qq.com/miniprogram/dev/api/canvas/CanvasContext.drawImage.html
|
||
|
echarts.registerPreprocessor(option => {
|
||
|
if (option && option.series) {
|
||
|
if (option.series.length > 0) {
|
||
|
option.series.forEach(series => {
|
||
|
series.progressive = 0;
|
||
|
});
|
||
|
} else if (typeof option.series === 'object') {
|
||
|
option.series.progressive = 0;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
},
|
||
|
|
||
|
methods: {
|
||
|
getCanvasAttr2d() {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
const query = uni.createSelectorQuery().in(this)
|
||
|
query
|
||
|
.select('#' + this.canvasId)
|
||
|
.fields({
|
||
|
node: true,
|
||
|
size: true
|
||
|
})
|
||
|
.exec(res => {
|
||
|
const canvasNode = res[0].node
|
||
|
this.canvasNode = canvasNode
|
||
|
const canvasDpr = uni.getSystemInfoSync().pixelRatio
|
||
|
const canvasWidth = res[0].width
|
||
|
const canvasHeight = res[0].height
|
||
|
this.ctx = canvasNode.getContext('2d')
|
||
|
|
||
|
const canvas = new WxCanvas(this.ctx, this.canvasId, true, canvasNode)
|
||
|
echarts.setCanvasCreator(() => {
|
||
|
return canvas
|
||
|
})
|
||
|
resolve({
|
||
|
canvas,
|
||
|
canvasWidth,
|
||
|
canvasHeight,
|
||
|
canvasDpr
|
||
|
})
|
||
|
})
|
||
|
});
|
||
|
},
|
||
|
getCanvasAttr() {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
this.ctx = uni.createCanvasContext(this.canvasId, this);
|
||
|
var canvas = new WxCanvas(this.ctx, this.canvasId, false);
|
||
|
echarts.setCanvasCreator(() => {
|
||
|
return canvas;
|
||
|
});
|
||
|
const canvasDpr = 1
|
||
|
var query = uni.createSelectorQuery()
|
||
|
// #ifndef MP-ALIPAY
|
||
|
.in(this)
|
||
|
// #endif
|
||
|
query.select('#' + this.canvasId).boundingClientRect(res => {
|
||
|
const canvasWidth = res.width
|
||
|
const canvasHeight = res.height
|
||
|
resolve({
|
||
|
canvas,
|
||
|
canvasWidth,
|
||
|
canvasHeight,
|
||
|
canvasDpr
|
||
|
})
|
||
|
}).exec();
|
||
|
});
|
||
|
},
|
||
|
// #ifdef H5
|
||
|
//H5绘制图表
|
||
|
initChart(option) {
|
||
|
this.ctx = uni.createCanvasContext(this.canvasId, this);
|
||
|
if (chartList[this.canvasId]) {
|
||
|
chartList[this.canvasId].dispose()
|
||
|
chartList[this.canvasId] = null
|
||
|
}
|
||
|
chartList[this.canvasId] = echarts.init(document.getElementById(this.canvasId));
|
||
|
chartList[this.canvasId].setOption(option?option:this.option);
|
||
|
},
|
||
|
//H5生成图片
|
||
|
canvasToTempFilePath(opt) {
|
||
|
const base64 = chartList[this.canvasId].getDataURL()
|
||
|
opt.success && opt.success({tempFilePath:base64})
|
||
|
},
|
||
|
// #endif
|
||
|
// #ifndef H5
|
||
|
//绘制图表
|
||
|
async initChart(option) {
|
||
|
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||
|
const canvasAttr = await this.getCanvasAttr2d();
|
||
|
// #endif
|
||
|
// #ifndef MP-WEIXIN || MP-TOUTIAO
|
||
|
const canvasAttr = await this.getCanvasAttr();
|
||
|
// #endif
|
||
|
const {
|
||
|
canvas,
|
||
|
canvasWidth,
|
||
|
canvasHeight,
|
||
|
canvasDpr
|
||
|
} = canvasAttr
|
||
|
chartList[this.canvasId] = echarts.init(canvas, null, {
|
||
|
width: canvasWidth,
|
||
|
height: canvasHeight,
|
||
|
devicePixelRatio: canvasDpr // new
|
||
|
});
|
||
|
canvas.setChart(chartList[this.canvasId]);
|
||
|
chartList[this.canvasId].setOption(option?option:this.option);
|
||
|
},
|
||
|
//生成图片
|
||
|
canvasToTempFilePath(opt) {
|
||
|
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||
|
var query = uni.createSelectorQuery()
|
||
|
// #ifndef MP-ALIPAY
|
||
|
.in(this)
|
||
|
// #endif
|
||
|
query.select('#' + this.canvasId).fields({ node: true, size: true }).exec(res => {
|
||
|
const canvasNode = res[0].node
|
||
|
opt.canvas = canvasNode
|
||
|
uni.canvasToTempFilePath(opt, this)
|
||
|
})
|
||
|
// #endif
|
||
|
// #ifndef MP-WEIXIN || MP-TOUTIAO
|
||
|
if (!opt.canvasId) {
|
||
|
opt.canvasId = this.canvasId;
|
||
|
}
|
||
|
this.ctx.draw(true, () => {
|
||
|
uni.canvasToTempFilePath(opt, this);
|
||
|
});
|
||
|
// #endif
|
||
|
},
|
||
|
// #endif
|
||
|
|
||
|
touchStart(e) {
|
||
|
if (chartList[this.canvasId] && e.touches.length > 0) {
|
||
|
var touch = e.touches[0];
|
||
|
var handler = chartList[this.canvasId].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');
|
||
|
}
|
||
|
},
|
||
|
touchMove(e) {
|
||
|
if (chartList[this.canvasId] && e.touches.length > 0) {
|
||
|
var touch = e.touches[0];
|
||
|
var handler = chartList[this.canvasId].getZr().handler;
|
||
|
handler.dispatch('mousemove', {
|
||
|
zrX: touch.x,
|
||
|
zrY: touch.y
|
||
|
});
|
||
|
handler.processGesture(wrapTouch(e), 'change');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
touchEnd(e) {
|
||
|
if (chartList[this.canvasId]) {
|
||
|
const touch = e.changedTouches ? e.changedTouches[0] : {};
|
||
|
var handler = chartList[this.canvasId].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');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function wrapTouch(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;
|
||
|
}
|
||
|
</script>
|
||
|
<style lang="scss" scoped>
|
||
|
.echarts {
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
</style>
|