如果让你展示国内各省市疫情数据你会怎么做

2020 年初始至今,冠状病毒肆虐,好在国内疫情已经逐步减少,武汉也解封了,而国外疫情却日益严重,不容乐观。

做个可视化地图模拟展示一下疫情

我们可以看到,各大 APP 都有实时显示全国乃至世界的疫情数据的地图表,那么它们是如何实现的呢?

让我们以中国为例,实现一下展示效果。由于平时用 Vue 较多,可视化框架之前在项目中用过 echarts,就用这两个来演示。(注:本次数据都是随机生成,非官方真实数据)

用 vue-cli 快速搭建

vue create vue-echarts-map-china

引入 echarts

yarn add echarts -D 

如何展示中国各省数据

ProvinceChart.vue


我们首先需要给 echarts 一个容器

引用 js/json 地图数据

echats 内置了 china.js 和 china.json 及其省市地图包,china.js 引入即可使用 china.json 需要注册到 echarts,两种方式任选

import echarts from "echarts";
import "echarts/theme/macarons"; // echarts 主题

// 1. china.js 直接使用
import china from "echarts/map/js/china";

// 2. china.json 需注册
import china from "echarts/map/json/china";
echarts.registerMap("china", china);

主要结构

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(){
      ...
    }
  }
};

drawChinaMap 方法详解

首先找到我们的容器用 echarts.init() 初始化 echarts

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

通过 setOption 传入我们需要设定的选项参数

图表类型及参数

最主要的是设置图表类型了

series: [
  {
    name: "数据",
    type: "map",
    mapType: "china", // 对应我们注册好的 "china"
    roam: true, // 是否可缩放
    label: { // 文本标签
      normal: {
        show: true //省份名称
      },
      emphasis: {
        show: false
      }
    },
    // 地图默认样式
    itemStyle: {
      normal: {
        show: true,
        areaColor: "#CECECE",
        borderColor: "#FCFCFC",
        borderWidth: "1"
      },
      emphasis: {
        show: true,
        areaColor: "#C8A5DF"
      }
    },
    data: [
      ...
    ]
  }
]

最重要的是 34 个省份的数据,这里我们模拟一下(注意格式和 name 是固定的)

data: [
  { name: "北京", value: Math.round(Math.random() * 1000) },
  { name: "天津", value: Math.round(Math.random() * 1000) },
  { name: "上海", value: Math.round(Math.random() * 1000) },
  { name: "重庆", value: Math.round(Math.random() * 1000) },
  { name: "河北", value: Math.round(Math.random() * 1000) },
  { name: "河南", value: Math.round(Math.random() * 1000) },
  { name: "云南", value: Math.round(Math.random() * 1000) },
  { name: "辽宁", value: Math.round(Math.random() * 1000) },
  { name: "黑龙江", value: Math.round(Math.random() * 1000) },
  { name: "湖南", value: Math.round(Math.random() * 1000) },
  { name: "安徽", value: Math.round(Math.random() * 1000) },
  { name: "山东", value: Math.round(Math.random() * 1000) },
  { name: "新疆", value: Math.round(Math.random() * 1000) },
  { name: "江苏", value: Math.round(Math.random() * 1000) },
  { name: "浙江", value: Math.round(Math.random() * 1000) },
  { name: "江西", value: Math.round(Math.random() * 1000) },
  { name: "湖北", value: 9999 },
  { name: "广西", value: Math.round(Math.random() * 1000) },
  { name: "甘肃", value: Math.round(Math.random() * 1000) },
  { name: "山西", value: Math.round(Math.random() * 1000) },
  { name: "内蒙古", value: Math.round(Math.random() * 1000) },
  { name: "陕西", value: Math.round(Math.random() * 1000) },
  { name: "吉林", value: Math.round(Math.random() * 1000) },
  { name: "福建", value: Math.round(Math.random() * 1000) },
  { name: "贵州", value: Math.round(Math.random() * 1000) },
  { name: "广东", value: Math.round(Math.random() * 1000) },
  { name: "青海", value: Math.round(Math.random() * 1000) },
  { name: "西藏", value: Math.round(Math.random() * 1000) },
  { name: "四川", value: Math.round(Math.random() * 1000) },
  { name: "宁夏", value: Math.round(Math.random() * 1000) },
  { name: "海南", value: Math.round(Math.random() * 1000) },
  { name: "台湾", value: Math.round(Math.random() * 1000) },
  { name: "香港", value: Math.round(Math.random() * 1000) },
  { name: "澳门", value: Math.round(Math.random() * 1000) }
] //数据

