Since the beginning of 2020, the coronavirus has been rampant. Fortunately, the domestic epidemic has been gradually reduced and Wuhan has been lifted, while the epidemic abroad has become increasingly serious, which is not optimistic.

Create a visual map simulation to show the epidemic

We can see that all major apps have real-time maps showing the epidemic data of the whole country and even the world. How do they achieve this?

Let’s take China as an example to achieve a demonstration effect. Since I usually use Vue a lot, I used Echarts in my project before, so I used these two to demonstrate. (Note: All data are randomly generated and unofficial real data)

Quick build with VUE-CLI

vue create vue-echarts-map-china
Copy the code

The introduction of echarts

yarn add echarts -D 
Copy the code

How to present Chinese provincial data

ProvinceChart.vue

<template>
  <div class="chart" ref="chart" style="width: 100%; height: 800px"></div>
</template>
Copy the code

We first need to give Echarts a container

Reference JS/JSON map data

Js and China. json as well as their provincial map packages are built into Echats. When importing China. js, you can use China. json, which needs to be registered with Echarts

import echarts from "echarts";
import "echarts/theme/macarons"; // echarts theme // 1.china.js uses import China from directly"echarts/map/js/china"; // 2. China. json needs to register import China from"echarts/map/json/china";
echarts.registerMap("china", china);
Copy the code

The main structure

export default {
  name: "chart".data() {
    return {
      chart: null
    };
  },
  mounted() {
    if (!this.chart) {
      this.drawChinaMap();
    }
  },
  beforeDestroy() {
    if(! this.chart) {return;
    }
    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    drawChinaMap() {... }}};Copy the code

DrawChinaMap method in detail

First find our container and initialize echarts with echarts.init()

this.chart = echarts.init(document.querySelector(".chart"), "macarons");
this.chart.setOption({
  ...
})
Copy the code

Pass in the option parameters we need to set through setOption

Chart types and parameters

The most important thing is to set the chart type

series: [
  {
    name: "Data".type: "map",
    mapType: "china", // Corresponding to our registered"china"
    roam: true// Text label: {// text label normal: {show:true// Province name}, emphasis: {show:false}}, itemStyle: {normal: {show:true,
        areaColor: "#CECECE",
        borderColor: "#FCFCFC",
        borderWidth: "1"
      },
      emphasis: {
        show: true,
        areaColor: "#C8A5DF"} }, data: [ ... ] }]Copy the code

The most important is the data of 34 provinces, here we simulate (note that the format and name are fixed).

data: [
  { name: "Beijing", value: Math.round(Math.random() * 1000) },
  { name: "Tianjin", value: Math.round(Math.random() * 1000) },
  { name: "Shanghai", value: Math.round(Math.random() * 1000) },
  { name: "Chongqing", value: Math.round(Math.random() * 1000) },
  { name: "Hebei", value: Math.round(Math.random() * 1000) },
  { name: "Henan", value: Math.round(Math.random() * 1000) },
  { name: "Yunnan", value: Math.round(Math.random() * 1000) },
  { name: "Liaoning", value: Math.round(Math.random() * 1000) },
  { name: "Heilongjiang", value: Math.round(Math.random() * 1000) },
  { name: "Hunan", value: Math.round(Math.random() * 1000) },
  { name: "Anhui province", value: Math.round(Math.random() * 1000) },
  { name: "Shandong", value: Math.round(Math.random() * 1000) },
  { name: "Xinjiang", value: Math.round(Math.random() * 1000) },
  { name: "Jiangsu", value: Math.round(Math.random() * 1000) },
  { name: "Zhejiang", value: Math.round(Math.random() * 1000) },
  { name: "Jiangxi", value: Math.round(Math.random() * 1000) },
  { name: "Hubei", value: 9999 },
  { name: "Guangxi", value: Math.round(Math.random() * 1000) },
  { name: "Gansu", value: Math.round(Math.random() * 1000) },
  { name: "Shanxi", value: Math.round(Math.random() * 1000) },
  { name: Inner Mongolia, value: Math.round(Math.random() * 1000) },
  { name: "Shaanxi", value: Math.round(Math.random() * 1000) },
  { name: "Jilin", value: Math.round(Math.random() * 1000) },
  { name: "Fujian", value: Math.round(Math.random() * 1000) },
  { name: "Guizhou", value: Math.round(Math.random() * 1000) },
  { name: "Guangdong", value: Math.round(Math.random() * 1000) },
  { name: "Qinghai", value: Math.round(Math.random() * 1000) },
  { name: "Tibet", value: Math.round(Math.random() * 1000) },
  { name: "Sichuan", value: Math.round(Math.random() * 1000) },
  { name: "The ningxia", value: Math.round(Math.random() * 1000) },
  { name: "Hainan", value: Math.round(Math.random() * 1000) },
  { name: "Taiwan", value: Math.round(Math.random() * 1000) },
  { name: "Hong Kong", value: Math.round(Math.random() * 1000) },
  { name: "Macau", value: math.round (math.random () * 1000)}] // DataCopy the code

