eCharts 344个县区地图可视化:GeoJSON注册与动态下钻实战 简介本资源面向从事地域性数据分析、人口统计与经济指标展示的前端开发者与数据可视化学习者提供eCharts县级行政区划地图的完整实现参考。包内共391个文件以380个JSON地图数据文件为核心覆盖344个县区的边界与坐标信息另含6个JS脚本、2个HTML示例页面及1份docx说明文档压缩包约2.82MB结构清晰便于按需取用。资源附带两种实现方式的Demo分别演示预定义地图数据集引用与自定义地图数据集成两条技术路线可帮助读者理解地图数据加载、option配置、颜色映射与交互事件监听的完整流程。目前已有1550人学习下载适合希望快速掌握县级地图渲染、将地理可视化集成到Web应用中的开发者参考借鉴。1. 344 个县区的地图为什么大多数团队第一步就卡住了做数据可视化的人迟早会撞上一个需求把全国 344 个县区级行政单元画到一张地图上按指标上色。听起来就是setOption的事真动手才发现坑在数据源——eCharts 官方地图包只到省级市级要自己找县级 GeoJSON 更是散落在各种渠道坐标系不统一、边界有重叠、名字对不上号。我见过不止一个团队在这卡了两天最后拿一张省级地图糊弄过去。这篇讲的就是怎么把 344 个县区的地图在 eCharts 里跑起来并且给出两种落地方式一种是直接注册 GeoJSON 的经典做法适合县区数量固定、需要精细控制样式的场景另一种是用geo组件配合map系列做动态切换适合需要下钻、联动、按需加载的场景。两种方式我都会给可复制的代码参数怎么调、哪里会翻车一并说清楚。适合正在做区域数据看板、业务覆盖分析、门店分布图的前端和数据同学。2. 先把地图数据这件事搞明白GeoJSON、坐标系与 344 这个数字2.1 344 个县区到底指什么“344 个县区”不是一个全国统一口径的数字。全国县级行政区划有 2800 多个344 通常是某个省、某个市、或者某个业务覆盖范围内的县区集合。所以第一步不是写代码是确认你手里的这份数据边界它覆盖哪些地级市、是否包含市辖区、是否包含功能区比如开发区、新区。我一般会先拿一份行政区划对照表把要画的县区名字列出来和 GeoJSON 里的properties.name逐个比对对不上的先记下来。常见做法是从公开的行政区划数据里筛出目标县区导出成一份清单再去找对应的边界数据。清单和边界数据必须能一一对应否则后面上色会出现“有数据没地图”或者“有地图没数据”的情况。2.2 GeoJSON 的最小结构eCharts 注册地图需要的是标准 GeoJSON核心就三块type、features、每个 feature 的properties和geometry。下面是一个县区的最小示例我把它拆开看{ type: FeatureCollection, features: [ { type: Feature, properties: { name: 某县, adcode: 000000 }, geometry: { type: Polygon, coordinates: [ [ [116.0, 36.0], [116.1, 36.0], [116.1, 36.1], [116.0, 36.1], [116.0, 36.0] ] ] } } ] }properties.name是 eCharts 用来匹配数据的键必须和你的数据里的name完全一致包括“县”“区”“市”这些后缀。adcode是行政区划代码可以用来做唯一标识避免重名。geometry里Polygon是单个多边形MultiPolygon是多个不相连的多边形比如岛屿eCharts 两种都支持。2.3 坐标系别让地图偏移几百米GeoJSON 常见的有 WGS84 和 GCJ02 两种坐标系。WGS84 是原始 GPS 坐标GCJ02 是国内地图服务常用的加密坐标。如果你拿到的边界数据是 GCJ02而底图或者散点数据是 WGS84叠加起来就会偏移。判断方法很简单找一个已知地标看它的坐标和地图上的位置是否吻合。我一般会统一用 GCJ02因为大部分公开的县区边界数据都是这个坐标系。如果你的数据源是 WGS84需要做一次转换转换库网上有现成的但要注意转换精度和边界点数量点太多会拖慢渲染。提示坐标系不统一是地图偏移最常见的原因先确认再写代码比事后调样式省事得多。3. 方式一注册 GeoJSON 直接画适合固定县区集合3.1 注册地图与初始化这种方式的核心是echarts.registerMap把 GeoJSON 注册成一个地图名然后在series里用map类型引用。下面是一个完整的最小可运行示例import * as echarts from echarts; import countyGeoJson from ./county-344.json; // 注册地图countyMap 是自定义地图名 echarts.registerMap(countyMap, countyGeoJson); const chart echarts.init(document.getElementById(map)); const option { tooltip: { trigger: item, formatter: {b}: {c} }, visualMap: { min: 0, max: 100, left: left, bottom: 10%, text: [高, 低], calculable: true, inRange: { color: [#e0f3f8, #4575b4] } }, series: [ { type: map, map: countyMap, // 对应 registerMap 的名字 roam: true, // 允许缩放和拖拽 label: { show: false // 县区太多默认不显示标签 }, itemStyle: { borderColor: #999, borderWidth: 0.5 }, emphasis: { label: { show: true }, itemStyle: { areaColor: #ffd700 } }, data: [] // 这里填你的指标数据 } ] }; chart.setOption(option);registerMap的第二个参数就是 GeoJSON 对象第一个参数是你自己起的名字后面series.map引用这个名字。roam: true开启缩放拖拽344 个县区在一张图上不开缩放基本没法看。label.show默认关掉因为县区名字密集全显示会糊成一片只在emphasis里打开悬停显示。3.2 数据绑定与 visualMap 上色数据格式是[{ name: 某县, value: 42 }, ...]name必须和 GeoJSON 里的properties.name一致。visualMap负责把数值映射到颜色min和max决定色带范围。如果数据里有异常值比如某个县区数值特别大会把其他县区的颜色压得很淡这时候要么手动设max要么用visualMap的pieces分段。const data [ { name: 某县, value: 42 }, { name: 某区, value: 78 }, // ... 其余县区 ]; // 把 data 塞进 series option.series[0].data data; chart.setOption(option);如果某些县区没有数据eCharts 会用默认颜色填充可以在itemStyle里设areaColor给一个灰色表示“无数据”。3.3 344 个县区的渲染性能344 个多边形每个多边形可能有几百到几千个点总点数可能到几十万。直接渲染一般没问题但如果加上标签、阴影、渐变帧率会掉。我一般会做三件事一是关闭label只在悬停时显示二是itemStyle里不用shadowBlur三是如果不需要缩放把roam关掉减少重绘。如果还是卡可以考虑用large模式或者把 GeoJSON 做一次简化减少点数。简化工具网上有但要注意别把边界简化得太厉害否则县区形状会变形。4. 方式二geo 组件 动态切换适合下钻和联动4.1 geo 组件与 map 系列的区别方式一用的是series.map地图和系列绑在一起。方式二用geo组件地图作为独立组件存在series里的map系列通过geoIndex关联到geo。这样做的好处是可以在同一个geo上叠加多个系列比如散点、线也可以动态切换geo的map属性来实现下钻。const option { geo: { map: countyMap, roam: true, label: { show: false }, itemStyle: { borderColor: #999, borderWidth: 0.5 }, emphasis: { itemStyle: { areaColor: #ffd700 } } }, series: [ { type: map, geoIndex: 0, // 关联到 geo 组件 data: [] } ] };geoIndex: 0表示这个系列用第 0 个geo组件的地图。geo组件负责地图的显示和交互series负责数据上色。这样拆分后切换地图只需要改geo.map不用重新注册整个系列。4.2 动态切换地图实现下钻下钻的逻辑是点击某个县区拿到它的adcode或名字去加载对应的下级 GeoJSON注册后更新geo.map。下面是一个简化的下钻示例chart.on(click, async (params) { if (params.componentType ! series) return; const adcode params.data.adcode; if (!adcode) return; // 加载下级 GeoJSON这里用 fetch 模拟 const res await fetch(/geo/${adcode}.json); const geoJson await res.json(); // 注册新地图 echarts.registerMap(map_${adcode}, geoJson); // 更新 geo 组件的 map chart.setOption({ geo: { map: map_${adcode} }, series: [{ data: [] }] // 清空数据等待新数据 }); });这里的关键是registerMap的名字要唯一用adcode拼接避免冲突。切换后series.data要清空否则旧数据会残留。实际项目里还要处理返回上一级、面包屑导航、加载状态这些属于业务逻辑不在本文展开。4.3 两种方式的选型对比对比项方式一series.map方式二geo map 系列适用场景固定县区集合样式精细控制需要下钻、联动、叠加多系列地图切换重新注册并更新 series改 geo.map 即可多系列叠加不方便方便geo 上可叠散点、线代码复杂度低中性能略好略差但差异不大我一般会先问需求如果只是画一张静态的县区分布图方式一够了如果要做点击下钻、和散点联动直接上方式二省得后面重构。5. 避坑与排查县区地图最容易翻车的 5 个地方5.1 名字对不上地图一片灰现象数据明明有地图上却全是默认色悬停也不显示数值。原因GeoJSON 里的properties.name和数据的name不一致比如一个是“某县”一个是“某县 ”多了空格或者一个是“某区”一个是“某市辖区”。解决写一个比对脚本把两边名字取出来做差集逐个修正。我一般会在数据加载后先跑一次校验把对不上的名字打印出来。5.2 地图偏移散点飘到海里现象县区边界和散点位置对不上整体偏移。原因坐标系不统一GeoJSON 是 GCJ02散点是 WGS84或者反过来。解决统一坐标系转换后再叠加。判断方法找一个已知地标看它的坐标和地图位置是否吻合。5.3 渲染卡顿拖拽掉帧现象344 个县区加载后缩放拖拽明显卡顿。原因多边形点数太多或者开了标签、阴影。解决关闭label去掉shadowBlur必要时简化 GeoJSON。如果还卡考虑分片加载先加载可视区域内的县区。5.4 边界重叠颜色互相覆盖现象相邻县区边界有重叠上色后边缘出现杂色。原因数据源本身有重叠或者简化后边界变形。解决用拓扑检查工具查一下重叠区域或者换一份质量更好的数据源。这个坑比较隐蔽放大后才能看到。5.5 下钻后返回地图没恢复现象下钻到县级后点返回地图还是县级的。原因geo.map没有改回上级地图名。解决在返回逻辑里重新setOption把geo.map设回上级地图名并清空数据。我一般会把地图层级和adcode存到一个栈里返回时弹栈。6. 进阶用 adcode 做唯一键把 344 个县区管起来前面一直用name做匹配但name有重名风险比如两个省都有“某县”。更稳的做法是用adcode做唯一键。eCharts 的series.data里可以带adcode然后在tooltip和点击事件里用adcode去查业务数据。const data [ { name: 某县, value: 42, adcode: 000000 }, // ... ]; // tooltip 里显示 adcode option.tooltip { trigger: item, formatter: (params) { const adcode params.data?.adcode || 未知; return ${params.name}br/adcode: ${adcode}br/值: ${params.value}; } };这样即使name有重复也能通过adcode区分。另外adcode还可以用来做数据校验把 GeoJSON 里的adcode和业务数据的adcode做交集快速找出缺失的县区。再进一步可以把 344 个县区的 GeoJSON 按adcode拆成单独文件按需加载。首屏只加载省级或市级地图点击后再加载对应县区的 GeoJSON。这样首屏体积小加载快适合县区数量多、但用户只看局部的情况。// 按需加载示例 async function loadCountyMap(adcode) { const res await fetch(/geo/county/${adcode}.json); const geoJson await res.json(); echarts.registerMap(county_${adcode}, geoJson); return county_${adcode}; }我自己的习惯是不管需求多简单先把adcode作为主键贯穿数据和地图后面加下钻、加联动、加校验都方便。这个习惯帮我省过好几次返工。希望帮到你。本文还有配套的精品资源点击获取