在Vue中使用echarts的实例代码(3种图)


Posted in Javascript onJuly 10, 2017

前言

公司的项目中需要对数据做可视化处理,高级点的D3.js目前还没接触到,因此选用了大众化的Echarts, 在vue的生态系统中已经有实现好的vue-echarts,但是使用现成的就意味着必须使用它定制好的数据结构,我也没办法对他进行一些修改。我个人也偏向于原生JS编程,因此没有采用,而是自己在vue中实现了对数据的可视化处理,先来看看效果图

以下数据已做脱敏处理

在Vue中使用echarts的实例代码(3种图)

在Vue中使用echarts的实例代码(3种图)

在Vue中使用echarts的实例代码(3种图)

这是目前用到的三种图。

可以看到,我在图表的外部添加了标题及说明,以及右侧的选择框组件,视图可以根据选择的不同,图表进行动态切换(echarts也是数据驱动),这就是个人定制化的好处

总体数据流向

所有的数据都是动态获取的,由前端向后台请求。当然请求数据肯定不会放在图表组件中,而是放在了外部。因为架构设计的不合理(MD前端就我一个人!),因此前期获取数据及存取数据的方式,和后期也较大的不同。

1. 存放在vuex中

这么大型的项目,vuex少不了。在前面的组件中,一次请求数据,然后将数据存储到了vuex中,echarts组件再从vuex中获取数据。这样的做法可能代码要稍微复杂点,但是数据存储在vuex中是随时可见的,我们也能随时保存获取的结果,对这些数据可以添加收藏也可以加入缓存中,下次再请求可以先从缓存调用。
(然而这只是我前端的想法,后台已经实现了对请求数据的缓存)

2. 存放在组件中,再分派到echarts组件

再对数据进行还原的时候(我的收藏,最近浏览),因为不需要保存或者收藏数据,我就直接用一个父组件请求,然后再分发到echarts组件,这样没有经过vuex,代码想多要少些。

组件代码

<template>
 <div class="r-echarts-line">
  <div class="top">
   <div class="title">
    {{origin.title}}
   </div>
   <div class="select-list">
    <Select style="width:120px;margin-right:.5rem" v-model="pagePick">
     <Option v-for="item in origin.page_select" :key="item" :value="item.val">{{item.name}}</Option>
    </Select>
    <Select style="width:120px" v-model="typePick">
     <Option v-for="item in typeList" :value="item.name" :key="item">{{item.name}}</Option>
    </Select>
   </div>
  </div>
  <div class="des">说明:符合于本次筛选条件的共有<span class='tips'>{{origin.desc}}</span>条<span style="font-weight:700;color:black">职位信息</span>。</div>
  <div class="bottom" id="echart" ref="mychart">

  </div>
 </div>
</template>

这是组件的html部分,可以看见top以及des是我自己添加的,bottom才是核心,也是整个echarts展示的部分,注意这里添加了ref,在script的代码中,我们将通过这个钩子,将DOM挂载到echarts中

<script>
// echarts相关
let echarts = require('echarts/lib/echarts');
require('echarts/lib/chart/bar');
require('echarts/lib/component/tooltip');
require('echarts/lib/component/toolbox');
require('echarts/lib/component/legend');
require('echarts/lib/component/markLine');

export default {
 name: 'r-echarts-line',
 data () {
  return {
  typePick: '数值',
  typeList: [
   {
    name: '数值'
   },
   {
    name: '百分比'
   }
  ],
  pagePick: 0,
  // myChart实例
   myChart: {},
   percent: {
    label: {
     normal: {
      show: true,
      position: 'inside',
      formatter: '{c}%'
     }
    }
   },
   numeric: {
    label: {
     normal: {
      show: true,
      position: 'inside',
      formatter: '{c}'
     }
    }
   }
  }
 },
 props: {
  index: {
   required: true,
   type: Number
  },
  data: {
   required: true,
   type: Object
  }
 },
 mounted () {
  this.setEchart();
 },
 updated () {
  if (!this.myChart) {
   this.setEchart();
  }
  this.chartChange();
 },
 computed: {
  origin () {
   return this.data;
  },
  opt() {
   let that = this;
   let obj = {
    color: ['#606c94'],
    tooltip: {
    },
    toolbox: {
      show: true,
      feature: {
        saveAsImage: {show: true}
      }
    },
    label: {
     normal: {
      show: true,
      position: 'inside',
      formatter: '{c}'
     },
     emphasis: {
      show: true
     }
    },
    xAxis: {
     type: 'value',
    },
    yAxis: {
     data: that.origin[that.type][that.pagePick].key,
     axisLabel: {
      interval: 0,
      rotate: -30
     }
    },
    series: [{
     name: that.origin.title,
     type: 'bar',
     data: that.origin[that.type][that.pagePick].val,
     barMaxWidth: '30',
     markLine: {
      data: [
       {type: 'average', name: '平均值'}
      ]
     }
    }]
   }
   return obj;
  },
  type () {
   if (this.typePick == '数值') {
    return 'numeric';
   } else if (this.typePick == '百分比') {
    return 'percent';
   } else {
    return 'numeric';
   }
  }
 },
 methods: {
  setEchart () {
   let dom = this.$refs.mychart;
   this.myChart = echarts.init(dom);
   this.myChart.setOption(this.opt);
  },
  chartChange () {
   this.myChart.setOption(this.opt);
   if (this.typePick == '百分比') {
    this.myChart.setOption(this.percent);
   }
   if (this.typePick == '数值') {
    this.myChart.setOption(this.numeric);
   }
  }
 }
}
</script>

