uniapp 中Echarts的使用(微信小程序)


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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM