之前没看过echart的地图,最近有个需求需要绘制到深圳地图,经过几番测试,实现需要的效果,这里写篇博客记录一下,先看效果图:
需求大概是这样,展示出深圳部分医院在地图上的位置以散点的方式进行展示,并可以显示某些信息。
首先要先把地图绘制出来,因为之前没用过地图,超人鸭也是先从官网的例子看起,经常逛echart官网的伙伴应该对这个例子不陌生:
这是去往官网例子的链接
每一种地图都会有按区域划分,而这些区域就可以看作一个单位,像上面的美国地图,每个洲就是它的单位,中国的地图就是以每个省作为单位,我最上面的深圳地图就是以每个区作为单位。这些单位地图一开始已经划分好,所以你可以直接赋值给这些单位某个值去展示,就像上面的例子一样,伙伴们如果看不太懂可以好好看看我上面放的官方例子。
回到我遇到的需求,是需要在深圳地图上展示部分医院,而不是去操作地图本身,不是给某个区某个数值,所以这时候地图只是作为一个坐标,供我们去定位,然后需要在上面再绘制一层散点图,官方也有同样的例子:
这是去往官方例子的链接
好了,看了几遍官网的例子后大概明白如何做了,回到我遇到的需求,我需要先绘制出深圳地图,将它作为坐标系展示。因为echart不再内置地图,所以我们需要手动引入一个地图数据的json文件,我绘制的是深圳地图,这些地图的json文件大家百度找找都是可以免费找到的。
得到地图数据的json文件后,这个json文件里面是一个对象,需要将它引入到我们用的地方,然后将这个对象给到echart注册,那如何将一个本地的json文件引入到我们要用的地方呢?如果你是在node.js服务器的环境下,比如vue脚手架开发,就可以使用require引入这个对象:
const shenzhenJson = require("./shenzhen.json");
但如果不是node环境呢,比如本地的一个html文件,第一想到的是ajax,但这是本地模拟一下,使用ajax还是有点麻烦,这里超人鸭用一种不太规范的方法引入,这是json文件原本的样子:
我使用一个变量定义这个对象:
然后在html文件中用script标签引入:
<script src="./shenzhen.json"></script>
这里已经引入成功了,我们可以打印测试一下:
<script>
console.log(shenzhen)
</script>
是没问题的,现在拿到深圳地图的json数据,接下来就是绘制地图了,还是echart那一套:
<script>
echarts.registerMap("shenzhen", shenzhen); // 注册一个地图,名字叫shenzhen
var myChart = echarts.init(document.getElementById('map')) // 拿到一个实例
option = {
backgroundColor: '#fff',
geo: { // 地理坐标系组件
map: 'shenzhen',
itemStyle: { // 这里的item就是上面说的地图的单位,在深圳地图上就是每个区
normal: {
areaColor: '#e8f6ff',
borderColor: '#4a9dc9'
}
},
emphasis: {
areaColor: '#cddeea'
}
}
}
myChart.setOption(option);
</script>
先看看效果:
接下来就是往上面绘制散点图,既然是往以这个地图作为坐标系,那显示在上面点的位置就要在这个地图上,我们需要先写好每个地点的经纬度:
var geoCoordMap = {
"龙岗中医院":[114.215683,22.7083],
"龙岗人民医院":[114.227615,22.726227],
"深圳市儿童医院":[114.054398,22.547491],
"深圳市人民医院":[114.128563,22.557564],
"深圳市第二人民医院":[114.116035,22.605417],
"深圳南山人民医院":[113.927406,22.52663],
"深圳市妇幼保健院":[114.048958,22.51841],
"深圳东方医院":[113.873001,22.75885],
"深圳岭南医院":[114.036186,22.52033],
"深圳和平医院":[113.895424,22.570961],
"深圳友谊医院":[114.103729,22.561831],
"深圳市香蜜湖医院":[114.019379,22.537119],
"深圳景田医院":[114.042046,22.549276],
"深圳市急救医疗中心":[113.824593,22.64187]
}
大家百度一下经纬度查询就能找到,然后是散点图的配置,还有一个处理数据的函数:
var convertData = function (data) {
var res = [];
for (var i = 0; i < data.length; i++) {
var geoCoord = geoCoordMap[data[i].name];
if (geoCoord) {
res.push({
name: data[i].name,
value: geoCoord.concat(data[i].value)
});
}
}
return res;
}
// 散点图的配置:
series: [
{
type: 'scatter', // 散点图类型
coordinateSystem: 'geo', // 使用地理坐标系
data:convertData([
{name: '龙岗中医院',value: [10,20,3]}, // value的值是随便写的,不用理会
{name: '龙岗人民医院',value:[20,30,2]},
{name:'深圳市儿童医院',value:[30,20,3]},
{name:'深圳市第二人民医院',value:[40,50,5]},
{name:'深圳南山人民医院',value:[40,50,5]},
{name:'深圳市妇幼保健院',value:[40,50,5]},
......
]),
symbolSize: 13, // 散点的大小
itemStyle: {
normal:{
color: '#fd9a95' // 散点的颜色
}
}
}
]
上面的处理函数也是从官网改造一点细节复制过来的,处理后的每一项data就是这个样子:
散点图会根据value的前两项去匹配坐标,在地图上显示,后面的数据并无关系。到这里的效果:
跟最上面的完成图比较就只剩提示框和提示框里面的内容,这个其实比较简单,都是echart官网配置项而已,下面超人鸭将整个实现绘制的代码贴出来:
<script>
var geoCoordMap = {
"龙岗中医院":[114.215683,22.7083],
"龙岗人民医院":[114.227615,22.726227],
"深圳市儿童医院":[114.054398,22.547491],
"深圳市人民医院":[114.128563,22.557564],
"深圳市第二人民医院":[114.116035,22.605417],
"深圳南山人民医院":[113.927406,22.52663],
"深圳市妇幼保健院":[114.048958,22.51841],
"深圳东方医院":[113.873001,22.75885],
"深圳岭南医院":[114.036186,22.52033],
"深圳和平医院":[113.895424,22.570961],
"深圳友谊医院":[114.103729,22.561831],
"深圳市香蜜湖医院":[114.019379,22.537119],
"深圳景田医院":[114.042046,22.549276],
"深圳市急救医疗中心":[113.824593,22.64187]
}
var convertData = function (data) {
var res = [];
for (var i = 0; i < data.length; i++) {
var geoCoord = geoCoordMap[data[i].name];
if (geoCoord) {
res.push({
name: data[i].name,
value: geoCoord.concat(data[i].value)
});
}
}
return res;
}
echarts.registerMap("shenzhen", shenzhen);
var myChart = echarts.init(document.getElementById('map'))
option = {
backgroundColor: '#fff',
title: {
text: '全市医院分布',
},
tooltip: { // 提示框
trigger: 'item',
backgroundColor: '#fffeff',
padding: 8,
textStyle: {
color: '#00a2ff'
},
// 给提示框添加样式
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);text-align:center',
formatter: function (params) { // 格式化提示框的文字,下面使用模板字符串
return `<span style="color:#aaaaaa">${params.name}</span><br />
<div style="font-size:14px;font-weight:700;">
满意度:${params.value[2]}
<br />满意率:${params.value[3]}<br />排名:${params.value[4]}
</div>
`
}
},
geo: {
map: 'shenzhen',
itemStyle: {
normal: {
areaColor: '#e8f6ff',
borderColor: '#4a9dc9'
},
emphasis: {
areaColor: '#cddeea'
}
}
},
series: [
{
type: 'scatter',
coordinateSystem: 'geo',
data:convertData([
{name: '龙岗中医院',value: [10,20,3]},
{name: '龙岗人民医院',value:[20,30,2]},
{name:'深圳市儿童医院',value:[30,20,3]},
{name:'深圳市第二人民医院',value:[40,50,5]},
......
]),
symbolSize: 13,
itemStyle: {
normal:{
color: '#fd9a95'
}
}
}
]
}
myChart.setOption(option);
</script>
看到我使用了回调函数格式化了提示框显示的内容,这个回调函数带了一个params参数,这个对象里面基本什么信息都有,大家不知道的话打印一下什么都明了。
到这里就实现使用echart散点图绘制地图,超人鸭这篇文章所实现的适合那种某个区域的某种东西的分布情况,用处还是挺大的,欢迎大家指教哦。