首先我引入了需要的echarts组件,这个部分通过npm i echarts -S添加。

接着data部分我设置了那些将会引起变化的参数。需要注意的是,我并没有将echarts的opt部分写入到data中,因为整个图表是基于数据驱动的,并且随时会发生变化,因此我将opt设置为计算属性computed,这样opt将会根据我的选择动态变化,echarts也将动态响应,mychart用于接收echarts生成的图表实例,再参数变换的时候将会起作用。

props部分是我接收到的参数,这个组件时基于前面我讲的第二种方式——父组件获取数据分发,data是父组件分发给echarts的数据源。

暂时忽略两个Vue生命周期钩子, 后面讲

计算属性中设置了两个属性,origin和opt,注意这个origin很重要,通过它我将opt项与复杂的数据解耦,无论外面的数据怎么换,opt只关心origin的值,而这个opt在两种数据获取的方式中是不一样的,使用vuex的方式,origin将会直接从vuex中获取数据。这样一定程度上也实现了组件的复用。

opt就是该图表组件的设置项了,这个参数按照官网给的配置,自己搭配即可。

接下来是methods部分,setEchart将会完成对整个图表的初始化,通过this.$refs获取DOM实例,再由echars生成实例并绑定在data中的mychart选项。

chartChange是用来响应我自定义组件的变化的,针对选框的不同将会有不同的显示情况。在这里是百分比和数据的切换

接着是前面忽略的生命周期部分

mounted里使用setEchart方法,初始化图表组件,一定要在这里使用该方法,否则会找不到DOM

updated周期里是响应参数变化的方法,首先检测该实例有没有生成(单页应用因为用户可能存在的误操作,很可能导致实例没有生成,这里检测是很有必要的),接着在vue中的数据发生改变时运行chartChange方法,注意,我的选择框是没有绑定事件的,只是通过v-model改变了参数,然后opt动态响应了参数的变化。当opt的参数变化的时候,updated中的方法就会执行,echarts也会动态响应。这个就是使用基于数据驱动vue最精巧的地方,避免了通过事件调用echartChange方法。也是vue中使用echarts核心的一环

另外还有一个就是获取地图参数的,并不用在官网里下载,提供的npm包里就有,按需引用就好了(使用官网的js版本会报错没找到echarts)

import echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/map';
import 'echarts/map/js/china.js';

style部分就没什么好聊的了,只需要记住一点,必须显式指定加载echarts 的DOM的宽度和高度

父组件对echarts组件的调用

调用组件的方法按照常规组件调用就好了,只是因为echarts加载数据绘制需要耗费不少时间,我们可能需要通过keep-alive保存组件在内存中,避免切出去的时候被释放了。另外可能一个页面需要展示多个echarts类型组件,这里考虑使用component动态组件

<template>
 <div class="focus-echarts-wrap">
  <keep-alive>
   <component :is="currentView" :index="focusType"></component>
  </keep-alive>
 </div>
</template>

其他问题

在生成柱状图和饼状图的时候,加载时间并不算太慢。只是在加载地图类型的时候,尤其是我在生成中国地图的时候,达到了10s+的延迟,并且阻塞的是主线程,这段时间用户是无法操作的,相当于卡顿的情况。

该数据是在32bit的QQ浏览器上测得的,同事用的64bit的谷歌浏览器会好一点。

