前言
之前的一个项目要在内网部署,这时高德地图需要走代理,在公司申请代理资源是一件极其繁琐的事情(手动狗头),退而求其次,将其中采用地图部分用echarts代替,功能也发生了一些变化。如下图所示的定位查找改为点击下钻,这篇文章具体说一下Echarts多层级下钻及返回功能的实现过程
思路
===> 创建初始化地图
===> 点击获取下一层地图数据
===> 记录每一步地图所处层级
===> 返回上一级
实现
1. 创建初始化地图
使用echarts 画地图有两种方法,一种是通过js,一种是json,我们这里通过json文件绘制
从echart 的文档上来看, 我们在echart中使用 geo 和 使用 series 来绘制地图,它们之间有一点细微的差别,可以忽略不计。
创建一个函数页面加载后调用
onMounted(() => {
getAreaCounty('邵阳市')
})
const getAreaCounty = (name) => {
// 我从后台获取json数据的接口函数
apiAreaCounty({ parent: name }).then((res) => {
// 获取绘制容器
mychart = echarts.init(chart.value)
// 绘制地图
initEcharts(res, name, mychart)
mychart.on('click', (params) => {
// 点击下钻的操作写在这里
})
})
}
const initEcharts = (geoJson, name, mychart) => {
echarts.registerMap(name, geoJson)
let option = {
series: [
{
show: true,
type: 'map',
map: name,
itemStyle: {
areaColor: '#1890ff'
}
}
]
}
mychart.setOption(option)
}
2. 点击获取下一层地图数据
const getAreaCounty = (name) => {
// 我从后台获取json数据的接口函数
apiAreaCounty({ parent: name }).then((res) => {
// 获取绘制容器
mychart = echarts.init(chart.value)
// 绘制地图
initEcharts(res, name, mychart)
mychart.on('click', (params) => {
// 点击下钻的操作写在这里
// 从params中拿取每一层数据所需要的参数或判断条件等或者从全局变量/函数传参中读取
apiAreaCounty({ parent: params.name }).then((res) => {
initEcharts(res, params.name, mychart)
})
})
})
}
3. 记录每一步地图所处层级
这一步是多层下钻返回的关键,将每次点击的发起不同请求的参数保存到数组中,每一步返回,读取保存的最后一组参数发起新的请求,同时将数组中的这组数据移除
const initEcharts = (geoJson, name, mychart, level, flag) => {
echarts.registerMap(name, geoJson)
let option = {
series: [
{
show: true,
type: 'map',
map: name,
itemStyle: {
areaColor: '#1890ff'
}
}
]
}
mychart.setOption(option)
if(flag){
mapStack.push({
name: lastName, // 发起请求所传参数
level: lastLevel // 发起请求所传参数
})
lastName = name
lastLevel = level
}
}
4. 返回上一级
绑定点击返回事件
function onBack() {
if (mapStack.length != 0) {//如果有上级目录则执行
let map = mapStack.pop();
apiAreaCounty({ parent: map.name }, map.level).then((res) => {
initEcharts(res, map.name, mychart, map.level, false)
lastLevel = map.level
lastName = map.name
})
}
}
完整代码
<template>
<div ref="chart" id="main" @dblclick='onBack'></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
import { apiAreaCounty } from '@/service/api/grid'
onMounted(() => {
getAreaCounty('邵阳市', 'county')
})
const chart = ref()
// 记录所在位置
let mapStack = []
let lastName = ''
let lastLevel = ''
// 地图初始化数据
let ShaoYangJson = null
let mychart = null
// 返回上一级
const onBack = () => {
console.log(mapStack)
if (mapStack.length != 0) {//如果有上级目录则执行
let map = mapStack.pop(); //获取最后一步操作
apiAreaCounty({ parent: map.name }, map.level).then((res) => {
initEcharts(res, map.name, mychart, map.level, false)
lastLevel = map.level
lastName = map.name
})
}
}
let mapRes = {
county: 'street',
street: 'scope'
}
const getAreaCounty = (name, level) => {
apiAreaCounty({ parent: name }, level).then((res) => {
ShaoYangJson = res
mychart = echarts.init(chart.value)
initEcharts(res, area, mychart, level, false)
lastName = '邵阳市'
lastLevel = 'county'
mychart.off('click')
mychart.on('click', (params) => {
// level/level1 是因为我后端接口提供了多个不同的接口 我在前端封装成了一个调用根据传参不同的level拼接url,关于level/level1 部分可忽略
const level1 = mapRes[lastLevel]
判断是否还有下一级,没有下一级,返回初始地图
if (level1) {
apiAreaCounty({ parent: params.name }, level1).then((res) => {
initEcharts(res, params.name, mychart, level1, true)
})
} else {
initEcharts(ShaoYangJson, '邵阳市', mychart, 'county', false)
mapStack = []
lastName = '邵阳市'
lastLevel = 'county'
}
})
})
}
const initEcharts = (geoJson, name, mychart, level, flag) => {
echarts.registerMap(name, geoJson)
let option = {
series: [
{
show: true,
type: 'map',
map: name,
itemStyle: {
areaColor: '#1890ff'
}
}
]
}
mychart.setOption(option)
if(flag){
mapStack.push({
name: lastName,
level: lastLevel
})
lastName = name
lastLevel = level
}
}
</script>
<style scoped>
#main {
width: 100%;
height: 100%;
}
.back{
position: absolute;
top: 0;
left: 20px;
}
</style>
效果
虽然实现了多级下钻及返回的效果,但是目前基于业务代码还没有进行过多的优化封装,希望实现的过程对大家有帮助
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。