You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							284 lines
						
					
					
						
							8.3 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							284 lines
						
					
					
						
							8.3 KiB
						
					
					
				
								import WxCanvas from './wx-canvas';
							 | 
						|
								import * as echarts from './echarts';
							 | 
						|
								
							 | 
						|
								let ctx;
							 | 
						|
								
							 | 
						|
								function compareVersion(v1, v2) {
							 | 
						|
								  v1 = v1.split('.')
							 | 
						|
								  v2 = v2.split('.')
							 | 
						|
								  const len = Math.max(v1.length, v2.length)
							 | 
						|
								
							 | 
						|
								  while (v1.length < len) {
							 | 
						|
								    v1.push('0')
							 | 
						|
								  }
							 | 
						|
								  while (v2.length < len) {
							 | 
						|
								    v2.push('0')
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  for (let i = 0; i < len; i++) {
							 | 
						|
								    const num1 = parseInt(v1[i])
							 | 
						|
								    const num2 = parseInt(v2[i])
							 | 
						|
								
							 | 
						|
								    if (num1 > num2) {
							 | 
						|
								      return 1
							 | 
						|
								    } else if (num1 < num2) {
							 | 
						|
								      return -1
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  return 0
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								Component({
							 | 
						|
								  properties: {
							 | 
						|
								    canvasId: {
							 | 
						|
								      type: String,
							 | 
						|
								      value: 'ec-canvas'
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    ec: {
							 | 
						|
								      type: Object
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    forceUseOldCanvas: {
							 | 
						|
								      type: Boolean,
							 | 
						|
								      value: false
							 | 
						|
								    }
							 | 
						|
								  },
							 | 
						|
								
							 | 
						|
								  data: {
							 | 
						|
								    isUseNewCanvas: false
							 | 
						|
								  },
							 | 
						|
								
							 | 
						|
								  ready: function () {
							 | 
						|
								    // 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;
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								    });
							 | 
						|
								
							 | 
						|
								    if (!this.data.ec) {
							 | 
						|
								      console.warn('组件需绑定 ec 变量,例:<ec-canvas id="mychart-dom-bar" '
							 | 
						|
								        + 'canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>');
							 | 
						|
								      return;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if (!this.data.ec.lazyLoad) {
							 | 
						|
								      this.init();
							 | 
						|
								    }
							 | 
						|
								  },
							 | 
						|
								
							 | 
						|
								  methods: {
							 | 
						|
								    init: function (callback) {
							 | 
						|
								      const version = wx.getSystemInfoSync().SDKVersion
							 | 
						|
								
							 | 
						|
								      const canUseNewCanvas = compareVersion(version, '2.9.0') >= 0;
							 | 
						|
								      const forceUseOldCanvas = this.data.forceUseOldCanvas;
							 | 
						|
								      const isUseNewCanvas = canUseNewCanvas && !forceUseOldCanvas;
							 | 
						|
								      this.setData({ isUseNewCanvas });
							 | 
						|
								
							 | 
						|
								      if (forceUseOldCanvas && canUseNewCanvas) {
							 | 
						|
								        console.warn('开发者强制使用旧canvas,建议关闭');
							 | 
						|
								      }
							 | 
						|
								
							 | 
						|
								      if (isUseNewCanvas) {
							 | 
						|
								        // console.log('微信基础库版本大于2.9.0,开始使用<canvas type="2d"/>');
							 | 
						|
								        // 2.9.0 可以使用 <canvas type="2d"></canvas>
							 | 
						|
								        this.initByNewWay(callback);
							 | 
						|
								      } else {
							 | 
						|
								        const isValid = compareVersion(version, '1.9.91') >= 0
							 | 
						|
								        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;
							 | 
						|
								        } else {
							 | 
						|
								          console.warn('建议将微信基础库调整大于等于2.9.0版本。升级后绘图将有更好性能');
							 | 
						|
								          this.initByOldWay(callback);
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    initByOldWay(callback) {
							 | 
						|
								      // 1.9.91 <= version < 2.9.0:原来的方式初始化
							 | 
						|
								      ctx = wx.createCanvasContext(this.data.canvasId, this);
							 | 
						|
								      const canvas = new WxCanvas(ctx, this.data.canvasId, false);
							 | 
						|
								
							 | 
						|
								      if (echarts.setPlatformAPI) {
							 | 
						|
								        echarts.setPlatformAPI({
							 | 
						|
								          createCanvas: () => canvas,
							 | 
						|
								        });
							 | 
						|
								      } else {
							 | 
						|
								        echarts.setCanvasCreator(() => canvas);
							 | 
						|
								      };
							 | 
						|
								      // const canvasDpr = wx.getSystemInfoSync().pixelRatio // 微信旧的canvas不能传入dpr
							 | 
						|
								      const canvasDpr = 1
							 | 
						|
								      var query = wx.createSelectorQuery().in(this);
							 | 
						|
								      query.select('.ec-canvas').boundingClientRect(res => {
							 | 
						|
								        if (typeof callback === 'function') {
							 | 
						|
								          this.chart = callback(canvas, res.width, res.height, canvasDpr);
							 | 
						|
								        }
							 | 
						|
								        else if (this.data.ec && typeof this.data.ec.onInit === 'function') {
							 | 
						|
								          this.chart = this.data.ec.onInit(canvas, res.width, res.height, canvasDpr);
							 | 
						|
								        }
							 | 
						|
								        else {
							 | 
						|
								          this.triggerEvent('init', {
							 | 
						|
								            canvas: canvas,
							 | 
						|
								            width: res.width,
							 | 
						|
								            height: res.height,
							 | 
						|
								            canvasDpr: canvasDpr // 增加了dpr,可方便外面echarts.init
							 | 
						|
								          });
							 | 
						|
								        }
							 | 
						|
								      }).exec();
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    initByNewWay(callback) {
							 | 
						|
								      // version >= 2.9.0:使用新的方式初始化
							 | 
						|
								      const query = wx.createSelectorQuery().in(this)
							 | 
						|
								      query
							 | 
						|
								        .select('.ec-canvas')
							 | 
						|
								        .fields({ node: true, size: true })
							 | 
						|
								        .exec(res => {
							 | 
						|
								          const canvasNode = res[0].node
							 | 
						|
								          this.canvasNode = canvasNode
							 | 
						|
								
							 | 
						|
								          const canvasDpr = wx.getSystemInfoSync().pixelRatio
							 | 
						|
								          const canvasWidth = res[0].width
							 | 
						|
								          const canvasHeight = res[0].height
							 | 
						|
								
							 | 
						|
								          const ctx = canvasNode.getContext('2d')
							 | 
						|
								
							 | 
						|
								          const canvas = new WxCanvas(ctx, this.data.canvasId, true, canvasNode)
							 | 
						|
								          if (echarts.setPlatformAPI) {
							 | 
						|
								            echarts.setPlatformAPI({
							 | 
						|
								              createCanvas: () => canvas,
							 | 
						|
								              loadImage: (src, onload, onerror) => {
							 | 
						|
								                if (canvasNode.createImage) {
							 | 
						|
								                  const image = canvasNode.createImage();
							 | 
						|
								                  image.onload = onload;
							 | 
						|
								                  image.onerror = onerror;
							 | 
						|
								                  image.src = src;
							 | 
						|
								                  return image;
							 | 
						|
								                }
							 | 
						|
								                console.error('加载图片依赖 `Canvas.createImage()` API,要求小程序基础库版本在 2.7.0 及以上。');
							 | 
						|
								                // PENDING fallback?
							 | 
						|
								              }
							 | 
						|
								            })
							 | 
						|
								          } else {
							 | 
						|
								            echarts.setCanvasCreator(() => canvas)
							 | 
						|
								          }
							 | 
						|
								
							 | 
						|
								          if (typeof callback === 'function') {
							 | 
						|
								            this.chart = callback(canvas, canvasWidth, canvasHeight, canvasDpr)
							 | 
						|
								          } else if (this.data.ec && typeof this.data.ec.onInit === 'function') {
							 | 
						|
								            this.chart = this.data.ec.onInit(canvas, canvasWidth, canvasHeight, canvasDpr)
							 | 
						|
								          } else {
							 | 
						|
								            this.triggerEvent('init', {
							 | 
						|
								              canvas: canvas,
							 | 
						|
								              width: canvasWidth,
							 | 
						|
								              height: canvasHeight,
							 | 
						|
								              dpr: canvasDpr
							 | 
						|
								            })
							 | 
						|
								          }
							 | 
						|
								        })
							 | 
						|
								    },
							 | 
						|
								    canvasToTempFilePath(opt) {
							 | 
						|
								      if (this.data.isUseNewCanvas) {
							 | 
						|
								        // 新版
							 | 
						|
								        const query = wx.createSelectorQuery().in(this)
							 | 
						|
								        query
							 | 
						|
								          .select('.ec-canvas')
							 | 
						|
								          .fields({ node: true, size: true })
							 | 
						|
								          .exec(res => {
							 | 
						|
								            const canvasNode = res[0].node
							 | 
						|
								            opt.canvas = canvasNode
							 | 
						|
								            wx.canvasToTempFilePath(opt)
							 | 
						|
								          })
							 | 
						|
								      } else {
							 | 
						|
								        // 旧的
							 | 
						|
								        if (!opt.canvasId) {
							 | 
						|
								          opt.canvasId = this.data.canvasId;
							 | 
						|
								        }
							 | 
						|
								        ctx.draw(true, () => {
							 | 
						|
								          wx.canvasToTempFilePath(opt, this);
							 | 
						|
								        });
							 | 
						|
								      }
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    touchStart(e) {
							 | 
						|
								      if (this.chart && e.touches.length > 0) {
							 | 
						|
								        var touch = e.touches[0];
							 | 
						|
								        var handler = this.chart.getZr().handler;
							 | 
						|
								        handler.dispatch('mousedown', {
							 | 
						|
								          zrX: touch.x,
							 | 
						|
								          zrY: touch.y,
							 | 
						|
								          preventDefault: () => {},
							 | 
						|
								          stopImmediatePropagation: () => {},
							 | 
						|
								          stopPropagation: () => {}
							 | 
						|
								        });
							 | 
						|
								        handler.dispatch('mousemove', {
							 | 
						|
								          zrX: touch.x,
							 | 
						|
								          zrY: touch.y,
							 | 
						|
								          preventDefault: () => {},
							 | 
						|
								          stopImmediatePropagation: () => {},
							 | 
						|
								          stopPropagation: () => {}
							 | 
						|
								        });
							 | 
						|
								        handler.processGesture(wrapTouch(e), 'start');
							 | 
						|
								      }
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    touchMove(e) {
							 | 
						|
								      if (this.chart && e.touches.length > 0) {
							 | 
						|
								        var touch = e.touches[0];
							 | 
						|
								        var handler = this.chart.getZr().handler;
							 | 
						|
								        handler.dispatch('mousemove', {
							 | 
						|
								          zrX: touch.x,
							 | 
						|
								          zrY: touch.y,
							 | 
						|
								          preventDefault: () => {},
							 | 
						|
								          stopImmediatePropagation: () => {},
							 | 
						|
								          stopPropagation: () => {}
							 | 
						|
								        });
							 | 
						|
								        handler.processGesture(wrapTouch(e), 'change');
							 | 
						|
								      }
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    touchEnd(e) {
							 | 
						|
								      if (this.chart) {
							 | 
						|
								        const touch = e.changedTouches ? e.changedTouches[0] : {};
							 | 
						|
								        var handler = this.chart.getZr().handler;
							 | 
						|
								        handler.dispatch('mouseup', {
							 | 
						|
								          zrX: touch.x,
							 | 
						|
								          zrY: touch.y,
							 | 
						|
								          preventDefault: () => {},
							 | 
						|
								          stopImmediatePropagation: () => {},
							 | 
						|
								          stopPropagation: () => {}
							 | 
						|
								        });
							 | 
						|
								        handler.dispatch('click', {
							 | 
						|
								          zrX: touch.x,
							 | 
						|
								          zrY: touch.y,
							 | 
						|
								          preventDefault: () => {},
							 | 
						|
								          stopImmediatePropagation: () => {},
							 | 
						|
								          stopPropagation: () => {}
							 | 
						|
								        });
							 | 
						|
								        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;
							 | 
						|
								}
							 | 
						|
								
							 |