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

项目场景:

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


定义 DOM 容器

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

例:

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

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

单个数据视图进行自适应

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

1. 使用window.onresize

let myChart = echarts.init(document.getElementById(dom))
window.onresize = function () {
    myChat.resize()
}

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

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

myChart.resize({
  width: 800,
  height: 400
});

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

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

let myChart1 = echarts.init(document.getElementById(dom1))
let myChart2 = echarts.init(document.getElementById(dom2))
window.onresize = function () {
 	myChat1.resize()
 	myChat2.resize()
}

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

let myChart = echarts.init(document.getElementById(dom))
let sizeFun = function () {
 	myChat.resize()
}
window.addEventListener('resize', sizeFun )

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

多个数据视图进行自适应

这里分享一下我的思路:

1.通过父子传值

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

2.通过封装

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

在这里插入图片描述

还有可以切换柱状图

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

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

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

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

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

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} 

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

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wh1T3ZzT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值