用 Python 做一个疫情大屏(优化版)
The following article is from 萝卜大杂烩 Author 周萝卜
文/周萝卜 图片来源于网络
最近在网络上看到了很多地图下钻的文章,感觉都很不错,正好自己也在研究这部分知识,就想着把下钻这个功能结合到疫情大屏中来,这样就能够更好的展示不同省份的疫情信息了。废话不多说,直接来干货!
也可以先来回顾下上一篇的疫情大屏:用 Python 做一个超全的疫情大屏
下钻功能思路
我这里还是使用 ECharts 来处理,有一个 API 是 registerMap,可以用来生成地图。它有两个比较重要的参数,mapName 和 geoJson。
mapName 顾名思义,就是该注册地图的名称。
而对于 geoJson 呢,需要是 GeoJson 格式的数据,具体格式可以参见 http://geojson.org/。说白了就是包含了经纬度信息和地理名称的 json 数据,这种数据很多网站都有提供,我选取了如下的网站获取
https://data.jianshukeji.com/geochina/tianjin.json
可以看出,只要替换 json 名称,如:tianjin,就可以获取到天津对应的 geojson 数据。
下面就是正常的绘制地图了,只需要注意把 mapType 设置为前面注册的地图名称即可。
后台数据准备
由于现在要展示各个市级别的数据,那么我们就需要重新准备下后台的数据接口,把各省的地级市信息捞取出来,注意对于直辖市需要特殊处理
def get_chart_city_map_data():
city_map_dict = {}
map_data = json.loads(rd.get('trend'))
city_data = map_data['data']['areaTree'][0]
special = ['北京', '天津', '上海', '重庆', '香港', '澳门']
for data in city_data['children']:
city_list = []
if data['name'] in special:
for inner_data in data['children']:
if '区' in inner_data['name']:
city_list.append({'name': inner_data['name'], 'value': inner_data['total']['confirm']})
else:
city_list.append({'name': inner_data['name'] + '区', 'value': inner_data['total']['confirm']})
else:
for inner_data in data['children']:
city_list.append({'name': inner_data['name'], 'value': inner_data['total']['confirm']})
city_map_dict[data['name']] = city_list
return city_map_dict
然后统一到一个接口中返回
@app.route('/get_map_data')
def get_map_data():
map_data = get_chart_map_data()
city_data = get_chart_city_map_data()
return jsonify({'country': map_data, 'city': city_data})
前端功能实现
下面我们来根据思路编写前端代码,首先在中国地图上设置点击事件,更加当前点击的省份信息来请求 geojson 数据并注册地图。
mapChart.on('click', function (params) {//点击事件
if (params.name in provinces) {
$.getJSON('https://data.jianshukeji.com/geochina/' + provinces[params.name] + '.json', function (jsondata) {
echarts.registerMap(params.name, jsondata);
var d = [];
for (var i = 0; i < jsondata.features.length; i++) {
d.push({
name: jsondata.features[i].properties.name
})
}
renderMap(params.name, data)
})
}
})
接下来就是 renderMap 函数,其实就是正常的绘制地图代码
function renderMap (map, data) {
// 初始化绘制省市地图配置
var cityMapContainer = document.getElementById('map_1');
var myMapChart = echarts.init(cityMapContainer);
option.title = {
text: map + '疫情地图',
subtext: '点击标题返回全国地图',
triggerEvent: true
};
option.tooltip = {
trigger: 'item'
};
option.visualMap = {
min: 0,
max: 1500,
show: false,
left: 'right',
top: 'bottom',
text: ['高', '低'], // 文本,默认为数值文本
calculable: true,
textStyle: {
color: '#fff'
}
};
option.series = [
{
name: '确诊人数',
type: 'map',
mapType: map,
roam: false,
data: data['city'][map],
label: {
show: true,
emphasis: {//对应的鼠标悬浮效果
show: false,
textStyle:{color:"#800080"}
}
},
itemStyle: {
normal: {
borderWidth: .5,//区域边框宽度
borderColor: '#002097',//区域边框颜色
areaColor:"#4c60ff",//区域颜色
},
emphasis: {
borderWidth: .5,
borderColor: '#4b0082',
areaColor:"#ffdead",
}
}
}
];
// 渲染地图
myMapChart.setOption(option);
myMapChart.on('click', function (params) {
if (params.componentType == 'title') {
mymap(local_var)
}
})
}
这里又做了一个判断,如果用户点击标题,则会调用创建中国地图的函数,以此来达到返回全国地图的效果!
最后我们来看下效果图,由于从 geojson 拿到的数据和从网上接口拿到的地级市名称不尽相同,所以有一些地级市的数据无法显示,暂时还没有很好的解决办法,无奈!
完整网站示例,可以访问这里查看
https://ncov.luobodazahui.top