在微信小程序中使用echarts

在微信小程序中使用echarts

准备

  • 安装依赖 npm install echarts mpvue-echarts --save
    • 下载成功后在node_modules里面会多出 echarts、mpvue-echats 、zrender 三个目录
    • 将mpvue-echats目录下的src目录放进components文件夹中
    • 由于小程序包大小限制,可以定制化echcarts并根据自身框架引入

组件代码

由于小程序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>

使用

可去echcarts官网在线调试好后,直接复制配置项

<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>

参考链接:
https://www.cnblogs.com/baiyis/p/13520681.html

猜你喜欢

转载自blog.csdn.net/weixin_48888726/article/details/128956379