初始化
This commit is contained in:
242
components/echarts-uniapp/echarts-uniapp.vue
Normal file
242
components/echarts-uniapp/echarts-uniapp.vue
Normal file
@@ -0,0 +1,242 @@
|
||||
<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(newValue.series){
|
||||
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);
|
||||
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>
|
||||
26
components/echarts-uniapp/echarts.min.js
vendored
Normal file
26
components/echarts-uniapp/echarts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
105
components/echarts-uniapp/wx-canvas.js
Normal file
105
components/echarts-uniapp/wx-canvas.js
Normal file
@@ -0,0 +1,105 @@
|
||||
export default class WxCanvas {
|
||||
constructor(ctx, canvasId, isNew, canvasNode) {
|
||||
this.ctx = ctx;
|
||||
this.canvasId = canvasId;
|
||||
this.chart = null;
|
||||
this.isNew = isNew
|
||||
if (isNew) {
|
||||
this.canvasNode = canvasNode;
|
||||
}
|
||||
else {
|
||||
this._initStyle(ctx);
|
||||
}
|
||||
|
||||
// this._initCanvas(zrender, ctx);
|
||||
|
||||
this._initEvent();
|
||||
}
|
||||
|
||||
getContext(contextType) {
|
||||
if (contextType === '2d') {
|
||||
return this.ctx;
|
||||
}
|
||||
}
|
||||
|
||||
// canvasToTempFilePath(opt) {
|
||||
// if (!opt.canvasId) {
|
||||
// opt.canvasId = this.canvasId;
|
||||
// }
|
||||
// return wx.canvasToTempFilePath(opt, this);
|
||||
// }
|
||||
|
||||
setChart(chart) {
|
||||
this.chart = chart;
|
||||
}
|
||||
|
||||
attachEvent() {
|
||||
// noop
|
||||
}
|
||||
|
||||
detachEvent() {
|
||||
// noop
|
||||
}
|
||||
|
||||
_initCanvas(zrender, ctx) {
|
||||
zrender.util.getContext = function () {
|
||||
return ctx;
|
||||
};
|
||||
|
||||
zrender.util.$override('measureText', function (text, font) {
|
||||
ctx.font = font || '12px sans-serif';
|
||||
return ctx.measureText(text);
|
||||
});
|
||||
}
|
||||
|
||||
_initStyle(ctx) {
|
||||
ctx.createRadialGradient = () => {
|
||||
return 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.touches[0];
|
||||
this.chart.getZr().handler.dispatch(name.ecName, {
|
||||
zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
|
||||
zrY: name.wxName === 'tap' ? touch.clientY : touch.y
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
set width(w) {
|
||||
if (this.canvasNode) this.canvasNode.width = w
|
||||
}
|
||||
set height(h) {
|
||||
if (this.canvasNode) this.canvasNode.height = h
|
||||
}
|
||||
|
||||
get width() {
|
||||
if (this.canvasNode)
|
||||
return this.canvasNode.width
|
||||
return 0
|
||||
}
|
||||
get height() {
|
||||
if (this.canvasNode)
|
||||
return this.canvasNode.height
|
||||
return 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user