Vue3-Echarts实现全国全级地图下钻

1,180 阅读1分钟

Vue 3.2.25
Echarts 5.3.3

github全国地图资源下载地址

完整代码

<template>
    <div class="top-bar">
        <p>
            <span v-for="item in paths">
                <i v-if="paths.length != 1"> / </i>
                {{ item.name }}
            </span>
        </p>
        <a-button v-if="paths.length > 1" @click="onBack">返回上一级</a-button>
    </div>
    <div ref="mapRef" class="map"></div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
import { useMapStore } from '@/store/map'
import theme from '@/components/pageModel/theme.json'

const mapStore = useMapStore()
// dom
const mapRef = ref()
// 地图数据
const mapJson = ref()
// 图表实例
let mapChart: any = null

/* 地图配置
-------------------------*/
const mapOption = {
	geo: {
		map: 'china', // 必填的
		roam: true,
		zoom: 1.3,
		layoutSize: '100%',
		layoutCenter: ['50%', '70%'],
		label: {
			show: true,
		},
	},
}
/* 下钻路径
-------------------------*/
interface Path {
	path: string // 由level和adcode组成的一个文件路径
	name: string
}
const paths = ref<Path[]>([
	{
		path: 'china.json',
		name: '中国',
	},
])

/* 初始化地图
-------------------------*/
const initMap = async ({ path, name }: Path) => {
	if (!mapChart) {
		mapChart = echarts.init(mapRef.value, theme, 'macarons')
	}
	mapOption.geo.map = name
	mapJson.value = await mapStore.getGelMapData(path)
        // 这是静态方法
	echarts.registerMap(name, mapJson.value)
	mapChart.setOption(mapOption, true)
	setEvent()
}

const setEvent = () => {
	mapChart.off('click')
	mapChart.on('click', (e: any) => {
		const { name, level, adcode } = mapJson.value.features.find((item: any) => item.properties.name === e.name)?.properties
		const path = { path: `${level}/${adcode}.json`, name: name }
		if (paths.value.map((item) => item.name).includes(name)) return
		paths.value.push(path)
		initMap(path)
	})
}

const onBack = () => {
	paths.value.pop()
	const path = paths.value[paths.value.length - 1]
	initMap(path)
}

onMounted(() => {
	initMap(paths.value[0])
})
</script>

<style lang="less" scoped>
.map {
	width: 1000px;
	height: 800px;
	margin: 10px auto;
	border: 2px solid #6bf2f7;
}
.top-bar {
	display: block;
	text-align: center;
}
</style>

注意渲染地图必须要配置geo 和 name字段