初步判断是echarts的问题。当然也因为是在dev模式下,可能和我打开了vuex和事件的监测有关。具体的延迟时间我会在线上版本测试,希望情况会好转吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于js与flash实现的网站flv视频播放插件代码
Oct 14 Javascript
自定义百度分享的分享按钮
Mar 18 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
Jun 02 Javascript
Google Maps基础及实例解析
Aug 06 Javascript
浅谈js对象的创建和对6种继承模式的理解和遐想
Oct 16 Javascript
微信小程序 本地存储及登录页面处理实例详解
Jan 11 Javascript
bootstrap select下拉搜索插件使用方法详解
Nov 23 Javascript
解决vue-cli创建项目的loader问题
Mar 13 Javascript
vue自定义全局共用函数详解
Sep 18 Javascript
微信小程序实现搜索功能
Mar 10 Javascript
分享一款超好用的JavaScript 打包压缩工具
Apr 26 Javascript
使用jquery实现轮播图效果
Jan 02 jQuery
jquery.validate.js 多个相同name的处理方式
Jul 10 #jQuery
Angular2生命周期钩子函数的详细介绍
Jul 10 #Javascript
使用Webpack提高Vue.js应用的方式汇总(四种)
Jul 10 #Javascript
在vue中获取dom元素内容的方法
Jul 10 #Javascript
jQuery实现html table行Tr的复制、删除、计算功能
Jul 10 #jQuery
vue移动端裁剪图片结合插件Cropper的使用实例代码
Jul 10 #Javascript
vue轮播图插件vue-awesome-swiper的使用代码实例
Jul 10 #Javascript
You might like
PHP中的正规表达式(二)
2006/10/09 PHP
PHP实现Socket服务器的代码
2008/04/03 PHP
php下连接ftp实现文件的上传、下载、删除文件实例代码
2010/06/03 PHP
PHP数据库万能引擎类adodb配置使用以及实例集锦
2014/06/12 PHP
PHP统计数值数组中出现频率最多的10个数字的方法
2015/04/20 PHP
php foreach如何跳出两层循环(详解)
2016/11/05 PHP
Mootools 1.2教程 事件处理
2009/09/15 Javascript
jquery实现的可隐藏重现的靠边悬浮层实例代码
2013/05/27 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
2014/05/01 Javascript
jQuery内置的AJAX功能和JSON的使用实例
2014/07/27 Javascript
jQuery检测输入的字符串包含的中英文的数量
2015/04/17 Javascript
简介AngularJS中使用factory和service的方法
2015/06/17 Javascript
jquery+CSS实现的水平布局多级网页菜单效果
2015/08/24 Javascript
JavaScript统计字符串中每个字符出现次数完整实例
2016/01/28 Javascript
灵活的理解JavaScript中的this指向
2016/02/25 Javascript
JS实现图片平面旋转的方法
2016/03/01 Javascript
BootStrop前端框架入门教程详解
2016/12/25 Javascript
JS点击动态添加标签、删除指定标签的代码
2018/04/18 Javascript
AjaxFileUpload.js实现异步上传文件功能
2019/04/19 Javascript
gulp构建小程序的方法步骤
2019/05/31 Javascript
Android 自定义view仿微信相机单击拍照长按录视频按钮
2019/07/19 Javascript
JavaScript中while循环的基础使用教程
2020/08/11 Javascript
[52:37]完美世界DOTA2联赛循环赛 Forest vs DM BO2第一场 10.29
2020/10/29 DOTA
Python编程使用tkinter模块实现计算器软件完整代码示例
2017/11/29 Python
Python中存取文件的4种不同操作
2018/07/02 Python
树莓派采用socket方式文件传输(python)
2019/06/22 Python
PyQt5事件处理之定时在控件上显示信息的代码
2020/03/25 Python
美国背景检查、公共记录和人物搜索网站:BeenVerified
2018/02/25 全球购物
屈臣氏俄罗斯在线商店:Watsons俄罗斯
2020/08/03 全球购物
电子商务应届生求职信
2013/11/16 职场文书
公司领导班子对照材料
2014/08/18 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
刑事辩护授权委托书范本
2014/10/17 职场文书
python Tkinter的简单入门教程
2021/04/11 Python
Beekeeper Studio开源数据库管理工具比Navicat更炫酷
2022/06/21 数据库
Java实现HTML转为Word的示例代码
2022/06/28 Java/Android