Other option Settings

backgroundColor: "#FFFFFF",
title: {
  text: "Big Data of National Map of Provinces and cities",
  subtext: "Fictitious data",
  x: "center"
},
tooltip: {
  trigger: "item"}, Toolbox: {// right side reset download show:true,
  orient: "vertical",
  right: "20",
  top: "center",
  feature: {
    mark: { show: true },
    restore: { show: true },
    saveAsImage: { show: true}}}, // visualMap: {show:true,
  x: "left",
  y: "center",
  splitList: [
    { start: 10000 },
    { start: 1000, end: 9999 },
    { start: 500, end: 999 },
    { start: 100, end: 499 },
    { start: 10, end: 99 },
    { start: 0, end: 9 }
  ],
  color: [
    "#a50026"."#d73027"."#f46d43"."#fdae61"."#fee090"."#ffffbf"."#f0f0f0"]},Copy the code

The effect is as follows:

How to present the data of Chinese cities

If it is easier to show the individual data for each city, just change the map and corresponding data into provinces

import hubei from "echarts/map/json/province/hubei";
echarts.registerMap("hubei", hubei);

series:[
  ...
  mapType: "hubei". ]Copy the code

You can also click on the province to switch into the city of the effect, there are corresponding online tutorials, the implementation method is also simple, not detailed introduction here.

But I want to see the whole map of China under the epidemic situation of the city?

Map of Merged provinces and cities

Since the official only provides json or JS packages of Chinese maps and separate maps of provinces and cities, but does not combine them together, we do not have ready data.

However, I noticed that json packages of China and provinces only have different features, as shown in the following figure:

china.features = [...new Set([...china.features, ...hubei.features])];
Copy the code

Eventually, I abandoned this approach for the following reasons:

  1. Poor visual effects:

As shown in the picture below, it is hard to see words at all, and dense without words

  1. Poor rendering:

Currently only one province is implemented, but it is predictable that with all the provinces there is a lot of data (features length will eventually be 533), rendering will get stuck

  1. There is an introduction delay problem:

Due to the need to import 34 provincial JSON packages separately and merge them into China, usually the Echarts components have already been rendered

Use a map of China to match the scatter chart

I found the official example of Scatter – VisualMap-Piecewise and felt that this method also met my requirements and rendered better

Option to change

The main difference from the original option is that Series uses scatter type and introduces the Geo coordinate system component

geo: {
  map: "china",
  roam: trueItemStyle: {itemStyle: {itemStyle: {itemStyle: {itemStyle: {itemStyle: {"#323c48",
      borderColor: "# 111"}, Emphasis: {// Highlight the style areaColor:"#2a333d"
    }
  }
},
series: [
  {
    name: "Number of confirmed cases", symbolSize: 10, // Point coordinate sizetype: "scatter",
    data: this.cityData,
    coordinateSystem: "geo"}]Copy the code

The data format is as follows

// this.cityData
{
  ...
  { name: "Wuhan", value: [114.31, 30.52, 8888}], // {name: name, value: [x, y, value}], {name:"Daqing", value: [125.03, 46.58, Math.round(Math.random() * 100) }]
}
Copy the code

Sample trivia

Note that the dangling data in the tooltip in the official example is problematic. It is not the value of PM2.5, but the Y value of polar coordinates

To display the correct data, set the formatter in tooltip: set the data as the third piece of data in the callback function format

tooltip: {
  trigger: "item",
  formatter: params => {
    return (
      params.seriesName + "<br/>" + params.name + ":"+ params.data.value[2] ); }}Copy the code

In addition, geo data in the example is also incomplete, and complete Geo data in China can be obtained through datav.

The final effect is as follows:

conclusion

So far, we have completed the visualization of epidemic simulation data of various provinces and cities in China. If we want to show the world data similarly, we only need to find the corresponding map package to replace and process the corresponding data. Echarts provides complete documentation, and there are plenty of libraries and methods to explore.

To see the full code: click here

See here, don’t point a praise 😄!