我同时兼任前端开发以及数据可视化中的疫情地图绘制,这部分内容属于我们项目中放在首页最醒目位置的内容,也是我们比较核心的功能之一。疫情地图绘制我将利用echarts的地图控件实现世界地图的绘制,功能包括世界地图国家板块、视觉映射效果(疫情严重与否体现在颜色深浅)、疫情数据的展示等。
在开发疫情地图过程中,数据取自后端,但并不像一般页面中获取——渲染——展示这一简单流程即可实现。由于地图绘制和数据获取在同一生命周期且数据获取(axios请求数据)的时间不确定,取决于接口大小、网络速度等问题,因此需要引入大量异步和同步函数来完成数据渲染。
首先从网络获取一个namemap,国家中英文名对照表,由于echarts内部世界地图的板块是英文标识的,因此需要其与中文名对应(部分对照):
"Azerbaijan": "阿塞拜疆",
"Bahamas": "巴哈马",
"Bangladesh": "孟加拉国",
"Belgium": "比利时",
"Benin": "贝宁",
"Burkina Faso": "布基纳法索",
"Burundi": "布隆迪",
"Bulgaria": "保加利亚",
"Bosnia and Herz.": "波斯尼亚和黑塞哥维那",
"Belarus": "白俄罗斯",
"Belize": "伯利兹",
"Bermuda": "百慕大群岛",
"Bolivia": "玻利维亚",
"Brazil": "巴西",
"Brunei": "文莱",
"Bhutan": "不丹",
"Botswana": "博茨瓦纳",
"Cambodia": "柬埔寨",
"Cameroon": "喀麦隆",
"Canada": "加拿大",
"Central African Rep.": "中非共和国",
"Chad": "乍得",
之后在页面编写地图绘制函数:
drawChart(name,data){
//基于准备好的dom,初始化echarts实例
let chart=echarts.init(document.getElementById('chart1'))
//监听屏幕变化自动缩放图表
window.addEventListener('resize',function() {
chart.resize()
})
var _this=this
//绘制图表
chart.setOption({
grid:{
width:'100%',
height:'100%',
left:'0%',
right:'0%',
bottom:'0%',
containLabel:true
},
//提示框组件
tooltip:{
trigger:'item',//触发类型,数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用
//提示框浮层内容格式器,支持字符串模板和回调函数两种形式
//使用函数模板 传入的数据值-》value:number | Array
formatter:function(val){
if(val.data == null) return;
return val.name+': '+val.value
}
},
// 视觉映射组件
visualMap:{
min:0,
max:10000,
text:['max','min'],
realtime:false,
calcuable:true,
color:['#ff4500','#fffafa'],
},
series:[
{
type:'map',//类型
//系列名称。用于tooltip的显示,legend的图例筛选 在setOption更新数据和配置项时用于指定对应的系列
name:'世界地图',
mapType:'world',//地图类型
//是否开启鼠标缩放和平移漫游 默认不开启,若只想开启缩放或者平移,可以设置成‘scale’或者‘move’设置成true为都开启
roam:true,
//图形上的文本标签
label:{
show:false//是否显示对应地名
},
zoom:1.2,
//地图区域的多边形图形样式
itemStyle:{
//areaColor:'#7b68ee', //地图区域的颜色,如果设置了visualMap,areaColor属性将不起作用
borderWidth:0.5,//描边线宽为0 时无描边
borderColor:'#000',//图形的描边颜色 支持的颜色格式同color,不支持回调函数
borderType:'solid'//描边类型, 默认为实线,支持'solid‘,’dashed‘,‘dotted’
},
//高亮状态下的多边形和标签样式
emphasis:{
label:{
show:true,//是否显示标签
color:'#fff'//文字的颜色,如果设置为auto,则为视觉映射得到的颜色,如系列色
},
itemStyle:{
areaColor:'#0064d0'//地图区域的颜色
}
},
//自定义地区的名称映射
nameMap:name,
// 地图系列的数据内容数组,数组项可以为单个数值
data:data
}
]
})
chart.on('click',function (param) {
console.log(param.data.name)
//控制逻辑
})
}
其原理很简单,首先在页面保留一个div,设置其id为‘chart1’,在JavaScript函数里利用document.getElementById()获取对应dom元素,对图表设置若干设置,大体情况如注释。在visualMap设置里进行视觉映射效果的配置,我将疫情严重与否映射到白色到棕红色。tooltip设置中可以配置鼠标悬浮时的提示框显示,我将其设置为国家名:现存确诊的格式。
在
chart.on('click',function (param) {
})
代码中,匿名函数体触发点击事件,现在预想是对应后期的可视化图表页面跳转。
绘制图表函数写好后,编写一个传入数据的函数:
getWorld(data){
let namemap=world.namemap
let dataArr=this.worldChartdata
this.drawChart(namemap,dataArr)
},
编写axios请求,获取后端数据:
loadWorldData(){
/* var _this=this
this.$axios.get('/user/2').then(resp=>{
if(resp&&resp.status===200){
_this.worlddata=resp.data.newslist
}
}).then(()=>{
for(var i=0;i<this.worlddata.length;i++){
var obj={
name:this.worlddata[i].provinceName,
value:this.worlddata[i].currentConfirmedCount
}
this.worldChartdata.push(obj)
}
console.log(this.worldChartdata)
}).then(()=>{
this.getWorld(this.msg)
})*/
var _this=this
this.$axios.get('/user/world_data').then(resp=>{
if(resp&&resp.status===200){
_this.worldChartdata=resp.data
}
}).then(()=>{
this.getWorld(this.msg)
})
},
可以看到,axios请求会返回一个promise对象,promise对象中的数据处理需要在then函数中进行处理。同时利用then函数必须等待前面的方法执行完的同步特点,进行顺序处理,先获取数据后渲染数据到地图。在mounted周期调用loadWorldData()函数即可。最后我们可以看到效果: