Use Vue+ Datav +Echarts to create a large screen of COVID-19 epidemic data (dynamically refreshing)

The source code

Look at: https://blog.lanweihong.com/posts/29267/

rendering

demo

Only suitable for 1080P screen. Press F11 to enter full screen after browser access to see the best display effect.

  1. Epidemic real data demo address: demo address – real data
  2. Analog data demo address: demo address – analog data

Front-end frameworks and class libraries

  • Vue.js
  • Apache ECharts
  • DataV
  • axios
  • Element
  • Mock

Code implementation

Create a project

Create a VUE project using the VUE CLI, and install it without the VUE CLI using the following command:

npm install -g @vue/cli

Create the project:

vue create datav-covid-19

Install dependencies

NPM install echarts NPM install echarts NPM install echarts NPM install echarts NPM install element-ui NPM install echarts NPM install echarts NPM install echarts NPM install 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

Introduction of registration

To introduce in the project, edit 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' // import 'echarts- Liquidfill 'import VueRouter from 'vue-router' import { Icon, Row, Col, Table, TableColumn, Button, Dialog, Link } from 'element-ui'; // Register echarts vue.prototype.$echarts = echarts vue.config.productionTip = false // Register Axios vue.prototype Vue.use(Icon) Vue.use(Row) Vue.use(Col) Vue.use(Col) 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')

Write a component

Because space is limited, for the sake of reading experience, here is an example of the cumulative ranking component. For other components, please see the code on GitHub.

Cumulative ranking component

rendering

The cumulative ranking component is displayed in the bar chart of Echarts, and the implementation code is as follows:

<template> <div ref="provinceRankingBarChart" style="width: 100%; height: 100%" /> </template> <script> import * as echarts from 'echarts' let chart = null export default { props: { data: { type: Object, default () { return { provinceList: [], valueList: [] } } } }, methods: { initChart () { if (null ! = chart && undefined ! = chart) { chart.dispose() } chart = this.$echarts.init(this.$refs.provinceRankingBarChart) this.setOptions() }, setOptions() { var salvProValue = this.data.valueList; var salvProMax = []; for (let i = 0; i < salvProValue.length; i++) { salvProMax.push(salvProValue[0]) } let option = { grid: { left: '2%', right: '2%', bottom: '2%', top: '2%', containLabel: true }, tooltip: { trigger: 'axis', axisPointer: { type: 'none' }, formatter: function (params) { return params[0].name + ' : ' + params[0].value } }, xAxis: { show: false, type: 'value' }, yAxis: [{ type: 'category', inverse: true, axisLabel: { show: true, textStyle: { color: '#fff' }, }, splitLine: { show: false }, axisTick: { show: false }, axisLine: { show: false }, data: this.data.provinceList }, { type: 'category', inverse: true, axisTick: 'none', axisLine: 'none', show: true, axisLabel: { textStyle: { color: '# FFFFFF ', fontSize: '12'},}, data: salvProvalue}], series: [{name: 'value ', type: 'bar', zlevel: 1, itemStyle: { normal: { barBorderRadius: 30, color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: 'RGB (2,163,254,1)'}, {offset: 1, color:' RGB (125,64,255,1)'}]),},}, barWidth: 20, data: salvProvalue}, {name: 'background ', type: 'bar', barWidth: 20, barGap: '-100%', data: salvProMax, itemStyle: {normal: {color: 'rgba(24,31,68,1)', barborderRadius: 30,}},},]} chart.setOptions}, watch: {data: { handler(newList, oldList) { if (oldList ! = newList) { this.setOptions() } }, deep: true } } } </script>

Introduce usage to the page:

<template> <div class="demo"> <province-ranking-bar-chart ref="rankChart" :data="dataList" style="width: 100%; Height: 380px" /> </div> </template> <script> // import ProvincerankingBarchart from '.. /components/ProvinceRankingBarChart' export default { components: {provincerAnkingBarChart}, data () {return {dataList: {provinceList: [' Hubei ', 'Taiwan '], valueList: [68188, 15379]}}, mounted() {// mount this.$refs.rankchart. Initchart ()}} </script> <style >.demo {width: 25px; 500px; height: 600px; } </style>

The code of other components is not written here. The complete code has been uploaded to GitHub, and you can check it if you need.

The complete component structure is as follows:

Prepare simulation data

There are two ways to provide data in the project. One is to request the real background address, and the format of the data returned is to refer to the JSON file in the data directory. The second is to use mocks locally to generate Mock data. This is only the way Mock data is generated using mocks.

Use a Mock to generate Mock data

Mock folder covid19.js and index.js in the root directory of your project.

Writing a mock service

The code for covid19.js is as follows. It uses some syntax for mocks. See the documentation for details.

Const provinceData = require('.. /data/covid19-province.json') const dailyData = require('.. /data/covid19-daily-list.json') // mockJS const Mock = require(' mockJS ') // mockJS const Mock = require(' mockJS ' Mock.Random module.exports = [ { url: '/api/covid-19/overall', type: 'get', response: config => { return { success: True, code: 200, message: "operation succeeded ", 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 } } ]
Register a mock service

InitMockData () is called to register the mock service.

Mock = require(' mockJS ') const Mock = require(' mockJS ') 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 }
Using mock services

Introduced in main.js:

const { initMockData } = require('.. /mock') // Register initMockData()

Get (‘/ API/COVID-19 /list’). Here, request.get() is the method I wrote in Axios encapsulation.

Encapsulated data interface

Encapsulation axios

For the convenience of using Axios, I simply encapsulated a tool class request.js:

import axios from "axios" import sysConst from '.. /libs/const' const fetch = (method = 'GET', 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 }

The const.js code introduced here is as follows:

If (process.env.node_env === 'development') {// modify your API base URL = ''} else {// your API base URL = ''  = '' } export default { baseUrl }

Encapsulated data interface

Create a new folder API in the root directory of the project to save the compiled data interface, and add a file covid19.js in the directory to encapsulate the requested data:

Import * as request from '@/utils/request' /** * interface */ 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) } }

Call the data interface to get the data and update the diagram presentation

// import covid19Service from '.. / / using/API/covid19 'let self = this covid19Service. GetOverall (). Then (= > {if ((res)! Res.success) {console.log(' error :' + res.info) return} // Modify data, The chart component detects a change in data and triggers the setOptions() method to update the display (setOptions() is defined in the chart component) self.basicData = res.data})

The project structure

The complete project structure is as follows:

└ Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises - Exercises │ ├─ Anti-Flag - Anti-Flag - Anti-Flag - Anti-Flag - Anti-Flag - Anti-Flag ├ ─ CuredAndDeadRateChart # cure rate and mortality rate chart │ ├ ─ the past week, the total cure chart │ CurrentConfirmedCompareBarChart # ├ ─ DataMap │ # data map └ ─ ProvinceRankingBarChart # cumulative ranking chart ├ ─ libs # some commonly used configuration ├ ─ the router # routing configuration ├ ─ utils # tools └ ─ views # view

Detailed structure:

conclusion

  1. The use of components to encapsulate each display chart, chart display and reuse can be better;
  2. useaxiosRequest a backend service or a local mock service to retrieve data and then reassign the data specified in the diagram.

Source code of the project: The source code of the project has been uploaded to GitHub, and you can find the address in my blog: Use Vue+ Datav +Echarts to create a large screen of COVID-19 epidemic data (which can be dynamically refreshed).

This project is a personal learning work with limited ability. It is inevitable that there will be bugs and mistakes. Please forgive me. If you have better suggestions or ideas, please point out, thank you