前言 :
在家空闲时间,整理下地图下钻的思路,下面是我个人的一个思路,供大家参考!如果帮到你了,可以点个赞关注一下!大家如果有更好的思路,评论区可以交流学习一下!个人原创转载请注明!
1. 准备json文件
- echats官网:Apache ECharts
- 数据可视化平台从这里获取json文件:DataV.GeoAtlas地理小工具系列
2. 基础配置,先把地图搞出来再说,直接看效果和代码
这里我导入了下载好的,地图json文件,先看效果图
import * as echarts from 'echarts'
import china from '@/map/china.json'
data() {
return {
charts: null
}
},
mounted() {
this.initMap()
},
methods: {
initMap() {
this.charts?.dispose()
echarts.registerMap('chinaMap', china)
// 初始化地图
this.charts = echarts.init(this.$refs.mapRef)
const options = {
/* 配置项 */
// 背景颜色
backgroundColor: '#fff',
// 提示浮窗样式
tooltip: {
show: true,
trigger: 'item',
alwaysShowContent: false,
backgroundColor: '#0C121C',
borderColor: 'rgba(0, 0, 0, 0.16);',
enterable: true,
textStyle: {
color: '#DADADA',
fontSize: '12',
width: 20,
height: 30,
overflow: 'break' /* 超出换行 */
}
},
geo: [
/* 第一层样式,等级最高 */
{
map: 'china',
layoutSize: '90%' /* 地图的大小 */,
layoutCenter: ['50%', '50%'] /* 把地图放到盒子的正中间 */,
zlevel: 4,
itemStyle: {
areaColor: '#03459b',
borderColor: '#2c7fba',
borderWidth: '1'
},
/* 是否显示文字 */
label: {
show: true,
color: '#fff',
fontSize: 10
},
/* hover高亮下的样式 */
emphasis: {
label: {
show: true,
color: '#02507a',
fontSize: 12
},
itemStyle: {
areaColor: '#94dcf8'
}
},
},
]
}
this.charts.setOption(options)
this.charts.resize() // 监听窗口大小变化
window.addEventListener('resize', this.charts.resize)
}
}
2.1 如果你想添加点击后的样式,添加属性selectedMode
/* 是否开启选中*/
selectedMode: 'single', //单选
/* 选中后的样式 */
select: {
label: {
show: true,
color: '#02507a',
fontSize: 12
},
itemStyle: {
areaColor: '#94dcf8'
}
}
2.2 添加geo多层
如果你感觉没有层级感,可以再配置一个geo.把背景改成黑色即可,然后在向右向下移动一点,直接看代码,在geo数组配置项中添加再次添加一个对象
/* 第二层 */
{
map: 'chinaMap',
layoutSize: '90%' /* 地图的大小 */,
zlevel: 3, //注意 这里越低越在最下面
layoutCenter: ['51%', '51%'],
label: {
show: false
},
itemStyle: {
areaColor: '#000',
borderColor: '#000',
borderWidth: '1'
},
emphasis: {
disabled: true //下面的禁止高亮
}
}
3. 缩放拖拽
在options中配置这个属性
animationDurationUpdate: 0 /* 实现缩放、拖动同步且不卡顿 */,
/* 缩放平移事件 */
this.charts.on('georoam', (params) => {
let option = this.charts.getOption() //获得option对象
let len = option.geo.length
if (params.zoom) {
//捕捉到缩放时
for (var i = 0; i < len; i++) {
option.geo[i].center = option.geo[0].center
option.geo[i].zoom = option.geo[0].zoom
}
} else {
//捕捉到拖曳时
for (var i = 0; i < len; i++) {
option.geo[i].center = option.geo[0].center
}
}
this.charts.setOption(option) //设置option
}),
4 . 地图下钻
我们先随意写死一个,先拿山东省来试试!先下载下来山东地图的json文件, 一步步来,再说后面的思路!
4.1 下钻首先得有个点击事件
this.charts.on('click', (params) => {
console.log(params, '地图已经被点击了')
})
有个name属性,根据name这个值去做一些事情
4.2 下钻思路
我们想办法点击的时候拿到当前点击的地图json文件是不是就可以了,如何拿到呢?你可以定义一个对象数组,与每个名称给个id通过id去找json文件,我感觉写起来太多比较麻烦,我观察了下json文件,可以通过json文件拿到adcode,我们在下载json文件的时候,重命名为这个adcode不就行了,如下图
直接开始正文
我这边在data中定义了俩个字段,定义mapCode是因为想模拟的更贴近工作一些,有时候请求后台拿数据肯定会需要一个字段!
data() {
return {
charts: null,
mapObject: china, //初始化地图的json对象
mapCode: '80001' //地图的code或者id
}
},
然后点击事件,先说一下我的个人思路,通过循环当前的json文件,根据点击的name值去判断去找adcode,如果找到了动态导入该地图的json文件并使用 break跳出循环,所以我用的是原生的for循环,考虑到有些时候,部分地图可能不需要下钻 那找不到json文件不就报错了吗?所以我用了try-catch捕获错误,解决这个问题
echarts.registerMap('chinaMap', this.mapObject)
/* 地图点击事件 */
this.charts.on('click', (params) => {
/* 遍历地图特征集合 */
for (let item = 0; item < this.mapObject.features.length; item++) {
let ele = this.mapObject.features[item].properties
// 如果点击的名称与当前特征名称匹配
if (params.name === ele.name) {
try {
// 动态引入对应地区的json文件
const mapJson = require(`@/map/${ele.adcode}.json`)
if (this.mapObject == mapJson) return
this.mapCode = ele.adcode
//把地图数据赋值给mapObject
this.mapObject = mapJson
1. echarts.registerMap('chinaMap', this.mapObject)
// 更新图表选项
this.charts.setOption(options, true)
2. //不用代码1或者你这里使用2 直接调用初始化方法
this.initMap()
} catch (error) {
// 如果没定义这个文件,说明不能下钻,则使用原来的地图
console.error(`找不到${ele.adcode}.json文件`)
}
// 找到匹配项后跳出循环
break
}
}
})
5. 返回上一级
个人思路:
既然是返回上一级,肯定需要知道上一级adcode是什么才能找到上一级的json文件进行返回!我这里是先定义了一个空数组mapInfo,用于每次下钻后保留上次点击后的地图信息!每次下钻后去找上一次的map adCode,重新获取地图!
data() {
return {
charts: null,
mapObject: china,
mapInfo: [], //保留地图adcode信息
mapCode: '80001'
}
},
/* 地图点击事件 */
this.charts.on('click', (params) => {
/* 遍历地图特征集合 */
for (let item = 0; item < this.mapObject.features.length; item++) {
let ele = this.mapObject.features[item].properties
if (params.name === ele.name) {
try {
/* 添加上这段代码 把当前的地图信息存储到mapInfo中 */
this.mapInfo.push(ele.adcode)
} catch (error) {
// 如果没定义这个文件,说明不能下钻,则使用原来的地图
console.error(`找不到${ele.adcode}.json文件`)
}
// 找到匹配项后跳出循环
break
}
}
})
5.1 点击按钮返回上一级
<el-button
type="primary"
class="back-btn"
v-if="mapInfo.length"
@click="onBack()"
>返回上一级</el-button
>
/**
* 返回上一级地图
*/
onBack() {
/* 删除最后一个,如果没有了,说明上级就是最大的地图那么直接写死默认地图的code,如果存在说明最后一个就是它的上一级*/
this.mapInfo.pop()
// 如果地图信息栈为空
if (!this.mapInfo.length) {
// 加载默认地图对象
this.mapObject = require(`@/map/80001.json`)
// 设置默认地图代码
this.mapCode = 80001
} else {
// 获取当前地图信息栈的最后一个元素作为地图代码
const adcode = this.mapInfo[this.mapInfo.length - 1]
// 根据地图代码加载对应的地图对象
this.mapObject = require(`@/map/${adcode}.json`)
// 设置地图代码
this.mapCode = adcode
}
// 初始化地图
this.initMap()
}
5.2 点击地图空白处返回上一级
/*点击空白处的事件 */
this.charts.getZr().on('click', (params) => {
//判断如果target不存在证明点击的是空白处
if (!params.target) {
this.onBack()
}
})
ok,目前现在没有添加地图上的数据,下钻和返回以及其他的都可以了!