疫情地图数据展示平台

疫情数据地图展示

中国地图的实现

  先看一下效果图吧。
在这里插入图片描述

  整个项目是在vue框架下完成的,在完成了路由配置后,就可以开始做地图的展示部分了。在这里只展示国内疫情部分也就是我自己独立完成的部分。

地图样式

  地图的部分主要是用的echart插件来封装完成的。具体的地图的option如下

      getMapOpt(place) {
           let option = option = {
             title:{
               text:"现有确诊不包含死亡病例和治愈病例",
               textStyle:{
                 color:"#ccc",
                 fontSize:16,
                 fontWeight:'normal'
                 },
               left:'center',
               top:'10'
             },
             textStyle: {
               fontSize: 10
             },
             tooltip: {
               trigger: 'item',
               formatter: function(params) {
                 //console.log(params);
                
                    return (params.data.name + "<br>现有确诊:" + params.data.value)
                   

               }
             },
             visualMap: {
               type: 'piecewise',
               pieces: [{
                   gte: 10000,
                   color: '#B80909'
                 },
                 {
                   gte: 1000,
                   lte: 9999,
                   color: '#E85B5B'
                 },
                 {
                   gte: 100,
                   lte: 999,
                   color: '#F57567'
                 },
                 {
                   gte: 10,
                   lte: 99,
                   color: '#FF9985'
                 },
                 {
                   gte: 1,
                   lte: 9,
                   color: '#FFE5DB'
                 },
                 {
                   value: 0,
                   color: '#fff'
                 }
               ],
             },
             series: [{
               name: '确诊数量',
               type: 'map',
               mapType: place ? place : 'china',
               roam: true,
               zoom: 1,
               label: {
                 normal: {
                   show: true
                 }
               },

               emphasis: {
                 itemStyle: {
                   areaColor: "#95F3F1",
                 },
                 label: {
                   color: "#fff"
                 }
               },
               data:this.initdata(place)

             }]
           }
           return option
         },

option里面的data部分,我用initdata函数做了处理 ,这个放在后面陈述。配置好option后,就可以看到灰色的中国地图。接下来就是填充数据。

数据填充

  首先准备好json 文件,我的json文件是调用了网上的免费接口,然后打印出来复制到本地得到的。嗯,废话不多说,调用json文件,存到data里面。由于echart地图的格式与json的格式不一,所以再拿到数据后还是需要重新赋值一次。对数据处理的代码如下。

 getHomeInfo(){
            	/* axios.get('static/mock/China.json')
            	.then(this.getHomeInfoSucc) */
              axios.get('http://localhost:3000/chinalist')
              .then(this.getHomeInfoSucc).then(this.initMap())
            },
            getHomeInfoSucc(res){
            	res = res.data
             // console.log(res);
            	if( res.data){
            		const data = res.data
              // console.log(data);
                for (var i = 0;i< data.Chinalist.length;i++)
                {


                  this.confirmedlist.push({
                    name:data.Chinalist[i].provinceShortName,
                    value:data.Chinalist[i].confirmedCount,
                    cities:[
                      data.Chinalist[i].cities
                    ]
                  })
                }

            	}
             // console.log(this.rightdata);
            },

由于后面还要 实现地图下沉的功能,所以我在这里也获取了省级地图的数据。拿到数据后,在option里面给data赋值就好了。由于我这里只有最终完成的代码,可以看到上方描述的地图样式代码中的data是initdata()。在没有做地图下沉的时候,自己填充this.confirmedlist即可。
我的json文件结构如下:

{
   "data": {
     "Chinalist": [{
         "provinceName": "香港",
         "provinceShortName": "香港",
         "currentConfirmedCount": 51,
         "confirmedCount": 1093,
         "suspectedCount": 63,
         "curedCount": 1038,
         "deadCount": 4,
         "comment": "疑似1例",
         "locationId": 810000,
         "cities": []
       }, {
         "provinceName": "内蒙古自治区",
         "provinceShortName": "内蒙古",
         "currentConfirmedCount":0,
         "confirmedCount": 77,
         "suspectedCount": 0,
         "curedCount": 76,
         "deadCount": 1,
         "comment": "",
         "locationId": 150000,
         "cities": [ {
           "cityName": "鄂尔多斯市",
           "currentConfirmedCount": 0,
           "confirmedCount": 11,
           "suspectedCount": 0,
           "curedCount": 11,
           "deadCount": 0,
           "locationId": 150600
         }
                  }]
       }]
       }
       
