/**
|
* CECharts
|
* @author Tevin
|
*/
|
|
<template>
|
<view class="c-echarts">
|
<canvas
|
class="c-echarts-canvas"
|
type="2d"
|
:id="canvasId"
|
:canvasId="canvasId"
|
@touchstart="evt => disableTouch ? null : touchStart(evt)"
|
@touchmove="evt => disableTouch ? null : touchMove(evt)"
|
@touchend="evt => disableTouch ? null : touchEnd(evt)"
|
></canvas>
|
</view>
|
</template>
|
|
<script>
|
import WxCanvas from './wxCanvas';
|
import * as echarts from './echarts';
|
import './cECharts.scss';
|
|
let canvasCount = 0;
|
const 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;
|
};
|
|
export default {
|
name: 'CECharts',
|
components: {},
|
props: {
|
canvasId: {
|
type: String,
|
default: () =>
|
'ec-canvas-' + ++canvasCount + '-' + parseInt(Math.random() * 10000),
|
},
|
disableTouch: {
|
type: Boolean,
|
default: false,
|
},
|
onReady: Function,
|
},
|
data() {
|
return {};
|
},
|
methods: {
|
init(callback) {
|
// 基础库必须 2.9.0 以上,使用 <canvas type="2d"></canvas>,不支持旧版
|
const query = wx.createSelectorQuery();
|
query
|
.select('#' + this.canvasId)
|
.fields({ node: true, size: true })
|
.exec(res => {
|
const canvasNode = res[0].node;
|
this.canvasNode = canvasNode;
|
const canvasDpr = wx.getSystemInfoSync().pixelRatio;
|
const canvasWidth = res[0].width;
|
const canvasHeight = res[0].height;
|
const ctx = canvasNode.getContext('2d');
|
const canvas = new WxCanvas(ctx, this.canvasId, true, canvasNode);
|
echarts.setCanvasCreator(() => {
|
return canvas;
|
});
|
if (typeof callback === 'function') {
|
callback(canvas, canvasWidth, canvasHeight, canvasDpr);
|
} else {
|
this.triggerEvent('init', {
|
canvas: canvas,
|
width: canvasWidth,
|
height: canvasHeight,
|
dpr: canvasDpr,
|
});
|
}
|
});
|
},
|
canvasToTempFilePath(opt) {
|
const query = wx.createSelectorQuery().in(this);
|
query
|
.select('#' + this.canvasId)
|
.fields({ node: true, size: true })
|
.exec(res => {
|
const canvasNode = res[0].node;
|
opt.canvas = canvasNode;
|
wx.canvasToTempFilePath(opt);
|
});
|
},
|
touchStart(e) {
|
if (this.chart && e.touches.length > 0) {
|
const touch = e.touches[0];
|
const handler = this.chart.getZr().handler;
|
handler.dispatch('mousedown', {
|
zrX: touch.x,
|
zrY: touch.y,
|
preventDefault: () => {},
|
stopImmediatePropagation: () => {},
|
stopPropagation: () => {},
|
});
|
handler.dispatch('mousemove', {
|
zrX: touch.x,
|
zrY: touch.y,
|
preventDefault: () => {},
|
stopImmediatePropagation: () => {},
|
stopPropagation: () => {},
|
});
|
handler.processGesture(wrapTouch(e), 'start');
|
}
|
},
|
touchMove(e) {
|
if (this.chart && e.touches.length > 0) {
|
const touch = e.touches[0];
|
const handler = this.chart.getZr().handler;
|
handler.dispatch('mousemove', {
|
zrX: touch.x,
|
zrY: touch.y,
|
preventDefault: () => {},
|
stopImmediatePropagation: () => {},
|
stopPropagation: () => {},
|
});
|
handler.processGesture(wrapTouch(e), 'change');
|
}
|
},
|
touchEnd(e) {
|
if (this.chart) {
|
const touch = e.changedTouches ? e.changedTouches[0] : {};
|
const handler = this.chart.getZr().handler;
|
handler.dispatch('mouseup', {
|
zrX: touch.x,
|
zrY: touch.y,
|
preventDefault: () => {},
|
stopImmediatePropagation: () => {},
|
stopPropagation: () => {},
|
});
|
handler.dispatch('click', {
|
zrX: touch.x,
|
zrY: touch.y,
|
preventDefault: () => {},
|
stopImmediatePropagation: () => {},
|
stopPropagation: () => {},
|
});
|
handler.processGesture(wrapTouch(e), 'end');
|
}
|
},
|
},
|
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;
|
}
|
}
|
});
|
setTimeout(() => {
|
this.init((canvas, width, height, dpr) => {
|
this.chart = echarts.init(canvas, null, {
|
width: width,
|
height: height,
|
devicePixelRatio: dpr, // 像素
|
});
|
canvas.setChart(this.chart);
|
this.onReady && this.onReady(this.chart);
|
this.chart.setOption({
|
tooltip: {
|
backgroundColor: 'rgba(50,50,50,0.7)',
|
textStyle: {
|
color: '#ffffff',
|
},
|
// 重新修正浮窗位置
|
position: (pos, params, dom, rect, size) => {
|
const [pX, pY] = pos;
|
const [contX, contY] = size.contentSize;
|
const [viewX, viewY] = size.viewSize;
|
const contentPoint = {};
|
// 鼠标在左侧时 tooltip 显示到右侧
|
if (pX < viewX / 2) {
|
contentPoint.right = Math.max(viewX - pX - contX, 0);
|
}
|
// 鼠标在右侧时 tooltip 显示到左侧。
|
else {
|
contentPoint.left = Math.max(pX - contX, 0);
|
}
|
// 限制不超过底部边界
|
if (pY + contY <= viewY) {
|
contentPoint.top = pY;
|
} else {
|
contentPoint.top = viewY - contY;
|
}
|
return contentPoint;
|
},
|
},
|
});
|
});
|
}, 100);
|
},
|
};
|
</script>
|