vue中如何使用ECharts画图并实现自适应 您所在的位置:网站首页 echart画图表 vue中如何使用ECharts画图并实现自适应

vue中如何使用ECharts画图并实现自适应

#vue中如何使用ECharts画图并实现自适应| 来源: 网络整理| 查看: 265

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

1. vue 中如何使用 ECharts 1.1.安装 ECharts npm install echarts --save 复制代码 1.2.引入 ECharts

在 vue 项目的 main.js 文件中全局全部引入:

// 全部引入echarts import * as echarts from 'echarts' Vue.prototype.$echarts = echarts 复制代码

以上引入方式是将 ECharts 中所有的图表和组件全部引入,这会导致打包时文件过大,所以我们也可以根据实际需要在需要画图的 .vue 文件中按需引入:

// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。 import * as echarts from 'echarts/core' // 引入柱状图图表,图表后缀都为Chart,也可以引入其他图表 import { BarChart, PieChart, LineChart } from 'echarts/charts' // 引入提示框,标题,直角坐标系组件,组件后缀都为 Component import { TitleComponent, TooltipComponent, GridComponent, LegendComponent, DatasetComponent } from 'echarts/components' // 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步 import { CanvasRenderer } from 'echarts/renderers' // 注册必须的组件 echarts.use([ TitleComponent, TooltipComponent, GridComponent, BarChart, PieChart, LineChart, CanvasRenderer, LegendComponent, DatasetComponent ]) 复制代码 1.3.使用 ECharts 画图

在页面标签中新建一个 id(必需)为 main 的固定宽高的 div

复制代码

在 methods 写好画图的方法,该方法包含一些图表的配置信息

methods: { initChart(domName, title) { var myChart = this.$echarts.init(domName) var option = { title: { text: title }, legend: { data: ['销量'] }, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] } option && myChart.setOption(option) } } } 复制代码

在 mounted 中调用该方法进行画图

mounted() { this.initChart(document.getElementById('main'), '111111111') }, 复制代码

页面效果如图

以上就是 vue 中使用 ECharts 画图的基本方法,具体也可参考官方。

但是光基本的使用方法,往往无法满足项目的需求,一般在项目中我们需要实现图表的自适应或者多图,嵌套画图,实时数据画图,循环画图等等。下面我们先来研究如何实现图表的自适应。

2.ECharts 图表自适应 2.1.前提

将图表容器的宽高设置为百分比的形式,完整代码如下:

export default { data() { return { } }, mounted() { this.initChart(document.getElementById('main1'), '111111111') this.initChart(document.getElementById('main2'), '222222222') }, methods: { initChart(domName, title) { var myChart = this.$echarts.init(domName) var option = { title: { text: title }, legend: { data: ['销量'] }, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] } // 绘制图表 option && myChart.setOption(option) } } } .chartCon{ width: calc(100% - 40px); background-color: #fff; position: absolute; left: 20px; right: 20px; bottom: 20px; top: 20px; .normalStyle{ width:50%; height:100%; float:left; border:1px solid #eee } } 复制代码

页面渲染存在以下问题:

1)初次渲染时,图表高度不是按设置的100%来显示,如图:

2)需要手动点一下浏览器的刷新后才正常显示,如图:

3)图表没有随着浏览器窗口的大小而自适应显示,如图:

2.2.实现自适应

方法一、使用 window.onresize(官方)

基于前提中的代码,更改 initChart 方法的代码如下:

initChart(domName, title) { var myChart = this.$echarts.init(domName) // 自适应 window.onresize = function() { myChart.resize() } var option = { title: { text: title }, legend: { data: ['销量'] }, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] } // 绘制图表 option && myChart.setOption(option) } 复制代码

存在的问题:

1)初次渲染时,图表高度仍然不是按设置的100%来显示,如图:

2)仍然需要手动刷新一次后才正常显示,如图:

2)多个图表的时候就只有最后一个自适应生效了,onresize会被覆盖,如图:

方法二、使用 window.addEventListener 添加 resize 方法

基于前提中的代码,更改 initChart 方法的代码如下:

initChart(domName, title) { var myChart = this.$echarts.init(domName) //自适应 var listener = function() { myChart.resize() } window.addEventListener('resize', listener) var option = { title: { text: title }, legend: { data: ['销量'] }, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] } // 绘制图表 option && myChart.setOption(option) } 复制代码

存在的问题:

1)初次渲染时,图表高度仍然不是按设置的100%来显示,如图:

2)仍然需要手动刷新一次后才正常显示,如图:

3)虽然基本实现了图表的自适应,但是当 vue 页面路由跳转到下一个页面时,上一个页面的 onresize 方法仍会继续执行。

方法三、通过封装自适应方法 esresize 实现

参考:blog.csdn.net/qq_31967985…

esresize.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(evt) { 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 } 复制代码

vue 文件中引入 esresize.js

import { EleResize } from '@/utils/esresize'// 图表自适应 复制代码

使用:基于前提中的代码,更改 initChart 方法的代码如下:

initChart(domName, title) { var myChart = this.$echarts.init(domName) // 自适应 var listener = function() { myChart.resize() } EleResize.on(domName, listener) var option = { title: { text: title }, legend: { data: ['销量'] }, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] } // 绘制图表 option && myChart.setOption(option) } 复制代码

使用该方法以上所有存在的问题都被解决了。

2.3.补充

对于将图表容器宽高设置成百分比而造成的初次渲染时图表容器高度不生效的问题(以上方法一和方法二的问题1),还可以通过监听浏览器窗口变化动态设置图表容器大小为 window.innerWidth 和 window.innerHeight 来解决,可以搭配自适应来一起使用,只不过这样比较繁琐,不推荐使用,但是也可以参考一下实现方式。

具体代码如下:

export default { data() { return { screenHeight: window.innerHeight, screenWidth: window.innerWidth, normalHeight: window.innerHeight * 0.9, normalWidth: window.innerWidth } }, watch: { // 监听screenHeight和screenWidth从而动态修改图表容器宽高 screenHeight(val) { this.screenHeight = val this.normalHeight = this.screenHeight * 0.9 }, screenWidth(val) { this.screenWidth = val this.normalWidth = this.screenWidth } }, mounted() { // 画图 this.initChart(document.getElementById('main1'), '111111111') this.initChart(document.getElementById('main2'), '222222222') // 浏览器窗口变化触发,获取当前浏览器窗口大小 window.onresize = () => { return (() => { window.screenHeight = window.innerHeight window.screenWidth = window.innerWidth this.screenHeight = window.screenHeight this.screenWidth = window.screenWidth })() } }, methods: { initChart(domName, title) { var myChart = this.$echarts.init(domName) // 自适应 var listener = function() { myChart.resize() } window.addEventListener('resize', listener) var option = { title: { text: title }, legend: { data: ['销量'] }, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] } // 绘制图表 option && myChart.setOption(option) } } } .chartCon{ width: calc(100% - 40px); background-color: #fff; position: absolute; left: 20px; right: 20px; bottom: 20px; top: 20px; .normalStyle{ width:50%; height:100%; float:left; border: 1px solid #eee; } } 复制代码

初次渲染时页面完好,如图:

3.总结

以上内容只是针对在 div 中画图时存在的一些问题和解决办法,貌似在 Tabs 标签页中画图又会出现别的问题,继续研究,感谢各位大佬!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有