地图下沉

  在实现地图下沉之前,需要拿到中国所有省份的地图json文件。大致思路就是,点击了地图 之后拿到echart地图param参数,根据点击的省份名称去重新加载省份的地图和省份城市的数据。在设置option的时候传入拿到的省份名称的参数,就可以显示出对应的省份地图。代码如下

<script>
    import axios from 'axios'
    import echarts from 'echarts'
    import "echarts/map/js/china.js"
    var provinces = ['shanghai', 'hebei', 'shanxi1', 'neimenggu', 'liaoning',
                      'jilin', 'heilongjiang', 'jiangsu','zhejiang', 'anhui',
                      'fujian', 'jiangxi', 'shandong', 'henan', 'hubei',
                      'hunan', 'guangdong', 'guangxi', 'hainan',    'sichuan',
                      'guizhou', 'yunnan', 'xizang', 'shanxi', 'gansu',
                      'qinghai', 'ningxia', 'xinjiang', 'beijing',
                       'tianjin', 'chongqing', 'xianggang', 'aomen', 'taiwan'
    ];
    var provincesText = ['上海', '河北', '山西', '内蒙古', '辽宁',
      '吉林', '黑龙江', '江苏', '浙江', '安徽',
      '福建', '江西', '山东', '河南', '湖北', '湖南',
      '广东', '广西', '海南', '四川', '贵州', '云南',
      '西藏', '陕西', '甘肃', '青海', '宁夏', '新疆',
      '北京', '天津', '重庆', '香港', '澳门', '台湾'
    ];
   export default {
       name: 'mapcurrent',
       data(){
         return{
           cities:[]
         }
       },
       methods: {
         initdata(place){
           var provinceIndex
           for(var i in provinces){
             if(provinces[i] === place)
             {
               provinceIndex = i
             }
           }
           place = provincesText[provinceIndex]
           if(place){


             var list = JSON.parse(this.$route.query.currentlist);
              var index;
             for (var i in list){
               //console.log(i);
               var name = list[i].name
               if(name === place){
                 index = i;
               }
             }


             var cities = list[index].cities[0]
             //console.log(list[3].cities);

             for (var i of cities)
             {
               //console.log(i)
               this.cities.push({
                 name:i.cityName,
                 value:i.currentConfirmedCount
               })
             }
             //console.log(this.cities);
             return this.cities

           }
           else{
            return JSON.parse(this.$route.query.currentlist)
           }
         },
         getMapOpt(place) {
           let option = option = {
             title:{
               text:"现有确诊不包含死亡病例和治愈病例",
               textStyle:{
                 color:"#ccc",
                 fontSize:16,
                 fontWeight:'normal'
                 },
               left:'center',
               top:'10'
             },
             textStyle: {
               fontSize: 10
             },
             tooltip: {
               trigger: 'item',
               formatter: function(params) {
                 //console.log(params);
                
                    return (params.data.name + "<br>现有确诊:" + params.data.value)
                   

               }
             },
             visualMap: {
               type: 'piecewise',
               pieces: [{
                   gte: 10000,
                   color: '#B80909'
                 },
                 {
                   gte: 1000,
                   lte: 9999,
                   color: '#E85B5B'
                 },
                 {
                   gte: 100,
                   lte: 999,
                   color: '#F57567'
                 },
                 {
                   gte: 10,
                   lte: 99,
                   color: '#FF9985'
                 },
                 {
                   gte: 1,
                   lte: 9,
                   color: '#FFE5DB'
                 },
                 {
                   value: 0,
                   color: '#fff'
                 }
               ],
             },
             series: [{
               name: '确诊数量',
               type: 'map',
               mapType: place ? place : 'china',
               roam: true,
               zoom: 1,
               label: {
                 normal: {
                   show: true
                 }
               },

               emphasis: {
                 itemStyle: {
                   areaColor: "#95F3F1",
                 },
                 label: {
                   color: "#fff"
                 }
               },
               data:this.initdata(place)

             }]
           }
           return option
         },
         //显示中国地图
         showChinaMap() {
           let option = this.getMapOpt()
           this.map.setOption(option, true);
         },
         //显示各省地图
         getProvinceMapOpt(provinceAlphabet) {
           axios.get('http://localhost:3000/province',{
             params:{
               province:provinceAlphabet
             }
           }).then((s) => {
             echarts.registerMap(provinceAlphabet, s.data)
             let option = this.getMapOpt(provinceAlphabet)
             this.map.setOption(option, true);
           })
         },
         initMap() {

           this.map = echarts.init(this.$refs.chart1);
           let option = this.getMapOpt()
           if (option && typeof option === "object") {
             this.map.setOption(option, true);
           }
           this.map.on('click', (param) => {
             event.stopPropagation() // 阻止冒泡
             // 找到省份名
             let provinceIndex = provincesText.findIndex(x => {
               return param.name === x
             })
             if (provinceIndex === false) return
             let provinceAlphabet = provinces[provinceIndex]
             // 重新渲染各省份地图
             this.getProvinceMapOpt(provinceAlphabet)
           })
         }


       },
       created() {

       },
       mounted() {
           this.$nextTick(function(){
             this.initMap();
           })


       },


     }
   </script>

