• ECharts多个数据视图进行自适应大小的解决方案


    项目场景:

    在制作数据视图时经常会遇到多个数据视图的情况,在多个数据视图的情况下做自适应是比较麻烦的,这里就详细的分析一下该如何去制作,分享一下我的解决办法及思路。


    定义 DOM 容器

    这里需要注意一个地方,在定义高宽的 DOM 容器时,不能把宽度定为固定大小,或者父级也不能为固定大小,如果是固定的宽度哪怕重绘了,宽度也是一样的,所以是无法实现自适应的,一般情况下都是固定高度,然后宽度自适应

    例:

    <div ref="linechart" style="width:100%;height:400px;"></div>
    
    • 1

    想要实现数据视图的自适应就得先保证它的DOM容器是自适应的。

    单个数据视图进行自适应

    单个数据视图的解决方案就比较多了,也比较简单,就不过多的说明了

    1. 使用window.onresize

    let myChart = echarts.init(document.getElementById(dom))
    window.onresize = function () {
        myChat.resize()
    }
    
    • 1
    • 2
    • 3
    • 4

    这个是通过ECharts自带的方法
    myChart是你自己初始化一个 echarts,在myChart中有一个方法resize,调用这个方法可以实现重绘,实现自适应

    这里拓展一下,myChat.resize()是可以自定义大小的:

    myChart.resize({
      width: 800,
      height: 400
    });
    
    • 1
    • 2
    • 3
    • 4

    具体使用方法就看需求了。

    这里还需要注意一个地方,就是这个方法也是可以实现多个数据视图自适应,但是比较笨一点

    let myChart1 = echarts.init(document.getElementById(dom1))
    let myChart2 = echarts.init(document.getElementById(dom2))
    window.onresize = function () {
     	myChat1.resize()
     	myChat2.resize()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.使用window.addEventListener添加resize方法

    let myChart = echarts.init(document.getElementById(dom))
    let sizeFun = function () {
     	myChat.resize()
    }
    window.addEventListener('resize', sizeFun )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这个方法我也使用过,最大的问题就是当离开这个页面的时候这个函数依旧会去执行,当其他页面不存在这个DOM时则会报错,并且触发的非常频繁还需要写防抖节流器,所以不推荐使用,这里就不过多说明了。

    多个数据视图进行自适应

    这里分享一下我的思路:

    1.通过父子传值

    我是先用一个父组件,然后将这些视图分成一个个的子组件,在父组件监听浏览器的事件,当窗口大小改变之后把一个定义好的值(我这里用的是resize:true)传给子组件,子组件接收到时候在执行重绘。
    具体代码就不展示了,因为就是一个父子传值的问题也比较简单,主要是分享一下解决方案

    2.通过封装

    这个是我目前使用的方法,但是这个方法存在一定的局限性,就是先要确定需求,保证使用的数据视图是差不多的,比如都使用到折线图,柱状图,这种相似的数据视图
    在这里插入图片描述
    我这里全部使用的就是折线面积图,当点击某个端点时则切换显示该字段的明细。

    在这里插入图片描述

    还有可以切换柱状图

    在这里插入图片描述
    数据视图

    在这里插入图片描述
    这里说一下为什么这样做:

    1. 使用过ECache都知道,这个组件的代码量比较大,尤其是在多个数据视图的情况下,代码冗余量非常多。
    2. 因为我封装好了,需要修改时只需要修改封装的组件,降低维护成本
    3. 后续在需要制作时直接调用即可

    具体如何封装我会在后续发布
    通过封装我们就可以非常简单的解决这个自适应的问题了。

          option = option1;
          option && myChart.setOption(option);
          //根据窗口的大小变动图表 --- 重点
          let listener = function(){
            myChart.resize()
          }
          EleResize.on(chartDom,listener)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    EleResize

    这个JS是我在网上找到的一个ECharts图表自适应的JS

    // ECharts图表自适应JS
    var EleResize = {
      _handleResize: function (e) {
        var ele = e.target || e.srcElement
        var trigger = ele.__resizeTrigger__
        if (trigger) {
          var handlers = trigger.__z_resizeListeners
          if (handlers) {
            var size = handlers.length
            for (var i = 0; i < size; i++) {
              var h = handlers[i]
              var handler = h.handler
              var context = h.context
              handler.apply(context, [e])
            }
          }
        }
      },
      _removeHandler: function (ele, handler, context) {
        var handlers = ele.__z_resizeListeners
        if (handlers) {
          var size = handlers.length
          for (var i = 0; i < size; i++) {
            var h = handlers[i]
            if (h.handler === handler && h.context === context) {
              handlers.splice(i, 1)
              return
            }
          }
        }
      },
      _createResizeTrigger: function (ele) {
        var obj = document.createElement('object')
        obj.setAttribute('style',
        'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden;opacity: 0; pointer-events: none; z-index: -1;')
        obj.onload = EleResize._handleObjectLoad
        obj.type = 'text/html'
        ele.appendChild(obj)
        obj.data = 'about:blank'
        return obj
      },
      _handleObjectLoad: function () {
        this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__
        this.contentDocument.defaultView.addEventListener('resize', EleResize._handleResize)
      }
    }
    if (document.attachEvent) { // ie9-10
      EleResize.on = function (ele, handler, context) {
        var handlers = ele.__z_resizeListeners
        if (!handlers) {
          handlers = []
          ele.__z_resizeListeners = handlers
          ele.__resizeTrigger__ = ele
          ele.attachEvent('onresize', EleResize._handleResize)
        }
        handlers.push({
          handler: handler,
          context: context
        })
      }
      EleResize.off = function (ele, handler, context) {
        var handlers = ele.__z_resizeListeners
        if (handlers) {
          EleResize._removeHandler(ele, handler, context)
          if (handlers.length === 0) {
            ele.detachEvent('onresize', EleResize._handleResize)
            delete ele.__z_resizeListeners
          }
        }
      }
    } else {
      EleResize.on = function (ele, handler, context) {
      var handlers = ele.__z_resizeListeners
      if (!handlers) {
        handlers = []
        ele.__z_resizeListeners = handlers
        if (getComputedStyle(ele, null).position === 'static') {
          ele.style.position = 'relative'
        }
        var obj = EleResize._createResizeTrigger(ele)
        ele.__resizeTrigger__ = obj
        obj.__resizeElement__ = ele
      }
      handlers.push({
        handler: handler,
        context: context
        })
      }
      EleResize.off = function (ele, handler, context) {
        var handlers = ele.__z_resizeListeners
        if (handlers) {
          EleResize._removeHandler(ele, handler, context)
          if (handlers.length === 0) {
            var trigger = ele.__resizeTrigger__
            if (trigger) {
              trigger.contentDocument.defaultView.removeEventListener('resize', EleResize._handleResize)
              ele.removeChild(trigger)
              delete ele.__resizeTrigger__
            }
            delete ele.__z_resizeListeners
          }
        }
      }
    }
    export {EleResize} 
    
    • 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
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    将这个JS导入到页面中就可以直接使用了。

  • 相关阅读:
    python 实现两个文本文件内容去重
    js数组里使用三目判断,结合扩展运算符
    Mybatis如何使用分页插件pageHelper
    第八章相关内容
    机器学习与数据挖掘——数据预处理
    整理了一份七大专题的Java架构速成笔记
    常见漏洞危害总结
    工程师必备Linux最新命令大全
    模型评估指标
    【ZYNQ】petalinux实现开机自启动
  • 原文地址:https://blog.csdn.net/weixin_44748171/article/details/133376086