1、注意事项
1) 下载包 npm install echarts mpvue-echarts --save 下载成功后在node_modules里面会多出 echarts、mpvue-echats 、zrender 三个目录
2) 将mpvue-echats目录下的src目录放进components文件夹中
3) 由于小程序包大小限制,可以定制化echcarts( https://echarts.apache.org/zh/builder.html )并根据自身框架引入
2、组件(由于小程序canvas层级过高导致的各种bug,我这里是做做了转base64处理)
<template>
<view class="ec-canvas">
<canvas v-if="canvasId && !imgBase64" class="ec-canvas" :id="canvasId" :canvasId="canvasId" @touchstart="touchStart"
@touchmove="touchMove" @touchend="touchEnd" @error="error"></canvas>
<img class="ec-canvas" :src="imgBase64" />
</view>
</template>
<script>
import WxCanvas from ‘./wx-canvas‘;
import * as echarts from ‘@/static/libs/echarts/echarts.min‘; /*chart.min.js为在线定制*/
export default {
props: {
// echarts: {
// required: true,
// type: Object,
// default() {
// return echarts;
// }
// },
canvasId: {
type: String,
default: ‘ec-canvas‘
},
lazyLoad: {
type: Boolean,
default: false
},
disableTouch: {
type: Boolean,
default: true
},
throttleTouch: {
type: Boolean,
default: true
}
},
data(){
return {
imgBase64: ‘‘
}
},
onReady() {
if (!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() {
let self = this;
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.canvasId;
this.ctx = wx.createCanvasContext(canvasId, this);
const canvas = new WxCanvas(this.ctx, canvasId);
echarts.setCanvasCreator(() => canvas);
const query = wx.createSelectorQuery().in(this);
query
.select(`#${canvasId}`)
.boundingClientRect(res => {
if (!res) {
//setTimeout(() => this.init(), 200);
return;
}
this.chart = this.$emit(‘onInit‘, {
canvas,
width: res.width,
height: res.height
});
setTimeout(() => {
self.canvasToImg({
width: res.width,
height: res.height
})
}, 500);
})
.exec();
},
canvasToTempFilePath(opt) {
const {
canvasId
} = this;
this.ctx.draw(true, () => {
wx.canvasToTempFilePath({
canvasId,
...opt
});
});
},
touchStart(e) {
const {
disableTouch
} = this;
if (disableTouch || !e.mp.touches.length) return;
const touch = e.mp.touches[0];
echarts._zr.handler.dispatch(‘mousedown‘, {
zrX: touch.x,
zrY: touch.y
});
echarts._zr.handler.dispatch(‘mousemove‘, {
zrX: touch.x,
zrY: touch.y
});
},
touchMove(e) {
const {
disableTouch,
throttleTouch,
lastMoveTime
} = this;
if (disableTouch || !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];
echarts._zr.handler.dispatch(‘mousemove‘, {
zrX: touch.x,
zrY: touch.y
});
},
touchEnd(e) {
const {
disableTouch
} = this;
if (disableTouch) return;
const touch = e.mp.changedTouches ? e.mp.changedTouches[0] : {};
echarts._zr.handler.dispatch(‘mouseup‘, {
zrX: touch.x,
zrY: touch.y
});
echarts._zr.handler.dispatch(‘click‘, {
zrX: touch.x,
zrY: touch.y
});
},
// canvas转图片
canvasToImg(options){
let self = this;
uni.canvasToTempFilePath({
x: 0, // 起点坐标
y: 0,
width: options.width, // canvas 宽
height: options.height, // canvas 高
canvasId: self.canvasId, // canvas id
success(res) {
const savedFilePath = res.tempFilePath //相对路径
uni.getFileSystemManager().readFile({
filePath: savedFilePath, //选择图片返回的相对路径
encoding: ‘base64‘, //编码格式
success: res1 => { //成功的回调
self.imgBase64 = ‘data:image/jpeg;base64,‘ + res1.data //不加上这串字符,在页面无法显示的哦
},fail: (e) => {
self.imgBase64 = savedFilePath;
console.log("图片转换失败");
}
})
},
fail(err){
console.log(err)
}
},this)
}
}
};
</script>
<style scoped>
.ec-canvas {
width: 100%;
height: 100%;
flex: 1;
}
</style>
3、使用
<template>
<mpvue-echarts id="main" ref="mapChart" @onInit="renderLine" />
</template>
<script>
import * as echarts from ‘@/static/libs/echarts/echarts.min.js‘; /*chart.min.js为在线定制*/
import mpvueEcharts from ‘@/components/mpvue-echarts/echarts.vue‘;
export default {
data() {
return {
}
},
components: {
mpvueEcharts
},
methods: {
renderLine(e) {
let {
canvas,
width,
height
} = e;
echarts.setCanvasCreator(() => canvas);
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
canvas.setChart(chart);
var options = {
color: [‘#37a2da‘, ‘#32c5e9‘, ‘#67e0e3‘],
tooltip: {
trigger: ‘axis‘,
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: ‘shadow‘ // 默认为直线,可选为:‘line‘ | ‘shadow‘
},
confine: true
},
legend: {
data: [‘热度‘, ‘正面‘, ‘负面‘]
},
grid: {
left: 20,
right: 20,
bottom: 15,
top: 40,
containLabel: true
},
xAxis: [{
type: ‘value‘,
axisLine: {
lineStyle: {
color: ‘#999‘
}
},
axisLabel: {
color: ‘#666‘
}
}],
yAxis: [{
type: ‘category‘,
axisTick: {
show: false
},
data: [‘汽车之家‘, ‘今日头条‘, ‘百度贴吧‘, ‘一点资讯‘, ‘微信‘, ‘微博‘, ‘知乎‘],
axisLine: {
lineStyle: {
color: ‘#999‘
}
},
axisLabel: {
color: ‘#666‘
}
}],
series: [{
name: ‘热度‘,
type: ‘bar‘,
label: {
normal: {
show: true,
position: ‘inside‘
}
},
data: [300, 270, 340, 344, 300, 320, 310],
itemStyle: {
// emphasis: {
// color: ‘#37a2da‘
// }
}
},
{
name: ‘正面‘,
type: ‘bar‘,
stack: ‘总量‘,
label: {
normal: {
show: true
}
},
data: [120, 102, 141, 174, 190, 250, 220],
itemStyle: {
// emphasis: {
// color: ‘#32c5e9‘
// }
}
},
{
name: ‘负面‘,
type: ‘bar‘,
stack: ‘总量‘,
label: {
normal: {
show: true,
position: ‘left‘
}
},
data: [-20, -32, -21, -34, -90, -130, -110],
itemStyle: {
// emphasis: {
// color: ‘#67e0e3‘
// }
}
}
]
};
//初始化echarts实例
chart.setOption(options);
}
}
}
</script>
uniapp 中Echarts的使用(微信小程序)