# 代码片段欣赏

我们通常涉及图表可视化开发时一般都是用ECharts,本篇内容代码片段是介绍使用ECharts绘制的折线图如何设置放大限制以及调整拖拽时鼠标图标。

下面是基于vue的关键脚本片段实现。

# 欣赏开始

# 1、初始化ECharts时监听finish事件

function initECharts() {
  this.chart = echarts.init(document.getElementById('chart'))
  // 监听渲染结束事件,绑定相关事件
  this.chart.on('finished',  ()=> {
    const canvasEls = document.querySelectorAll('.chart-wrapper canvas')
    for(let i = 0; i < canvasEls.length; i++){
      const canvasEl = canvasEls[i]
      // 若该画布元素设置了bindEventFlag属性,说明绑定过事件,无须再绑定
      if(canvasEl.getAttribute('bindEventFlag')) continue
      this.bindEvent(canvasEls[i], this.chart)
    }
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13

注:eCharts是多画布进行绘制,所以有多个画布元素渲染,需要对所有画布元素进行事件绑定。

# 2、监听画布元素相关鼠标事件

function bindEvent(canvasEl, chart) {
  // 监听鼠标按下和抬起事件,用于调整拖拽时鼠标图标
  canvasEl.addEventListener('mousedown', function(){
    this.classList.add('cursor_move')
  })
  canvasEl.addEventListener('mouseup', function(){
    this.classList.remove('cursor_move')
  })

  // 监听鼠标滑轮事件,对放大操作进行限制
  // 当前放大倍数
  let scale = 1
  // 最大放大倍数
  const maxScale = 40
  canvasEl.addEventListener('mousewheel',function(e){
    // deltaY小于0说明是放大,否则是缩小
    if(e.deltaY < 0 ){
      // 放大处理
      if(scale >= maxScale) return

      scale += 1

      if(scale < maxScale) return

      const {
        dataZoom: [
          { zoomOnMouseWheel : zoomOnMouseWheelX },
          { zoomOnMouseWheel : zoomOnMouseWheelY },
        ]
      } = chart.getOption()
      if(zoomOnMouseWheelX && zoomOnMouseWheelY){
        // 禁用缩放
        chart.setOption({
          dataZoom: [
            { zoomOnMouseWheel : false },
            { zoomOnMouseWheel : false },
          ]
        })
      }
    }else {
      // 缩小处理
      if(scale <= 1) return

      scale -= 1

      if(scale >= maxScale) return

      const {
        dataZoom: [
          { zoomOnMouseWheel : zoomOnMouseWheelX },
          { zoomOnMouseWheel : zoomOnMouseWheelY },
        ]
      } = chart.getOption()
      if(!zoomOnMouseWheelX && !zoomOnMouseWheelY){
        chart.setOption({
          dataZoom: [
            { zoomOnMouseWheel : true },
            { zoomOnMouseWheel : true },
          ]
        })
      }
    }
  })

  // 元素添加自定义属性,用于标识是否绑定事件
  canvasEl.setAttribute('bindEventFlag', true)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
.cursor_move {
  cursor: move;
}
1
2
3

不知一些同学看到下面这段代码是否感到费解。让我简单分析给你听,

if(scale >= maxScale) return
scale += 1
if(scale < maxScale) return 
1
2
3

第一句表示当前放大倍数不小于最大放大倍数,则此时鼠标滑轮操作是无效果的;

第二句是对当前放大倍数加1;

第三句是判断当前放大倍数是否小于最大放大倍数,是则说明此时鼠标滑轮操作是可以放大的,但是当不小于最大放大倍数(其实只有等于最大放大倍数的情况),这时则开启禁用缩放。

对应地,缩小处理的三句代码则是相反的逻辑。

# 欣赏结语

以上片段的来由属于非业务细节上的体验优化。如果在细节之处解决得越好,我认为这位开发工程师的能力越强,因为细节之处往往能检查掌握的技术深度。