其他选项设置

backgroundColor: "#FFFFFF",
title: {
  text: "全国省市地图大数据",
  subtext: "虚构数据",
  x: "center"
},
tooltip: {
  trigger: "item"
},
toolbox: { // 右侧复位下载
  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"
  ]
},

效果如下:

如何展示中国各市数据

如果要展示各市单独数据较为简单,只需要把地图和对应数据变成省即可

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

series:[
  ...
  mapType: "hubei",
  ...
]

你还可以做到点击省切换成市的效果,网上也有相应教程,实现方法也简单,这里不作详细介绍。

但是我想要看整个中国地图下的市的疫情情况怎么办?

合并省市地图

由于官方只提供了中国地图和省市分开的地图 json 或 js 包,而没有合并在一起的,我们没有现成的数据。

然而我注意到,china 和各省的 json 包只是 features 不同,如下图所示:

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

最终,这种方法被我放弃了,原因如下:

  1. 视觉效果差:

如下图,有字根本看不清,没字也会很密集

  1. 渲染效果差:

目前只实现了一个省,可预见的是加上所有省份数据量很大(features 长度最终会是 533 ),渲染会卡顿

  1. 有引入延迟问题:

由于需要将 34 个省 JSON 包分别引入后合并到 china 内部,通常 echarts 组件已经渲染完毕

使用中国地图配合市散点图

我找到官方提供的scatter-visualMap-piecewise示例,感觉这种方式也能满足我的要求,且呈现效果更好

选项变化

与原选项主要区别是 series 使用 scatter 散点类型,同时引入 geo 地理坐标系组件

geo: {
  map: "china",
  roam: true,
  itemStyle: {
    // 定义样式
    normal: {
      // 普通状态下的样式
      areaColor: "#323c48",
      borderColor: "#111"
    },
    emphasis: {
      // 高亮状态下的样式
      areaColor: "#2a333d"
    }
  }
},
series: [
  {
    name: "确诊人数",
    symbolSize: 10, // 点坐标大小
    type: "scatter",
    data: this.cityData,
    coordinateSystem: "geo"
  }
]

其数据格式如下

// this.cityData
{
  ...
  { name: "武汉", value: [114.31, 30.52, 8888 }], // { name: name, value: [x, y, value}],
  { name: "大庆", value: [125.03, 46.58, Math.round(Math.random() * 100) }]
}

示例小问题

需要注意的是,官方示例中 tooltip 的悬浮数据是有问题的,它不是 pm2.5 的 value,而是极坐标的 Y 的值

想要其展示正确的数据需要在 tooltip 设置 formatter:以回调函数格式设置数据为 data 的第三个数据

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

另外,示例中 geo 数据也是不完整的,可通过 datav 获取完整中国 geo 数据。

最终效果如下:

总结

至此,我们完成了国内各省市疫情模拟数据的可视化,如果想要展示世界数据也是类似,只需找到相应地图包替换,并处理对应数据即可。echarts 提供了完整的文档,按需查找对应选项即可完成相应需求,当然还有很多不错的库和方法等我们去探究。

如需查看完整代码:请点这里

看到这里了,不点个赞吗!

你可能感兴趣的:(如果让你展示国内各省市疫情数据你会怎么做)