uniapp开发微信小程序中使用echarts
找到node_modules\mpvue-echarts\下的文件,保留src文件夹,其他删除,复制mpvue-echarts文件夹到项目的components中。定制echarts的js文件,然后下载,放到components的common目录下。
·
1、下载依赖:获取mpvue-echarts组件
npm install echarts mpvue-echarts
找到node_modules\mpvue-echarts\下的文件,保留src文件夹,其他删除,复制mpvue-echarts文件夹到项目的components中。
2、获取定制echarts的js文件
在https://echarts.apache.org/zh/builder.html定制echarts的js文件,然后下载,放到components的common目录下。
3、修改components/mpvue-echarts/src下面的文件,不然微信小程序会报错
- echarts.vue
<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/common/echarts.min.js";
function wrapTouch(e) {
for (let i = 0; i < e.mp.touches.length; i += 1) {
const touch = e.mp.touches[i];
touch.offsetX = touch.x;
touch.offsetY = touch.y;
}
return e;
}
export default {
props: {
// echarts: {
// required: true,
// type: Object,
// default() {
// return null;
// },
// },
onInit: {
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;
}
if (!this.lazyLoad) this.init();
},
methods: {
init(callback) {
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'
+ '#%E5%BE%AE%E4%BF%A1%E7%89%88%E6%9C%AC%E8%A6%81%E6%B1%82');
return;
}
// const { canvasId } = this;
// this.ctx = wx.createCanvasContext(canvasId);
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();
const query=wx.createSelectorQuery().in(this);//-----修改------
query.select(`#${canvasId}`).boundingClientRect((res) => {
if (!res) {
setTimeout(() => this.init(), 50);
return;
}
const { width, height } = res;
if (typeof callback === 'function') {
this.chart = callback(canvas, width, height);
} else if (typeof this.onInit === 'function') {
this.chart = this.onInit(canvas, width, height);
}
if (!this.chart) {
return;
}
const { handler } = this.chart.getZr();
this.handler = handler;
this.processGesture = handler.proxy.processGesture || (() => {});
}).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];
this.handler.dispatch('mousedown', {
zrX: touch.x,
zrY: touch.y,
});
this.handler.dispatch('mousemove', {
zrX: touch.x,
zrY: touch.y,
});
this.processGesture(wrapTouch(e), 'start');
},
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];
this.handler.dispatch('mousemove', {
zrX: touch.x,
zrY: touch.y,
});
this.processGesture(wrapTouch(e), 'change');
},
touchEnd(e) {
const { disableTouch, chart } = this;
if (disableTouch || !chart) return;
const touch = e.mp.changedTouches ? e.mp.changedTouches[0] : {};
this.handler.dispatch('mouseup', {
zrX: touch.x,
zrY: touch.y,
});
this.handler.dispatch('click', {
zrX: touch.x,
zrY: touch.y,
});
this.processGesture(wrapTouch(e), 'end');
},
},
};
</script>
<style scoped>
.ec-canvas {
width: 100%;
height: 100%;
}
</style>
- wx-canvas.js
export default class WxCanvas {
constructor(ctx, canvasId) {
this.ctx = ctx;
this.canvasId = canvasId;
this.chart = null;
WxCanvas.initStyle(ctx);
this.initEvent();
}
// 新增空函数,修复调用 echarts.init 时报错
addEventListener() {}
getContext(contextType) {
return contextType === '2d' ? this.ctx : null;
}
setChart(chart) {
this.chart = chart;
}
attachEvent() {
// noop
}
detachEvent() {
// noop
}
static initStyle(ctx) {
const styles = ['fillStyle', 'strokeStyle', 'globalAlpha',
'textAlign', 'textBaseAlign', 'shadow', 'lineWidth',
'lineCap', 'lineJoin', 'lineDash', 'miterLimit', 'fontSize'];
styles.forEach((style) => {
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.getZr().handler.dispatch(name.ecName, {
zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
zrY: name.wxName === 'tap' ? touch.clientY : touch.y,
});
};
});
}
}
4、页面使用
<template>
<view class="echarts-wrap">
<my-echarts
id="main"
canvasId="line"
:onInit="initChart"
/>
</view>
</template>
<script>
import * as echarts from "@/components/common/echarts.min.js"; //这里根据自己存放的路径修改
import myEcharts from "@/components/mpvue-echarts/src/echarts.vue"; //这里根据自己存放的路径修改
let chart = null //放外层方便拿到echart实例,如果放在data里面就会不显示tooltip
export default {
components: {
myEcharts,
},
data() {
return {
echarts
};
},
onReady() {},
mounted() {},
methods: {
initChart(canvas, width, height) {
chart = echarts.init(canvas, null, {
width: width,
height: height
})
canvas.setChart(chart)
let option = {
animation: true,
backgroundColor: '#ffffff',
color: ['#257DFF', '#9CD113', '#FF5C37'],
grid: {
left: 35,
top: 35,
bottom: 24
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: [
{
type: 'value',
splitLine: {
lineStyle: {
color: '#E8E8E8'
}
}
}
],
yAxis: [
{
type: 'category',
data: [
'四川',
'河北',
'深圳',
'陕西',
'广州',
'山东',
'上海'
],
axisLabel: {
margin: 2,
rich: {
value: {
lineHeight: 30,
align: 'center'
},
四川: {
height: 30,
align: 'center'
},
河北: {
height: 30,
align: 'center'
},
深圳: {
height: 30,
align: 'center'
},
陕西: {
height: 30,
align: 'center'
},
广州: {
height: 30,
align: 'center'
},
山东: {
height: 30,
align: 'center'
},
上海: {
height: 30,
align: 'center'
}
}
}
}
],
legend: {
itemWidth: 11,
itemHeight: 11,
width: '100%',
data: ['本月成交客户数', '本月跟进客户数', '本月新增客户数']
},
series: [
{
name: '本月成交客户数',
type: 'bar',
data: [100, 200, 300, 400, 500, 800, 1000]
},
{
name: '本月跟进客户数',
type: 'bar',
data: [2000, 2500, 1500, 1500, 1000, 1800, 2000]
},
{
name: '本月新增客户数',
type: 'bar',
data: [100, 150, 300, 130, 120, 110, 300]
}
]
}
chart.setOption(option)
return chart // 返回 chart 后可以自动绑定触摸操作
},
},
};
</script>
<style>
.echarts-wrap {
width: 100%;
height: 300px;
}
</style>
更多推荐
所有评论(0)