分享一个基于echarts实现的伪3D地图并实现自定义坐标点和坐标点涟漪效果,实现效果如下:
要实现上图中的效果,我们需要配置三种type的echarts图,即:map、effectScatter、scatter,废话不多说,我们直接开干!(echarts版本:^5.4.0,vue版本:2.x)
初始化
初始化部分代码比较简单,不过还是有几点需要注意:
- 我这里的地图渲染是借助DataV生成的,绘制地图的方法不是唯一,选择最适合你当前业务场景或你自己用起来最顺手的一种即可;
- initMap方法中接收的info参数是我这边服务端传递的数据,主要是需要标注的坐标点的经纬度和坐标点名称;
- mapData中对应的key:name、value等是按照echarts文档中散点图和涟漪图配置项进行配置的而不是随意定义的;
代码如下:
xml
<template>
<div class="map-box">
<div ref="map3d" style="width: 100%; height: 100%;" />
</div>
</template>
<script>
import * as echarts from 'echarts'
data() {
return {
// 考点标记图片
examSite: require('@/assets/screen/exam-site.png')
}
},
methods: {
/**
* 初始化地图
* @param info 坐标点信息
*/
async initMap(info) {
const mapJson = (await axios.get('https://geo.datav.aliyun.com/areas_v3/bound/152500_full.json')).data
const mapChart = echarts.init(this.$refs.map3d)
mapChart.showLoading()
// 注册地图
echarts.registerMap('MapAddress', mapJson)
const { organizationName, latitude, longitude } = info
// 地图点坐标,用于散点图和涟漪图
const mapData = [
{
name: organizationName,
value: [longitude, latitude],
type: 'normal',
img: this.examSite
}
]
const option = { ... }
mapChart.setOption(option)
mapChart.hideLoading()
window.addEventListener('resize', function() {
mapChart.resize()
})
}
}
</script>
到这里我们初始化就完成了,其实页面上啥也没有-_-,与其说是初始化,不如说是前期的一些参数接收和配置,接下来才是重头戏
地图配置项
我们在文件目录中新建一个叫做mapOptions的js文件来专门放置地图的一些配置项。
yaml
export const mapOptions = {
// 地理坐标系组件
geo: [
{
// registerMap注册的地图名称
map: 'MapAddress',
// 是否可缩放
roam: false,
// 地图层级
zlevel: 5,
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
left: 10,
right: 0,
top: 0,
bottom: 20,
itemStyle: {
areaColor: '#01215c',
borderWidth: 3,
borderColor: '#9ffcff',
// 阴影颜色
shadowColor: 'rgba(9, 140, 255, 0.9)',
shadowBlur: 14
},
// 高亮样式
emphasis: {
itemStyle: {
areaColor: '#01215c'
}
}
},
// 这一个是为了仿3D地图,故创建一个低层级的一模一样的地图
{
map: 'MapAddress',
roam: false,
zlevel: 4,
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
left: 10,
right: 0,
top: 0,
bottom: 20,
itemStyle: {
areaColor: '#01215c',
shadowColor: '#9ffcff',
shadowOffsetX: 0,
shadowOffsetY: 6
}
}
]
}
在代码中可以看到,我在geo中配置了两个相同的地图,仅仅是改变了层级和itemStyle的配置,然后我们将这个mapOptions文件引入进我们地图组件的option里面
ini
const option = {
...mapOptions
}
就可以得到下图效果:
此时可以看到边框就会有出现立体效果了,所以说这是伪3D,因为我们是基于平面来实现的。但是现在很明显地图太亮了,并且地图内部的边框和边缘的边框是一样粗的,很影响感观,所以我们对这个地图进行样式上的一些优化。
series type: 'map'
对于地图内容样式的一些优化很简单,大家对照echarts官网中series,type: 'map'的配置项文档对照来看就能看懂,所以不需要过多描述,我认为需要注意的配置项也写了注释。
yaml
const option = {
...mapOptions,
series: [
// map
{
type: 'map',
map: 'MapAddress',
zlevel: 5,
// 这个参数用于 scale 地图的长宽比
aspectScale: 0.75,
left: 10,
right: 0,
top: 0,
bottom: 20,
label: {
normal: {
show: false
},
emphasis: {
show: false,
textStyle: {
color: '#fff'
}
}
},
roam: false,
itemStyle: {
areaColor: '#01215c',
borderColor: 'rgba(61, 197, 225)',
borderWidth: 1
},
emphasis: {
disabled: true,
itemStyle: {
areaColor: '#01215c'
}
},
// 图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件。
silent: true
}
]
当我们写完了上面的配置后,就会发现我们的地图变得稍微好看了一些,至少中间的边框不会那么粗了。
地图我们渲染好了后就该标记坐标点了,这里我们用到的是scatter散点图,也是对照官方文档进行配置项的编写,同样很简单。
series type: 'scatter'
散点图的配置项直接接着上面map的配置项后面写就可以了,同样我也将type: 'scatter'的文档地址放在这里:echarts.apache.org/zh/option.h...
javascript
// 散点图
{
type: 'scatter',
coordinateSystem: 'geo',
zlevel: 6,
itemStyle: {
color: '#f00',
opacity: 1
},
// 自定义点样式
symbol: (value, params) => {
return `image://${params.data.img}`
},
// 动态改变点大小
symbolSize: (value, params) => {
return params.data.type === 'normal' ? [130, 30] : [127, 30]
},
// 点偏移量
symbolOffset: [45, -15],
label: {
show: true,
formatter: (params) => {
return params.data.name
},
color: '#fff',
fontSize: 16,
align: 'center',
offset: [10, 0]
},
z: 9999,
data: mapData
}
现在我们就可以看到我们自定义图标的坐标点已经渲染在了地图上,解释一下代码中的动态改变点大小,其实是一种很粗糙的处理方式,考虑到我们坐标点名称长度可能会不一样,所以对symbolSize做了处理,这个处理仅仅是满足我当前的项目。
最后我们将涟漪图配置项按照上面的方式写入代码:
series type: 'effectScatter'
css
// 波纹涟漪
{
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 5,
symbol: 'circle',
rippleEffect: {
color: '#FDD835',
number: 2,
scale: 8,
brushType: 'fill'
},
itemStyle: {
color: '#FDD835'
},
data: mapData
}
至此,我们就能实现文章开头的效果了!
内容不少,但不难,主要就是echarts的配置项,对照官方文档慢慢写就能写出来
写在最后
🥰🥰🥰感谢能看到最后的jym,这篇文章主要是记录自己在项目实现地图的过程,方便以后在其他项目中要用到时可以随时查找,写的不好望多多谅解😅,如果对你们也能有一定的帮助那我就太太太太荣幸了🤘