2020 年初始至今返干,冠狀病毒肆虐谦疾,好在國內(nèi)疫情已經(jīng)逐步減少,武漢也解封了犬金,而國外疫情卻日益嚴(yán)重念恍,不容樂觀。
做個可視化地圖模擬展示一下疫情
我們可以看到晚顷,各大 APP 都有實時顯示全國乃至世界的疫情數(shù)據(jù)的地圖表峰伙,那么它們是如何實現(xiàn)的呢?
讓我們以中國為例该默,實現(xiàn)一下展示效果瞳氓。由于平時用 Vue 較多,可視化框架之前在項目中用過 echarts栓袖,就用這兩個來演示匣摘。(注:本次數(shù)據(jù)都是隨機生成,非官方真實數(shù)據(jù))
用 vue-cli 快速搭建
vue create vue-echarts-map-china
引入 echarts
yarn add echarts -D
如何展示中國各省數(shù)據(jù)
ProvinceChart.vue
<template>
<div class="chart" ref="chart" style="width: 100%; height: 800px"></div>
</template>
我們首先需要給 echarts 一個容器
引用 js/json 地圖數(shù)據(jù)
echats 內(nèi)置了 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);
主要結(jié)構(gòu)
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 傳入我們需要設(shè)定的選項參數(shù)
圖表類型及參數(shù)
最主要的是設(shè)置圖表類型了
series: [
{
name: "數(shù)據(jù)",
type: "map",
mapType: "china", // 對應(yīng)我們注冊好的 "china"
roam: true, // 是否可縮放
label: { // 文本標(biāo)簽
normal: {
show: true //省份名稱
},
emphasis: {
show: false
}
},
// 地圖默認(rèn)樣式
itemStyle: {
normal: {
show: true,
areaColor: "#CECECE",
borderColor: "#FCFCFC",
borderWidth: "1"
},
emphasis: {
show: true,
areaColor: "#C8A5DF"
}
},
data: [
...
]
}
]
最重要的是 34 個省份的數(shù)據(jù),這里我們模擬一下(注意格式和 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: "內(nèi)蒙古", 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) }
] //數(shù)據(jù)
其他選項設(shè)置
backgroundColor: "#FFFFFF",
title: {
text: "全國省市地圖大數(shù)據(jù)",
subtext: "虛構(gòu)數(shù)據(jù)",
x: "center"
},
tooltip: {
trigger: "item"
},
toolbox: { // 右側(cè)復(fù)位下載
show: true,
orient: "vertical",
right: "20",
top: "center",
feature: {
mark: { show: true },
restore: { show: true },
saveAsImage: { show: true }
}
},
// 左側(cè)小導(dǎo)航圖標(biāo)
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"
]
},
效果如下:
如何展示中國各市數(shù)據(jù)
如果要展示各市單獨數(shù)據(jù)較為簡單捧弃,只需要把地圖和對應(yīng)數(shù)據(jù)變成省即可
import hubei from "echarts/map/json/province/hubei";
echarts.registerMap("hubei", hubei);
series:[
...
mapType: "hubei",
...
]
你還可以做到點擊省切換成市的效果赠叼,網(wǎng)上也有相應(yīng)教程,實現(xiàn)方法也簡單违霞,這里不作詳細(xì)介紹嘴办。
但是我想要看整個中國地圖下的市的疫情情況怎么辦?
合并省市地圖
由于官方只提供了中國地圖和省市分開的地圖 json 或 js 包买鸽,而沒有合并在一起的涧郊,我們沒有現(xiàn)成的數(shù)據(jù)。
然而我注意到眼五,china 和各省的 json 包只是 features 不同妆艘,如下圖所示:
china.features = [...new Set([...china.features, ...hubei.features])];
最終,這種方法被我放棄了弹砚,原因如下:
- 視覺效果差:
如下圖双仍,有字根本看不清,沒字也會很密集
- 渲染效果差:
目前只實現(xiàn)了一個省桌吃,可預(yù)見的是加上所有省份數(shù)據(jù)量很大(features 長度最終會是 533 )朱沃,渲染會卡頓
- 有引入延遲問題:
由于需要將 34 個省 JSON 包分別引入后合并到 china 內(nèi)部,通常 echarts 組件已經(jīng)渲染完畢
使用中國地圖配合市散點圖
我找到官方提供的scatter-visualMap-piecewise示例,感覺這種方式也能滿足我的要求逗物,且呈現(xiàn)效果更好
選項變化
與原選項主要區(qū)別是 series 使用 scatter 散點類型搬卒,同時引入 geo 地理坐標(biāo)系組件
geo: {
map: "china",
roam: true,
itemStyle: {
// 定義樣式
normal: {
// 普通狀態(tài)下的樣式
areaColor: "#323c48",
borderColor: "#111"
},
emphasis: {
// 高亮狀態(tài)下的樣式
areaColor: "#2a333d"
}
}
},
series: [
{
name: "確診人數(shù)",
symbolSize: 10, // 點坐標(biāo)大小
type: "scatter",
data: this.cityData,
coordinateSystem: "geo"
}
]
其數(shù)據(jù)格式如下
// 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 的懸浮數(shù)據(jù)是有問題的翎卓,它不是 pm2.5 的 value契邀,而是極坐標(biāo)的 Y 的值
想要其展示正確的數(shù)據(jù)需要在 tooltip 設(shè)置 formatter:以回調(diào)函數(shù)格式設(shè)置數(shù)據(jù)為 data 的第三個數(shù)據(jù)
tooltip: {
trigger: "item",
formatter: params => {
return (
params.seriesName + "<br/>" + params.name + ":" + params.data.value[2]
);
}
}
另外,示例中 geo 數(shù)據(jù)也是不完整的失暴,可通過 datav 獲取完整中國 geo 數(shù)據(jù)坯门。
最終效果如下:
總結(jié)
至此,我們完成了國內(nèi)各省市疫情模擬數(shù)據(jù)的可視化逗扒,如果想要展示世界數(shù)據(jù)也是類似古戴,只需找到相應(yīng)地圖包替換,并處理對應(yīng)數(shù)據(jù)即可矩肩。echarts 提供了完整的文檔现恼,按需查找對應(yīng)選項即可完成相應(yīng)需求,當(dāng)然還有很多不錯的庫和方法等我們?nèi)ヌ骄俊?/p>
如需查看完整代碼:請點這里
看到這里了黍檩,不點個贊嗎??叉袍!