代码中initdata函数部分,是对接收的数据部分的处理。

后台

后台部分就比较简单,直接上代码吧

var express = require("express"); //首先引入express模块,不了解去看nodejs教程 安装:npm install express

var app = express();

var fs = require("fs"); // 文件系统,引入user.json的数据 也可以自己随便写个数据 ;
var path = require('path');



var cors = require("cors");// 这个比较重要,解决跨域问题.npm install cors 装一下

app.use(cors({

origin: ['http://localhost:8080'], // 这是本地的默认地址和端口,vue启动的项目就是在这里,这样保证了等会我们在浏览器能访问服务器的数据(user.json)

methods: ["GET", "POST"],

alloweHeaders: ["Content-Type", "Authorization"]

}))



app.get("/chinalist", function (req, res) { //"/user" 是自定义的,用于显示在地址栏

fs.readFile(__dirname + "/" + "China.json", "utf-8", function (err, data) { // __dirname是文件夹的名,我们用fs读取China.json

res.end(data) // 然后把读取的文件通过 res.end()发送给客户端

})
const url= require('url');
app.get("/province",function(req,res){
  var province = url.parse(req.url,true).query.province;
  fs.readFile(__dirname+"/"+"province"+"/"+province+".json","utf-8",function(err,data){
    res.end(data)
  })
})

});

var server = app.listen(3000, function () { // 设置服务端端口为3000,即:http://127.0.0.1:3000

var host = server.address().address

var port = server.address().port

console.log("应用实例,访问地址为 http://%s:%s", host, port)

})

可以看到,当点击到省份地图的时候,就用传递的参数来决定获取省份的json文件。注意获取请求参数,需要调用一下parse方法。

两侧排名实现

对于两侧的排名实现,就是拿到数据之后,直接展示就可以了。值得一提的是,根据某个对象属性对数组排序。代码如下:

<script>
  function sortKey(array,key){
    return array.sort(function(a,b){
      var x = a[key];
      var y = b[key];
      if(x<y){
        return 1
      }else if(x>y){
        return -1
      }else {
        return 0
      }

    })
  }
export default{
  name:"LeftMap",
  props:{
    top50:Array,
  },
  computed:{
    sortList(){
      return sortKey(this.top50,"confirmedCount")
    }
  }



}

</script>

然后展示出来就可以了

 <ul>
      <div class="title">国内全省累计确诊病例 </div>
    	<li v-for="(item,index) in sortList">
        <div class="num">Top{{index+1}}&nbsp;&nbsp;{{item.confirmedCount}}</div>
        <div class="cityname">疫情地区:{{item.name}}</div>
      </li>
    </ul>

关于echart的饼图和左侧时间的显示比较简单,我就不在这里多说了,关于echart地图的配置可以去官网上面看,另外官网上也有很多实例。
码字不易,点个赞吧。在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值