ECharts 5.4 离线地图实战:3步加载本地JSON文件,实现省市区三级下钻
2026/7/13 12:26:47 网站建设 项目流程

ECharts 5.4 离线地图实战:3步实现省市区三级下钻可视化

在数据可视化领域,地图展示一直是呈现地理分布信息的核心方式。当项目需要在内网环境或网络条件受限的场景下运行时,离线地图解决方案显得尤为重要。本文将基于ECharts 5.4版本,手把手教你如何通过本地JSON文件实现中国地图的省市区三级下钻功能,无需依赖任何在线地图服务。

1. 环境准备与数据获取

1.1 项目基础配置

首先创建一个标准的HTML5项目结构,引入必要的ECharts库文件。建议使用官方构建的完整版本以包含地图组件:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>ECharts离线地图示例</title> <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script> <style> #map-container { width: 100%; height: 600px; } </style> </head> <body> <div id="map-container"></div> <script src="app.js"></script> </body> </html>

1.2 地图数据准备

离线地图的核心是GeoJSON数据文件。中国行政区划数据通常包含三个层级:

文件类型描述典型路径
国家级别中国整体轮廓/geo/china.json
省级别各省/直辖市边界/geo/province/
市级别各地级市边界/geo/city/

推荐从以下渠道获取规范的GeoJSON数据:

  • 阿里云DataV提供的 GeoAtlas
  • GitHub开源项目如 echarts-china-geojson
  • 国家基础地理信息中心公开数据

注意:确保获取的GeoJSON数据采用WGS84坐标系(EPSG:4326),这是ECharts地图的标准坐标参考系统。

2. 地图加载与渲染

2.1 初始化ECharts实例

在app.js中创建基础地图实例,配置初始参数:

const chartDom = document.getElementById('map-container'); const myChart = echarts.init(chartDom); const option = { title: { text: '中国行政区划地图', left: 'center' }, tooltip: { trigger: 'item', formatter: '{b}' }, series: [{ name: '中国', type: 'map', map: 'china', roam: true, label: { show: true, fontSize: 10 }, emphasis: { label: { show: true } } }] }; // 使用fetch API加载中国地图JSON fetch('./geo/china.json') .then(response => response.json()) .then(geoJson => { // 注册地图数据 echarts.registerMap('china', geoJson); myChart.setOption(option); });

2.2 实现省级下钻功能

扩展基础代码实现点击省份下钻到该省详细地图的功能:

let currentLevel = 'country'; // 当前视图层级 let currentProvince = ''; // 当前选中省份 myChart.on('click', function(params) { if (currentLevel === 'country' && params.componentSubType === 'map') { // 获取点击的省份名称 const provinceName = params.name; currentProvince = provinceName; // 根据省份ID加载对应GeoJSON const provinceId = getProvinceIdByName(provinceName); fetch(`./geo/province/${provinceId}.json`) .then(response => response.json()) .then(geoJson => { echarts.registerMap(provinceName, geoJson); // 更新图表配置 myChart.setOption({ series: [{ map: provinceName, data: [] }], title: { text: `${provinceName}行政区划` }, toolbox: { feature: { myBack: { show: true, title: '返回全国', icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.45,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891', onclick: function() { resetToCountryView(); } } } } }); currentLevel = 'province'; }); } }); function getProvinceIdByName(name) { // 省份名称到文件ID的映射表 const provinceMap = { '北京': '11', '天津': '12', '河北': '13', // 其他省份映射... '台湾': '71', '香港': '81', '澳门': '82' }; return provinceMap[name]; } function resetToCountryView() { currentLevel = 'country'; myChart.setOption(option); }

3. 实现完整三级下钻

3.1 市级地图加载逻辑

在省级下钻基础上继续扩展市级下钻功能:

myChart.on('click', function(params) { if (currentLevel === 'country' && params.componentSubType === 'map') { // 省级下钻逻辑(同上) } else if (currentLevel === 'province' && params.componentSubType === 'map') { const cityName = params.name; const cityId = getCityIdByName(cityName, currentProvince); fetch(`./geo/city/${cityId}.json`) .then(response => response.json()) .then(geoJson => { echarts.registerMap(cityName, geoJson); myChart.setOption({ series: [{ map: cityName, data: [] }], title: { text: `${currentProvince}·${cityName}地图` } }); currentLevel = 'city'; }); } }); function getCityIdByName(cityName, provinceName) { // 实际项目中这里需要建立完整的城市ID映射表 // 示例:河北省下各城市ID const cityMap = { '河北': { '石家庄': '1301', '唐山': '1302', '秦皇岛': '1303', // 其他城市... } // 其他省份... }; return cityMap[provinceName][cityName]; }

3.2 增强交互体验

为提升用户体验,添加以下交互功能:

  1. 面包屑导航
function updateBreadcrumb() { const breadcrumb = document.createElement('div'); breadcrumb.id = 'breadcrumb'; breadcrumb.style.position = 'absolute'; breadcrumb.style.top = '10px'; breadcrumb.style.left = '20px'; breadcrumb.style.zIndex = '100'; let html = '<span style="cursor:pointer" onclick="resetToCountryView()">中国</span>'; if (currentLevel === 'province') { html += ` > ${currentProvince}`; } else if (currentLevel === 'city') { html += ` > <span onclick="backToProvince()">${currentProvince}</span> > ${currentCity}`; } breadcrumb.innerHTML = html; chartDom.appendChild(breadcrumb); } function backToProvince() { // 返回省级视图的实现 }
  1. 区域高亮与数据绑定
// 在series配置中添加visualMap visualMap: { min: 0, max: 100, text: ['高', '低'], realtime: false, calculable: true, inRange: { color: ['#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'] } } // 绑定示例数据 data: [ {name: '北京', value: 83}, {name: '天津', value: 65}, // 其他数据... ]

4. 性能优化与错误处理

4.1 常见问题解决方案

问题现象可能原因解决方案
地图显示空白JSON文件路径错误检查控制台网络请求,验证文件路径
区域名称不匹配GeoJSON属性字段不一致统一使用"name"作为区域名称字段
下钻后边界显示异常不同层级数据坐标系不一致确保所有GeoJSON使用相同坐标系
移动端显示模糊未设置设备像素比初始化时添加echarts.init(dom, null, {devicePixelRatio: 2})

4.2 实现数据缓存

为避免重复加载相同GeoJSON文件,添加简单的缓存机制:

const geoJsonCache = {}; function loadGeoJson(url) { if (geoJsonCache[url]) { return Promise.resolve(geoJsonCache[url]); } return fetch(url) .then(response => response.json()) .then(data => { geoJsonCache[url] = data; return data; }); }

4.3 响应式适配

确保地图在不同屏幕尺寸下正常显示:

window.addEventListener('resize', function() { myChart.resize(); }); // 在CSS中添加响应式样式 @media (max-width: 768px) { #map-container { height: 400px; } .echarts-tooltip { font-size: 12px; } }

通过以上步骤,我们构建了一个完整的离线地图可视化方案。在实际项目中,可以根据需求进一步扩展以下功能:

  • 添加热力图、迁徙图等扩展图表类型
  • 集成本地数据库实现动态数据绑定
  • 开发更复杂的下钻策略(如直接下钻到区县级别)
  • 实现地图截图导出功能

这种方案特别适合政府内网、涉密项目等需要完全离线运行的环境,既保证了数据安全,又提供了专业级的可视化效果。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询