实时疫情数据可视化

数据获取

        腾讯提供的接口:https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5

技术栈

sass、 vue-router 、vue3、echarts、axios

效果图

注:相关数据是通过腾讯的接口,获取的19日的数据,在此仅做展示,不要谣传。

一、构建项目:

        之前使用过webpack构建项目,后来把学习中心放在vue上,所以一直都是使用vue官方的脚手架搭建项目。这次构建这各项目使用到vite去初始化,主要是因为看到其他同学的文章,想要体验一下。

        具体搭建过程可以参照官网的流程(开始 | Vite 官方中文文档 (vitejs.dev))。总的来说,给人的感觉还是不错的,打包速度可以明显感觉到比用脚手架搭建的项目块,这还是在代码量少的时候,不知道在更大型的项目下效果如何,反正现在是对vite来兴趣了。先收藏,找时间在好好宠幸^_^ ^_^。

这里不得不说一下vite好处,之前写样式都没使用过诸如sass、scss等css预处理器,就是看到教程中讲到的要使用css预处理器要进行一系列的配置,暂时还不想了解。vite支持css预处理开箱即用,安装好依赖就行了,是真的方便(npm i sass),也幸好之前虽然没理清楚配置流程,但是着重看了一下使用,还记得语法,真是不幸中的万幸。相较于传统的css语法,市面上的预处器的语法主要是使css的结构更加清晰,不易出错,有点类似与node树结构,其他的没有多大差别。不是太大型项目也用不到变量这些,总体来说还是可以去学习一下,对项目有帮助。

二,代码

通过效果图可以看到这个项目其实非常简洁。我这儿通过接口拿到数据后只使用了四川省的数据,结合echarts,展现了map这种数据可视化形式。如果你还想使用折线图、柱状图等形式来展现数据,可以去echats官方网站逛逛,看一下使用。

我分了三个组件来构建按这个页面。

1.头部图和标题为一个组件,上图没截出来。

2.中间悬浮样式那块为一个组件,用数值直观的展示。

3.map形式展示数据为一个组件。

看到上图,能够猜出我其实还想做全国实时疫情数据展示,但逻辑都差不多,无非再用下vue-router在写个页面展示数据,都是些重复性工作,所以这里偷了懒。有兴趣的同学可以自己完善。

主要逻辑: 在App.vue中用axios获取数据(方便传到子组件或者页面使用)---分析数据的结构和key的含义 ----用echarts展示数据。

最难应该就是最后一步,因为有些同学没使用过echarts这个插件,或者没有深入了解学习过使用起来不熟练。最耗时的确是第二步,因为不是自己的数据,你不了解结构,需要自己一点一点的去找,结果这数据还贼多,眼睛都给我看花了。不要怕我给大家都整理好了要用的数据的结构和key的含义。

第二步

各省的数据实在 “children”这个数组里面的,如下是四川的,其他都一样(香港,台湾要注意)

 各市的数据放在“children”这个数组里面,全国、各省、各市的结构都差不多。

"today" 和 "total"的内容都差不多,需要用到的数据也标出来了,如果你还想要使用其他数据,可以自己去查找含义使用。

第三步

echarts的使用

<script setup>
    import * as echarts from 'echarts';
    import { ref, reactive, onMounted, computed } from 'vue';
    //https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5 腾讯疫情数据
    import sc from '../assets/sc.json'; 
    import scmap from '../assets/scmap.json';
    
    let conmodule = ref('cum')
    
    echarts.registerMap('sichuan', scmap);
    
	var showda = ref(null)
	//数据可视化
	var alldata = reactive({
        //标题
        title: {
            text:'点击市区查看疫情详情',
        },
        // 点击出现提示框
        tooltip: {
            trigger: 'item',
            transitionDuration: 0.2
        },
        visualMap: {
            left: 'right',
            min: 0,
            max: conmodule.value == 'now'? sc.total.nowConfirm : sc.total.provinceLocalConfirm,
            inRange: {
                color: [
                  '#fee090',
                  '#f46d43',
                  '#a50026'
                ]
              },
            text: ['high', 'Low'],
            calculable: true,
        },
		series: [
			{
                name: '累计确诊人数',
				type: 'map',
                map: 'sichuan',
                // 数据
                data: confirmObj(conmodule.value)
			},
		]
    })
    // 各市的确诊人数
    function confirmObj(val) {
        let confirmdata = []
        if(val == 'cum'){
            sc.children.map((item) => {
                confirmdata.push({name: item.name, value: item.total.confirm})
            })
            confirmdata.splice(2,1)
            confirmdata.splice(-1,1)
            return confirmdata
        }
        if(val == 'now'){
            sc.children.map((item) => {
                confirmdata.push({name: item.name, value: item.total.nowConfirm})
            })
            confirmdata.splice(2,1)
            confirmdata.splice(-1,1)
            return confirmdata
        }
        
    }
    
    // 地图数据
    // function chinamapdata() {
    //     echarts.registerMap('sichuan', scmap);
    //     
    //     let myChart = echarts.init(showda.value);
    //     myChart.setOption(alldata);
    // }
    let myChart
	onMounted(() =>{
        // 初始化echarts实例
        myChart = echarts.init(showda.value);
        // 把数据渲染上去
        myChart.setOption(alldata);
	})
    
    function nowcon() {
        if( conmodule.value = 'cum') {
            conmodule.value = 'now'
        }
        alldata.visualMap.max = sc.total.nowConfirm;
        alldata.series[0].data = confirmObj(conmodule.value)
        myChart.setOption(alldata);
    }
    function cumcon() {
        if( conmodule.value = 'now') {
            conmodule.value = 'cum'
        }
        alldata.visualMap.max = sc.total.provinceLocalConfirm;
        alldata.series[0].data = confirmObj(conmodule.value);
        myChart.setOption(alldata);
    }
</script>

<template>
	<div class="chinamap">
        <div ref="showda" class="showmap"></div>
        <div class="but">
            <button :class=" conmodule == 'now'&&'active'" @click="nowcon" >现有确诊</button>
            <button :class=" conmodule == 'cum'&&'active'" @click="cumcon" >累计确诊</button>
        </div>
    </div>
</template>

<style lang="scss" scoped>
    .showmap{
        width: 100%;
        height: 375px;
    }
    .but{
        display: flex;
        justify-content: space-around;
        
        >button{
            width: 30%;
            height: 30px;
            background-color: #ffffff;
            border: 1px solid #ebebeb;
            border-radius: 5px;
        }
        
        .active{
            background-color: #fef9f8;
            border: 1px solid #e6c2b9;
        }
    }
</style>

这里只简单使用echarts做数据展示,如果想做更加全面炫酷的数据化展示可以去了解echarts官方文档。

初始化地图要使用GeoJSON文件,(首页 | GeoJSON.cn)可以去这个官网获取。


版权声明:本文为WYHID原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。