vue-echarts map地图动态下钻,自定义标注,tooltip弹窗

📅 2026/8/6 12:04:40
vue-echarts map地图动态下钻,自定义标注,tooltip弹窗
效果展示资源准备1. 地图json下载链接免费下载实时更新的geoJson数据、行政区划边界数据、区划边界坐标集合__HashTang2. 地图接送下载链接2阿里云DataV.GeoAtlas地理小工具系列2.2 新建down.js文件打开cmd命令框输入node down.js即可下载地图资源阿里云中下载的中国地图资源加载不出来以下是down.js核心代码const fs require(fs); const path require(path); const https require(https); const readline require(readline); // 基础配置 // 这是地图的下载地址 const baseUrl https://geo.datav.aliyun.com/areas_v3/bound/; // 这是所有地区编码 const infoUrl https://geo.datav.aliyun.com/areas_v3/bound/infos.json; // 控制直辖市下级区是否放在 citys 文件夹下便于地图下钻的逻辑处理 const MUNICIPALITIES [110000, 120000, 310000, 500000]; // 北京、天津、上海、重庆 let municipalityChildrenInCitys; // 控制直辖市下级区是否放在 citys 文件夹下 // 当前正在写入的文件路径用于 SIGINT 清理 let currentWritingFile null; // CtrlC 时清理不完整的文件 process.on(SIGINT, () { console.log(\n${colors.yellow}⚠${colors.reset} 检测到中断信号 (CtrlC)...); if (currentWritingFile fs.existsSync(currentWritingFile)) { try { fs.unlinkSync(currentWritingFile); console.log(${colors.yellow}⚠${colors.reset} 已清理不完整文件: ${colors.cyan}${currentWritingFile}${colors.reset}); } catch (err) { console.error(${colors.red}✗${colors.reset} 清理文件失败:, err.message); } } console.log(${colors.blue}ℹ${colors.reset} 程序已退出\n); process.exit(0); }); // // 这是输出目录 // const outputDir ./; // // 添加命名方式配置 // const config { // nameFormat: adcode, // 可选值: adcode, chinese // }; // 命令行交互 const rl readline.createInterface({ input: process.stdin, output: process.stdout }); const question (query) new Promise((resolve) rl.question(query, resolve)); // ANSI 颜色代码 终端进度条用 const colors { reset: \x1b[0m, bright: \x1b[1m, dim: \x1b[2m, red: \x1b[31m, green: \x1b[32m, yellow: \x1b[33m, blue: \x1b[34m, magenta: \x1b[35m, cyan: \x1b[36m, white: \x1b[37m, bgBlue: \x1b[44m, }; // 进度条类 class ProgressBar { constructor(name, total, width 30) { this.name name; this.total total; this.current 0; this.width width; } update(current, currentItem ) { this.current current; const percentage Math.round((this.current / this.total) * 100); const filledWidth Math.round(this.width * (this.current / this.total)); const emptyWidth this.width - filledWidth; const filled █.repeat(filledWidth); const empty ░.repeat(emptyWidth); const bar ${filled}${empty}; if (process.stdout.isTTY) { process.stdout.clearLine(0); process.stdout.cursorTo(0); process.stdout.write( ${colors.magenta}♦${colors.reset} ${colors.bright}${this.name}${colors.reset} ${colors.cyan}${bar}${colors.reset} ${colors.yellow}${percentage}%${colors.reset} (${this.current}/${this.total}) ${colors.dim}${currentItem}${colors.reset} ); } else { // 非 TTY 环境简化输出避免刷屏 if (this.current this.total || this.current % 10 0) { console.log([${this.name}] ${percentage}% (${this.current}/${this.total}) ${currentItem}); } } } complete() { process.stdout.write(\n); } } // 创建目录 const createDir (dir) { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } }; // 修改 HTTPS 请求函数添加重试机制 const httpsGet async (url, retries 3) { for (let i 0; i retries; i) { try { const response await new Promise((resolve, reject) { https.get(url, (res) { if (res.statusCode ! 200) { // 消耗响应流释放资源防止内存泄漏 res.resume(); reject(new Error(HTTP 状态码: ${res.statusCode})); return; } let data ; res.on(data, (chunk) data chunk); res.on(end, () resolve(data)); }).on(error, reject); }); try { return JSON.parse(response); } catch (parseError) { // 如果是最后一次重试则抛出错误 if (i retries - 1) { throw new Error(JSON 解析失败: ${parseError.message}); } // 否则继续重试 await new Promise(resolve setTimeout(resolve, 1000 * (i 1))); // 递增延迟 continue; } } catch (error) { // 如果是最后一次重试则抛出错误 if (i retries - 1) { throw error; } // 否则继续重试 await new Promise(resolve setTimeout(resolve, 1000 * (i 1))); // 递增延迟 continue; } } }; // 修改 getFileName 函数添加对全国地图的特殊处理 const getFileName (code, info, type , nameFormat) { // 如果是全国地图代码为100000则返回 china.json if (code 100000) { return china.json; } switch (nameFormat) { case chinese: return ${info.name}${type}.json; case adcode: default: return ${code}.json; } }; // 追踪写入状态便于中断时清理 const safeWriteFile (filePath, content) { currentWritingFile filePath; fs.writeFileSync(filePath, content); currentWritingFile null; // 写入完成清除追踪 }; // 修改 downloadJson 函数添加 useFullVersion 参数 const downloadJson async (url, outputPath, info, progressBar null, currentItem , useFullVersion false) { try { // 如果需要下载 full 版本先尝试下载 if (useFullVersion) { try { const fullUrl url.replace(.json, _full.json); const data await httpsGet(fullUrl); safeWriteFile(outputPath, JSON.stringify(data)); if (progressBar) { progressBar.update(progressBar.current 1, currentItem); } else { console.log(${colors.green}✓${colors.reset} 成功下载: ${colors.cyan}${outputPath}${colors.reset}); } return; } catch (error) { console.log(${colors.yellow}!${colors.reset} full 版本下载失败尝试基础版本...); } } // 下载基础版本 const data await httpsGet(url); safeWriteFile(outputPath, JSON.stringify(data)); if (progressBar) { progressBar.update(progressBar.current 1, currentItem); } else { console.log(${colors.green}✓${colors.reset} 成功下载: ${colors.cyan}${outputPath}${colors.reset}); } await new Promise(resolve setTimeout(resolve, 200)); } catch (error) { console.error(${colors.red}✗${colors.reset} 下载失败: ${colors.cyan}${url}${colors.reset}, error.message); if (progressBar) { progressBar.update(progressBar.current 1, ${colors.red}${currentItem} (失败)${colors.reset}); } } }; // 主函数 const main async () { try { console.log(\n colors.bright colors.bgBlue 中国地图数据下载工具 colors.reset \n); // 获取用户输入的输出目录 const outputDir await question(${colors.yellow}请输入输出目录路径 (直接回车默认为当前目录)${colors.reset}); const finalOutputDir outputDir || ./; // 获取地区信息用于省份选择 console.log(${colors.blue}ℹ${colors.reset} 正在获取地区信息...); const areaInfos await httpsGet(infoUrl); if (!areaInfos) { console.error(${colors.red}✗${colors.reset} 获取地区信息失败); return; } console.log(${colors.green}✓${colors.reset} 地区信息获取成功\n); // 提取所有省级行政区 const provinces Object.entries(areaInfos) .filter(([code]) code.endsWith(0000) code ! 100000) .map(([code, info]) ({ code, name: info.name })); // 选择下载范围全部省份 or 指定省份 const downloadScopeAnswer await question(${colors.yellow}请选择下载范围 (1: 全部省份, 2: 选择指定省份) [默认: 1]${colors.reset}); let selectedProvinces provinces; // 默认全部省份 if (downloadScopeAnswer 2) { // 列出所有省份 console.log(\n${colors.bright}可选省份列表${colors.reset}); provinces.forEach((province, index) { const num String(index 1).padStart(2, ); // 每行显示4个省份 const suffix (index 1) % 4 0 ? \n : \t; process.stdout.write(${colors.cyan}${num}.${colors.reset} ${province.name}${suffix}); }); // 确保换行 if (provinces.length % 4 ! 0) console.log(); console.log(); const provinceIndexAnswer await question(${colors.yellow}请输入省份序号多个用英文逗号分隔 (如: 1,5,11)${colors.reset}); // 解析输入的多个序号 const inputIndices provinceIndexAnswer.split(,).map(s s.trim()); const validProvinces []; const invalidIndices []; for (const indexStr of inputIndices) { const idx parseInt(indexStr, 10) - 1; if (idx 0 idx provinces.length !isNaN(idx)) { // 避免重复添加 if (!validProvinces.find(p p.code provinces[idx].code)) { validProvinces.push(provinces[idx]); } } else { invalidIndices.push(indexStr); } } // 报告无效序号 if (invalidIndices.length 0) { console.log(${colors.yellow}⚠${colors.reset} 忽略无效序号: ${invalidIndices.join(, )}); } if (validProvinces.length 0) { console.error(${colors.red}✗${colors.reset} 没有有效的省份序号退出程序); return; } selectedProvinces validProvinces; const selectedNames selectedProvinces.map(p p.name).join(、); console.log(${colors.green}✓${colors.reset} 已选择 ${colors.bright}${selectedProvinces.length}${colors.reset} 个省份: ${colors.bright}${selectedNames}${colors.reset}\n); } // 获取用户选择的命名方式 const nameFormatAnswer await question(${colors.yellow}请选择文件命名方式 (1: 行政代码, 2: 中文名称) [默认: 1]${colors.reset}); const nameFormat nameFormatAnswer 2 ? chinese : adcode; // 获取省级地图数据粒度 const provinceLevelAnswer await question(${colors.yellow}请选择省级地图数据粒度 (1: 包含市级边界, 2: 包含区县级边界, 3: 不包含下级边界) [默认: 1]${colors.reset}); const provinceLevel provinceLevelAnswer 2 ? 2 : (provinceLevelAnswer 3 ? 3 : 1); // 获取市级地图数据粒度 const cityLevelAnswer await question(${colors.yellow}请选择市级地图数据粒度 (1: 包含区县级边界, 2: 不包含下级边界) [默认: 1]${colors.reset}); const cityLevel cityLevelAnswer 2 ? 2 : 1; // 添加直辖市下级区存放位置的选择 const municipalityAnswer await question(${colors.yellow}是否将直辖市下级区地图放在citys文件夹下便于地图下钻的逻辑处理(y/n) [默认: y]${colors.reset}); municipalityChildrenInCitys municipalityAnswer.toLowerCase() ! n; // 创建输出目录 createDir(finalOutputDir); createDir(path.join(finalOutputDir, province)); createDir(path.join(finalOutputDir, citys)); createDir(path.join(finalOutputDir, county)); // 保存压缩版的 info.json fs.writeFileSync(path.join(finalOutputDir, info.json), JSON.stringify(areaInfos)); console.log(${colors.green}✓${colors.reset} 地区信息已保存至 info.json); // 计算总任务数基于选中的省份 let totalFiles 1; // 全国地图 for (const province of selectedProvinces) { const provinceCode province.code; const cities Object.entries(areaInfos).filter(([code]) code.startsWith(provinceCode.slice(0, 2)) code.endsWith(00) code ! provinceCode ); totalFiles; // 省级地图 totalFiles cities.length; // 市级地图 for (const [cityCode] of cities) { const counties Object.entries(areaInfos).filter(([code]) code.startsWith(cityCode.slice(0, 4)) !code.endsWith(00) ); totalFiles counties.length; // 县级地图 } } console.log(${colors.blue}ℹ${colors.reset} 总计需要下载 ${colors.yellow}${totalFiles}${colors.reset} 个地图文件); console.log(${colors.blue}ℹ${colors.reset} 共有 ${colors.yellow}${selectedProvinces.length}${colors.reset} 个省级行政区待下载\n); // 下载全国地图 const chinaInfo areaInfos[100000]; await downloadJson( ${baseUrl}100000.json, path.join(finalOutputDir, getFileName(100000, chinaInfo, , nameFormat)), chinaInfo ); console.log(${colors.blue}→${colors.reset} 全国地图下载完成\n); // 处理选中的省级数据 for (const province of selectedProvinces) { const provinceCode province.code; const info areaInfos[provinceCode]; // 获取所有下级行政区 const cities Object.entries(areaInfos).filter(([code]) code.startsWith(provinceCode.slice(0, 2)) code.endsWith(00) code ! provinceCode ); const counties Object.entries(areaInfos).filter(([code]) code.startsWith(provinceCode.slice(0, 2)) !code.endsWith(00) ); // 计算该省的总任务数 let provinceTotalTasks 1; // 省级地图 // 添加市级地图任务数 if (provinceLevel ! 3) { provinceTotalTasks cities.length; } // 添加区县级地图任务数如果需要 if (provinceLevel 2 || (provinceLevel ! 3 cityLevel 1)) { provinceTotalTasks counties.length; } console.log(${colors.blue}→${colors.reset} 开始处理: ${colors.bright}${info.name}${colors.reset}); console.log(${colors.blue}ℹ${colors.reset} 需要下载 ${colors.yellow}${provinceTotalTasks}${colors.reset} 个地图文件); const progressBar new ProgressBar(info.name, provinceTotalTasks); // 下载省级地图根据选择的粒度决定是否使用 full 版本 await downloadJson( ${baseUrl}${provinceCode}.json, path.join(finalOutputDir, province, getFileName(provinceCode, info, , nameFormat)), info, progressBar, 省级地图, provinceLevel ! 3 // 如果不是跳过下级边界则尝试下载 full 版本 ); // 如果不是跳过下级边界 if (provinceLevel ! 3) { // 下载市级地图 for (const [cityCode, cityInfo] of cities) { await downloadJson( ${baseUrl}${cityCode}.json, path.join(finalOutputDir, citys, getFileName(cityCode, cityInfo, , nameFormat)), cityInfo, progressBar, 市级: ${cityInfo.name}, cityLevel 1 // 如果选择包含区县级边界则尝试下载 full 版本 ); } // 下载区县级地图如果需要 if (provinceLevel 2 || cityLevel 1) { for (const [countyCode, countyInfo] of counties) { // 确定目标目录 const isMunicipality MUNICIPALITIES.includes(provinceCode); const targetDir (isMunicipality municipalityChildrenInCitys) ? citys : county; await downloadJson( ${baseUrl}${countyCode}.json, path.join(finalOutputDir, targetDir, getFileName(countyCode, countyInfo, , nameFormat)), countyInfo, progressBar, 区县: ${countyInfo.name} ); } } } progressBar.complete(); console.log(${colors.green}✓${colors.reset} ${colors.bright}${info.name}${colors.reset} 处理完成\n); } console.log(${colors.green}✨${colors.reset} ${colors.bright}所有地图数据下载完成${colors.reset}\n); } catch (error) { console.error(${colors.red}错误:${colors.reset}, error.message); } finally { rl.close(); } }; // 添加错误处理 process.on(unhandledRejection, (error) { console.error(${colors.red}✗${colors.reset} 未处理的 Promise 拒绝:, error); process.exit(1); }); main();代码片段template div classmap-box v-chart :optionmapOption classmap-chart clickhandleMapClick :resizeabletrue/ !-- 通过v-chart组件渲染地图 -- el-button typewarning classback-btn clickhandleBack返回上一级/el-button /div /template script setup import { ref, provide, onMounted, watch } from vue import VChart, { THEME_KEY } from vue-echarts // 引入v-chart组件 import * as echarts from echarts // 引入echarts import ChinaGroJson from /assets/map-json/100000.json // 引入全国地图json文件这里只引入全国地图json文件即可 import ziben2 from /assets/images/digitalTwin/ziben2.png // 引入全国地图json文件这里只引入全国地图json文件即可 import axios from axios import { useRouter } from vue-router const router useRouter() provide(THEME_KEY, light) // 提供主题dark / light const props defineProps({ dialogContent: { type: Object, default: {} } }) watch(() props.dialogContent, (newVal) { }, {deep: true }); const mapOption ref() // 地图配置 const geoJson { // 地图json数据 只初始化全国地图json文件其他省市县地图json文件在下面代码里动态获取,例如当前地图切换为北京则geoJson.province存储的就是北京市的地图json数据切换为天津则geoJson.province存储的就是天津市的地图json数据 china: ChinaGroJson, province: null, // 省 city: null, // 市 county: null // 县 } const currentLevel ref(china) // 当前地图级别默认为全国 const levelConfig { // 地图层级配置用于描述地图的层级关系 china: { nextLevel: province, // 下一级表示点击地图后地图要跳转到的下一级 geoKey: china, // 地图key表示地图的层级名称 jsonPath: province // 地图json路径表示地图json文件的存储路径 }, province: { nextLevel: city, geoKey: province, jsonPath: citys }, city: { nextLevel: county, geoKey: city, jsonPath: county } } // 文本 const geoText ref({ china: china, province: null, // 省 city: null, // 市 county: null // 县 }) const showDialog ref(true) /** * 设置地图option这里直接使用最基础的地图配置可以根据需求自行修改 * param {Array} mapData 地图要用的data数据 * param {String} mapName 地图名称 */ const setMapOption (mapData, mapName china) { mapOption.value { tooltip: { trigger: item, triggerOn: mousemove|click, // 触发条件 backgroundColor: rgba(22, 12, 5, 0.96), borderColor: #f2a13b, borderWidth: 1, padding: [8, 12], textStyle: { color: #fff5e7, fontSize: 13 }, axisPointer: { type: line, lineStyle: { color: rgba(255, 203, 112, 0.75), width: 1 }, }, formatter: {b} // 鼠标悬浮显示地区名称 // 数据格式化 // formatter: function(params) { // return ( // params.seriesName br / params.name params.value // ); // }, }, // backgroundColor: #0E2152, // 背景颜色 series: [ // { // name: mapName 全国 ? china : mapName, // type: map, // map: mapName, // roam: false, // 开启缩放和平移 // data: mapData // }, { type: currentLevel.value county ? scatter : effectScatter, // effectScatter|scatter带有涟漪特效动画的散点气泡图 coordinateSystem: geo, //该系列使用的坐标系:地理坐标系 effectType: ripple, // 特效类型,目前只支持涟漪特效ripple意为“涟漪” showEffectOn: render, // 配置何时显示特效。可选render和emphasis rippleEffect: { // 涟漪特效相关配置。 period: 10, // 动画的周期秒数。 scale: 4, // 动画中波纹的最大缩放比例。 brushType: fill, // 波纹的绘制方式可选 stroke 和 fill。 }, zlevel: 1, // 这里是关键一定要放在 series中显示层级 hoverAnimation: true, itemStyle: { normal: { // color: function(params){ // return levelColorMap[params.value[3]]; // }, color: rgba(255, 235, 59, .7), shadowBlur: 10, shadowColor: #333 } }, tooltip: { trigger: item, backgroundColor: transparent, borderColor: transparent, formatter: function (params) { return formatHtml(params.data); }, }, // symbol: image://${require(/assets/img/point.png)}, symbol: currentLevel.value county ? image://${new URL(/assets/images/digitalTwin/默认.png, import.meta.url)} : , symbolSize: currentLevel.value county ? [64, 36] : [8, 8], // symbolOffset: [-5, 0], label: { formatter: {b}, position: insideTop, show: currentLevel.value county ? true : false, textStyle: { color: #fff, fontSize: 12, } }, // data: gatewayPointData.value[mapName] ? gatewayPointData.value[mapName] : gatewayPointData.value[geoText.value[currentLevel.value]], // 筛选显示 data: [ { name: 鹿洼煤矿, value: [116.59,35.10], companyId: 583871900 }, { name: 化学公司, value: [116.55,35.10], companyId: 1101552392322834400 }, { name: 热电公司, value: [116.54,35.085], companyId: 1101552392322834400 }, { name: 建材公司, value: [116.58,35.08], companyId: 1101552768161833000 }, { name: 鲁泰集团, value: [116.60,35.37], companyId: 1002198288 }, { name: 太平煤矿, value: [116.77,35.37], companyId: 1101552392322834400 }, { name: 鲁泰矿业西北分公司, value: [109.76,38.28] }, { name: 新疆明基能源, value: [86.48,43.82] }, ], }, ], geo: { map: mapName 全国 ? china : mapName, // roam: false, label: { // 图形上的文本标签 normal: { // 通常状态下的样式 show: true, textStyle: { color: #fff, }, }, emphasis: { // 鼠标放上去高亮的样式 textStyle: { color: #fff, }, }, }, itemStyle: { normal: { // 地图区域的样式设置 borderColor: #f2a13b, borderWidth: 1, areaColor: { // image: image://${require(/assets/img/china-map.png)}, // repeat: repeat, type: radial, // 径向渐变 x: 0.5, // 圆心 y: 0.5, // 圆心 r: 0.8, // 半径 colorStops: [ { offset: 0, color: rgba(242, 161, 59, 0), }, // 0% 处的颜色 { offset: 0.5, color: rgba(242, 161, 59, .6), },// 100% 处的颜色 { offset: 1, color: rgba(242, 161, 59, .4), },// 100% 处的颜色 ], // colorStops: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ // ]), }, shadowColor: rgba(78, 59, 45, 0.8), //底层颜色 shadowOffsetX: 9, shadowOffsetY: 8, }, emphasis: { // 鼠标放上去高亮的样式 areaColor: #99631d, borderWidth: 0, }, }, }, } } const gatewayPointData ref({ china: [ { name: 山东省, value: [118.03,36.67] }, { name: 陕西省, value: [108.96,34.28] }, { name: 新疆维吾尔自治区, value: [87.63,43.80] }, ], 山东省: [ { name: 济宁市, value: [116.59,35.42] }, ], 陕西省: [ { name: 榆林市, value: [109.74,38.29] }, ], 新疆维吾尔自治区: [ { name: 昌吉回族自治州, value: [90.01,44.02] }, ], 济宁市: [ { name: 鱼台县, value: [116.66,35.02] }, { name: 任城区, value: [116.55,35.49] }, { name: 邹城市, value: [117.01,35.41] }, ], 榆林市: [ { name: 榆阳区, value: [109.73,38.28] }, ], 昌吉回族自治州: [ { name: 呼图壁县, value: [86.51,43.82] }, ], 鱼台县: [ { name: 鹿洼煤矿, value: [116.59,35.10], companyId: 583871900 }, { name: 化学公司, value: [116.55,35.10], companyId: 1101552392322834400 }, { name: 热电公司, value: [116.54,35.085], companyId: 1101552392322834400 }, { name: 建材公司, value: [116.58,35.08], companyId: 1101552768161833000 }, ], 任城区: [ { name: 鲁泰集团, value: [116.60,35.37], companyId: 1002198288 }, ], 邹城市: [ { name: 太平煤矿, value: [116.77,35.37], companyId: 1101552392322834400 }, ], 榆阳区: [ { name: 鲁泰矿业西北分公司, value: [109.76,38.28] }, ], 呼图壁县: [ { name: 新疆明基能源, value: [86.48,43.82] }, ] }) let landmarkArr ref([]) const formatHtml ({name, companyId}) { const targetCompany props.dialogContent.find( (v) v.companyId companyId ) if(!targetCompany) return return div classdialog div classtitle${name}/div div classdialog-middle div classdialog-middle-box div classleft img src${ziben2} alt / div p注册资本/万元/p p${targetCompany.funds}/p /div /div div classright img src${ziben2} alt / div p${targetCompany.honor ? targetCompany.honor : }/p p${targetCompany.remark ? targetCompany.remark : }/p /div /div /div /div div classdialog-content${ targetCompany.introduce }/div /div ; } const handleMapClick async event { // 地图点击事件 // console.log(event) const currentConfig levelConfig[currentLevel.value] // 获取当前地图层级配置 if(event.name 南海诸岛) return if (currentConfig) { currentLevel.value currentConfig.nextLevel // 更新当前层级把下一级作为当前层级存储到currentLevel中 const adcode geoJson[currentConfig.geoKey].features.find(item item.properties.name event.name).properties.adcode // 获取地区编码从geoJson中对应层级存储的json文件中获取 try { // const newGeoJson await import(/assets/map-json/${currentConfig.jsonPath}/${adcode}.json) // 动态获取下一级地图json文件, 例如/assets/map-json/citys/110100.json const newGeoJson await (await axios.get(map-json/${currentConfig.jsonPath}/${adcode}.json)).data geoJson[currentConfig.nextLevel] newGeoJson // 将获取到的地图json数据赋值到geoJson里对应的层级 geoText.value[currentLevel.value] event.name echarts.registerMap(event.name, geoJson[currentConfig.nextLevel]) // 注册新地图 if(currentConfig.nextLevel county) { if(gatewayPointData.value[event.name]) landmarkArr.value gatewayPointData.value[event.name] } setMapOption([地图数据], event.name) // 设置新地图配置 } catch (error) { console.log(地图数据加载失败, error) handleBack() // 如果加载失败则返回上一级 } } else { const filterData landmarkArr.value.filter(obj obj.name event.name) if(filterData?.[0].companyId) { // TODO: 我需要跳转vue页面哦 router.push({ path: /digitalTwin/Dt, query: { name: event.name } }) } } } // 返回上一级 const handleBack () { if (currentLevel.value china) return // 如果已经是最顶层则不处理 const prevLevels { province: china, city: province, county: city } const prevLevel prevLevels[currentLevel.value] // 获取上一级配置 currentLevel.value prevLevel // 返回上一级 echarts.registerMap(prevLevel, geoJson[prevLevel]) // 重新注册上一级地图例如我们当前层级是青岛市地图geoJson.province依然存储着山东省的地图此时我们直接使用即可 setMapOption([地图数据], prevLevel) // 设置新地图配置 } // 组件挂载初始化全国地图 onMounted(() { echarts.registerMap(china, geoJson.china) setMapOption([地图数据], china) }) /script style langscss scoped .map-box { box-sizing: border-box; position: relative; width: 100%; height: 100%; // background: url(/assets/images/digitalTwin/dashboard-bg.png) no-repeat; .back-btn { position: absolute; // color: #755628; color: #ffffff; background-color: rgba(29, 27, 23, 0.6); top: 3vw; left: 0; } } .map-chart { width: 100%; height: 100%; } :deep(.dialog) { width: vw(357); height: vw(200); background: url(/assets/images/digitalTwin/弹框.png) no-repeat; background-size: 100% 100%; margin-left: vw(10); position: absolute; z-index: 99999; padding: vw(12); .title { margin-left: vw(20); font-weight: 600; font-size: vw(16); margin-top: vw(-8); } .dialog-middle { height: vw(70); margin-top: vw(10); } .dialog-middle-box { display: flex; height: 100%; justify-content: space-around; align-items: center; .left, .right { flex: 1; height: vw(62); background: url(/assets/images/digitalTwin/center_item.png) no-repeat; background-size: 100% 100%; display: flex; div { display: flex; flex-direction: column; justify-content: space-evenly; align-items: flex-end; margin-left: vw(5); :first-child { color: #ffba57; font-size: vw(14); } :nth-child(2) { background-image: linear-gradient( to bottom, #ffffff 70%, #ffd493 30% ); font-size: vw(16); font-weight: 700; -webkit-background-clip: text; font-family: AlimamaShuHeiTi, sans-serif; background-clip: text; color: transparent; } p { display: -webkit-box; -webkit-line-clamp: 1; /* 要显示几行就填几 */ -webkit-box-orient: vertical; overflow: hidden; white-space: wrap; text-overflow: ellipsis; } } img { width: vw(32); height: vw(32); margin-top: vw(14); margin-left: vw(18); } } .left { margin-right: vw(14); } } .dialog-content { line-height: vw(25); font-size: vw(16); display: -webkit-box; -webkit-line-clamp: 4; /* 要显示几行就填几 */ -webkit-box-orient: vertical; overflow: hidden; /*这两行代码可以解决大部分场景下的换行问题*/ word-break: break-all; word-wrap: break-word; /*但在有些场景中还需要加上下面这行代码*/ white-space: normal; } } /style资源片段其它相关案例参考echarts map地图动态下钻,自定义标注,自定义tooltip弹窗【完整demo版本】_地图下钻-CSDN博客