Epidemic map data display platform

Epidemic data map display

The realization of Chinese map

First look at the renderings.

The whole project is completed under the vue framework. After the routing configuration is completed, you can start the map display part. Here I will only show the domestic epidemic part, which I have completed independently.

Map style

The part of the map is mainly encapsulated by the Eckart plug-in. The specific map option s are as follows

      getMapOpt(place) {
           let option = option = {
             title:{
               text:"The current diagnosis does not include dead cases and cured cases",
               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>Current diagnosis:" + 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: 'Number of confirmed cases',
               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
         },

In the data part of option, I used the initdata function to do the processing, which will be stated later. After the option is configured, you can see the gray map of China. The next step is to fill in the data.

Data filling

First, prepare the json file. My json file calls the free interface on the Internet, and then prints it and copies it to the local. Well, no more nonsense. Call the json file and save it in data. Since the format of echart map is different from that of json, it is necessary to re assign the data after getting the data again. The code for data processing is as follows.

 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);
            },

Since the function of map sinking is to be realized later, I also get the data of provincial map here. After getting the data, you can assign a value to data in option. Since I only have the final code here, you can see that the data in the map style code described above is initdata(). Fill in the map without sinking it this.confirmedlist Just.
My json file structure is as follows:

{
   "data": {
     "Chinalist": [{
         "provinceName": "Hong Kong",
         "provinceShortName": "Hong Kong",
         "currentConfirmedCount": 51,
         "confirmedCount": 1093,
         "suspectedCount": 63,
         "curedCount": 1038,
         "deadCount": 4,
         "comment": "Suspected 1 case",
         "locationId": 810000,
         "cities": []
       }, {
         "provinceName": "Inner Mongolia Autonomous Region",
         "provinceShortName": "Inner Mongolia",
         "currentConfirmedCount":0,
         "confirmedCount": 77,
         "suspectedCount": 0,
         "curedCount": 76,
         "deadCount": 1,
         "comment": "",
         "locationId": 150000,
         "cities": [ {
           "cityName": "ordos city ",
           "currentConfirmedCount": 0,
           "confirmedCount": 11,
           "suspectedCount": 0,
           "curedCount": 11,
           "deadCount": 0,
           "locationId": 150600
         }
                  }]
       }]
       }
       

Map sinking

Before sinking the map, you need to get the json file of all provinces in China. The general idea is to get the param parameter of echart map after clicking the map, and reload the map of the province and the data of the city of the province according to the name of the province clicked. When setting option, you can pass in the parameter of the name of the province you get, and the corresponding province map will be displayed. The code is as follows

<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 = ['Shanghai', 'Hebei', 'Shanxi', 'Inner Mongolia', 'Liaoning',
      'Jilin', 'Heilongjiang', 'Jiangsu', 'Zhejiang', 'Anhui',
      'Fujian', 'Jiangxi', 'Shandong', 'Henan', 'Hubei', 'Hunan',
      'Guangdong', 'Guangxi', 'Hainan', 'Sichuan', 'Guizhou', 'Yunnan',
      'Tibet', 'Shaanxi', 'Gansu', 'Qinghai', 'Ningxia', 'Xinjiang',
      'Beijing', 'Tianjin', 'Chongqing', 'Hong Kong', 'Macao', 'Taiwan'
    ];
   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:"The current diagnosis does not include death and cure cases",
               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>Current diagnosis:" + 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: 'Number of confirmed cases',
               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
         },
         //Show China Map
         showChinaMap() {
           let option = this.getMapOpt()
           this.map.setOption(option, true);
         },
         //Show map of provinces
         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() // Prevent blistering
             // Province name found
             let provinceIndex = provincesText.findIndex(x => {
               return param.name === x
             })
             if (provinceIndex === false) return
             let provinceAlphabet = provinces[provinceIndex]
             // Re render the map of each province
             this.getProvinceMapOpt(provinceAlphabet)
           })
         }


       },
       created() {

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


       },


     }
   </script>

The initdata function part of the code deals with the received data part.

backstage

The background part is relatively simple, go to the code directly

var express = require("express"); //First, introduce the express module. If you don't understand, go to the nodejs tutorial installation: npm install express

var app = express();

var fs = require("fs"); // File systems, importing user.json You can write your own data ;
var path = require('path');



var cors = require("cors");// This is more important to solve cross domain problems.npm install cors Put it on

app.use(cors({

origin: ['http://localhost:8080'], // This is the local default address and port. This is where the vue started the project. This ensures that we can access the server's data in the browser later( user.json )

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

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

}))



app.get("/chinalist", function (req, res) { //"/user" Is custom for display in the address bar

fs.readFile(__dirname + "/" + "China.json", "utf-8", function (err, data) { // Wei dirname is the name of the folder. We use fs to read it China.json

res.end(data) // Then pass the read file res.end()Send to client

})
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 () { // Set the server port to 3000, that is: http://127.0.0.1:3000

var host = server.address().address

var port = server.address().port

console.log("Application instance, access address is http://%s:%s", host, port)

})

As you can see, when you click the province map, you can use the parameters passed to determine the json file of the province. Note that to get the request parameters, you need to call the parse method.

Ranking on both sides

For the realization of ranking on both sides, it's just after getting the data, you can display it directly. It is worth mentioning that arrays are sorted according to an object property. The code is as follows:

<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>

And then show it

 <ul>
      <div class="title">Accumulated confirmed cases in the whole province of China </div>
    	<li v-for="(item,index) in sortList">
        <div class="num">Top{{index+1}}&nbsp;&nbsp;{{item.confirmedCount}}</div>
        <div class="cityname">Epidemic area:{{item.name}}</div>
      </li>
    </ul>

It's not easy to code. Please like it.

Keywords: JSON axios Vue npm

Added by paulspoon on Sun, 14 Jun 2020 12:26:34 +0300