柱状图上添加折线图(如何在柱状图上面添加折线图)
1505
2022-05-30
原文地址:使用Vue+DataV+Echarts打造新冠肺炎疫情数据大屏(可动态刷新)
源码
查看:https://blog.lanweihong.com/posts/29267/
效果图
演示
仅适配 1080P 屏幕,使用浏览器访问后按 F11 进入全屏可看最佳显示效果。
疫情真实数据演示地址:演示地址-真实数据
模拟数据演示地址:演示地址-模拟数据
前端框架和类库
Vue.js
Apache ECharts
DataV
axios
Element
Mock
代码实现
创建项目
使用 Vue Cli 创建 Vue 项目,没有 Vue Cli 的使用以下命令安装:
npm install -g @vue/cli
创建项目:
vue create datav-covid-19
安装依赖
# 安装 DataV npm install @jiaminghi/data-view # 安装 echarts npm install echarts -S # 安装 element-ui npm i element-ui -S # 安装 vue-router npm install vue-router # 安装 mockjs npm install mockjs --save-dev # 安装 axios npm install axios # 安装 echarts-liquidfill npm i echarts-liquidfill
引入注册
在项目中引入,编辑 main.js:
import Vue from 'vue' import App from './App.vue' import dataV from '@jiaminghi/data-view' import * as echarts from 'echarts' import 'element-ui/lib/theme-chalk/index.css'; import axios from 'axios' // 引入 echarts 水球图 import 'echarts-liquidfill' import VueRouter from 'vue-router' import { Icon, Row, Col, Table, TableColumn, Button, Dialog, Link } from 'element-ui'; // 注册 echarts Vue.prototype.$echarts = echarts Vue.config.productionTip = false // 注册 axios Vue.prototype.axios = axios // 注册 dataV Vue.use(dataV) // 注册路由 Vue.use(VueRouter) // 按需注册其他 element-ui 组件 Vue.use(Icon) Vue.use(Row) Vue.use(Col) Vue.use(Table) Vue.use(TableColumn) Vue.use(Button) Vue.use(Dialog) Vue.use(Link) new Vue({ render: h => h(App), }).$mount('#app')
编写组件
因为篇幅有限,为了阅读体验,这里以 累计排名 组件为例,其他的组件请看 Github 上的代码。
效果图
累计排名组件采用 ECharts 的柱状图来显示,实现代码如下:
在页面中引入使用:
其他组件的代码就不在这里写了,完整代码已上传 Github ,需要的可以去查看。
完整的组件结构如下:
准备模拟数据
项目中提供了两种数据提供方式,一是请求真实后台地址,返回的数据格式参考 data 目录下的 json 文件;二是在本地使用 Mock 生成模拟数据。这里仅介绍使用 Mock 生成模拟数据方式。
在项目根目录下创建文件夹 mock,分别创建 covid19.js 和 index.js;
covid19.js 代码如下,代码中使用到一些 Mock 的语法,具体使用方法请查看 Mock 的文档。
// 从本地读取 json 数据 const provinceData = require('../data/covid19-province.json') const dailyData = require('../data/covid19-daily-list.json') // 引入 mockjs const Mock = require('mockjs') // 使用 mockjs 的 Random 生成随机数据 const Random = Mock.Random module.exports = [ { url: '/api/covid-19/overall', type: 'get', response: config => { return { success: true, code: 200, message: "操作成功", data: { confirmedCount: Random.integer(110000, 120000), confirmedIncr: 72, curedCount: Random.integer(100000, 110000), curedIncr: 173, currentConfirmedCount: Random.integer(3000, 4000), currentConfirmedIncr: -110, deadCount: Random.integer(4000, 6000), deadIncr: 12, importedCount: Random.integer(6000, 8000), importedIncr: 23, noInFectCount: Random.integer(400, 600), noInFectIncr: 8, suspectIncr: 0, suspectCount: 2, updateTime: "2021-07-15 20:39:11", curedRate: Random.float(90, 95, 0, 9), deadRate: Random.float(1, 5, 0, 9) } } } }, { url: '/api/covid-19/area/latest/list', type: 'get', response: config => { return provinceData } }, { url: '/api/covid-19/list', type: 'get', response: config => { return dailyData } } ]
编辑 index.js,这里主要是注册 mock 服务,调用方法 initMockData() 完成注册;
const Mock = require('mockjs') // 引入写好的 mock 服务 const covid19 = require('./covid19') const mocks = [ ...covid19 ] function param2Obj(url) { const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') if (!search) { return {} } const obj = {} const searchArr = search.split('&') searchArr.forEach(v => { const index = v.indexOf('=') if (index !== -1) { const name = v.substring(0, index) const val = v.substring(index + 1, v.length) obj[name] = val } }) return obj } const initMockData = () => { Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send Mock.XHR.prototype.send = function() { if (this.custom.xhr) { this.custom.xhr.withCredentials = this.withCredentials || false if (this.responseType) { this.custom.xhr.responseType = this.responseType } } this.proxy_send(...arguments) } function XHR2ExpressReqWrap(respond) { return function(options) { let result = null if (respond instanceof Function) { const { body, type, url } = options result = respond({ method: type, body: JSON.parse(body), query: param2Obj(url) }) } else { result = respond } return Mock.mock(result) } } for (const i of mocks) { Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) } } module.exports = { mocks, initMockData }
在 main.js 中引入:
const { initMockData } = require('../mock') // 完成注册 initMockData()
然后在页面中使用 request.get('/api/covid-19/list') 就能请求获取到数据,这里的 request.get() 是我用 axios 封装写的方法。
封装数据接口
项目中的数据请求都是使用 axios 为方便使用,我简单封装了一个工具类 request.js:
import axios from "axios" import sysConst from '../libs/const' const fetch = (method = 'GET', url, param = '') => { // 处理 url url = `${sysConst.baseUrl}${url}` return new Promise((resolve, reject) => { axios({ method: method, url: url, changeOrigin: true, data: JSON.stringify(param) }).then((res) => { resolve(res.data) }, error => { reject(error) }).catch((error) => { reject(error) }) }) } const get = (url) => { return fetch('GET', url) } const post = (url, data) => { return fetch('POST', url, data) } const put = (url, data) => { return fetch('PUT', url, data) } const remove = (url, data) => { return fetch('DELETE', url, data) } export { get, post, put, remove }
这里引入的 const.js 代码如下:
let baseUrl = '' if (process.env.NODE_ENV === 'development') { // 修改你的 API 地址 baseUrl = '' } else { // 你的 API 地址 baseUrl = '' } export default { baseUrl }
在项目根目录下新建文件夹 api ,用于保存编写数据接口,在该目录下新增文件 covid19.js,用于封装请求获取数据:
import * as request from '@/utils/request' /** * 接口封装 */ export default { getOverall() { let url = `/api/covid-19/overall?_=${Math.random()}` return request.get(url) }, getProvinceDataList() { let url = `/api/covid-19/area/latest/list?_=${Math.random()}` return request.get(url) }, getDailyList() { let url = `/api/covid-19/list?t=${Math.random()}` return request.get(url) } }
调用数据接口获取数据并更新图表展示
// 引入 import covid19Service from '../api/covid19' // 使用 let self = this covid19Service.getOverall().then((res) => { if (!res.success) { console.log('错误:' + res.info) return } // 修改数据,图表组件检测到数据变化会触发 setOptions() 方法更新显示( setOptions() 在图表组件中已定义好) self.basicData = res.data })
项目结构
完整的项目结构如下:
├─build ├─data # 本地模拟数据目录 ├─mock # mock 配置 ├─public └─src ├─api # 接口封装目录 ├─assets ├─components # 组件目录 │ ├─About # 关于 │ ├─BasicDataItemLabel # 基本数据显示标签 │ ├─BasicProportionChart # 占比图表 │ ├─BasicTrendChart # 趋势图表 │ ├─ChartCard # 图表面板 │ ├─CuredAndDeadRateChart # 治愈率和死亡率图表 │ ├─CurrentConfirmedCompareBarChart # 最近一周累计治愈图表 │ ├─DataMap # 数据地图 │ └─ProvinceRankingBarChart # 累计排名图表 ├─libs # 一些常用的配置 ├─router # 路由配置 ├─utils # 工具类 └─views # 视图
详细结构:
总结
采用组件化封装各个展示图表,能更好的图表展示及复用;
使用 axios 请求后台服务或本地 mock 服务获取数据,然后重新赋值图表中指定的数据;
项目源码:本项目源码已上传至 Github,在我的博客中可查看到地址:使用Vue+DataV+Echarts打造新冠肺炎疫情数据大屏(可动态刷新)
这个项目是个人学习作品,能力有限,难免会有 BUG 和错误,敬请谅解。如有更好的建议或想法,请指出,谢谢
javaScript Vue
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。