简介:本资源提供 ECharts 3D 地图所需的 china.json 地理数据文件,面向从事 Web 数据可视化开发的前端工程师与数据大屏设计者,用于在三维空间中渲染中国地图并展示区域数据差异。压缩包内共 1 个文件,为 GeoJSON 格式的 json 数据,包含中国各省级行政区的边界坐标与属性信息,可直接通过 echarts.registerMap 注册后配合 geo3D 组件使用,整体包体约 13KB,体积轻量便于快速集成。该数据支持区域颜色、边界样式、标签显示及平移缩放等交互配置,适合构建地理数据大屏、区域统计展示等场景。目前已有 246 人学习下载,可作为 3D 地图开发的即用型基础数据,帮助开发者省去自行整理地理边界的工作,将精力集中于视觉定制与业务数据接入。
1. 从一份 china.json 说起:ECharts 3D 地图到底能跑出什么效果
前阵子帮一个做数据看板的朋友排查问题,他甩过来一个压缩包,里面就一个china.json,说“地图加载不出来,控制台报 404”。我打开一看,他项目里 ECharts 版本是 5.x,却还在用echarts/map/json/china.json这种老路径去引,而新版 ECharts 早就把内置地图数据剥离出去了。这个坑其实特别典型——很多人搜“echarts 3d json”,本质上是想找一份能直接喂给geo3D或map3D组件的中国地图 GeoJSON 数据,然后快速搭出一个带立体感、能交互的区域可视化页面。
这份资源就是干这个的:一份标准的china.json地理边界数据,配合 ECharts 的 GL 扩展,能渲染出可旋转、可缩放、可下钻的 3D 地图。它适合两类人:一是做数据大屏、区域业务监控的前端,需要快速出效果;二是想基于地图做二次开发,比如叠加散点、飞线、热力层的开发者。下面我就按“数据怎么用 → 环境怎么搭 → 代码怎么写 → 坑怎么避 → 怎么改”的顺序,把这份资源拆开讲透。
2. 数据与渲染链路:china.json 在 ECharts 3D 里扮演什么角色
2.1 GeoJSON 数据结构与 ECharts 的消费方式
china.json本质是一个 GeoJSON 格式的 FeatureCollection,里面每个 Feature 代表一个省级行政区,geometry字段存的是多边形坐标串,properties里通常带name、cp(中心点)等属性。ECharts 的registerMap方法会读取这份数据,把它转成内部的地图坐标系。3D 模式下,geo3D组件再基于这些边界做三角剖分,生成带高度的立体面。
// 引入 ECharts 核心与 GL 扩展 import * as echarts from 'echarts'; import 'echarts-gl'; // 3D 能力依赖这个扩展包 // 异步加载本地 china.json,注册为名为 'china' 的地图 fetch('/static/map/china.json') .then(res => res.json()) .then(geoJson => { echarts.registerMap('china', geoJson); // 关键一步:注册后才能被 geo3D 引用 initChart(); }); function initChart() { const chart = echarts.init(document.getElementById('map')); chart.setOption({ geo3D: { map: 'china', // 对应 registerMap 的名字 roam: true, // 开启旋转缩放 itemStyle: { areaColor: '#1a3a5c', borderColor: '#4fd1ff', borderWidth: 1 }, viewControl: { alpha: 45, // 俯仰角,控制立体感 beta: 0, // 旋转角 distance: 120 // 视距,越小越近 } } }); }这段代码里,registerMap是整条链路的枢纽——没有它,geo3D.map找不到数据源,页面就是一片空白。viewControl的三个参数决定了你第一眼看到的立体角度,alpha给 40 到 60 之间比较舒服,太小像平面,太大像俯冲。roam: true让用户能用鼠标拖拽旋转,这是 3D 地图区别于 2D 的核心体验。
2.2 3D 与 2D 地图的选型差异
很多人纠结到底用geo(2D)还是geo3D。从渲染成本看,2D 走 Canvas 或 SVG,几千个区域也扛得住;3D 走 WebGL,面数一多、叠加图层一复杂,低端显卡直接掉帧。从交互看,2D 适合精确点击下钻,3D 适合展示宏观态势。我一般建议:如果只是省市区三级联动,用 2D;如果要做大屏那种带光效、带高度柱的,才上 3D。
| 维度 | geo(2D) | geo3D(3D) |
|---|---|---|
| 渲染引擎 | Canvas / SVG | WebGL |
| 数据依赖 | registerMap 后直接可用 | 需 echarts-gl 扩展 |
| 交互方式 | 点击、缩放 | 旋转、缩放、俯仰 |
| 性能瓶颈 | 区域数量 | 面数 + 叠加图层数 |
| 适用场景 | 业务下钻、表单联动 | 数据大屏、态势展示 |
选型定下来之后,环境搭建就是下一步。这里有个容易被忽略的点:echarts-gl的版本必须和echarts主版本匹配,5.x 的 echarts 配 2.x 的 gl,混用会出现geo3D is not a function这种玄学报错。
3. 环境搭建与最小可运行 Demo:从零到看见立体中国
3.1 依赖安装与目录组织
不管你用 Vue、React 还是原生页面,依赖就两个:echarts和echarts-gl。用 npm 装的话,建议锁版本,避免自动升级带来的兼容问题。
# 初始化项目(以 Vite 为例) npm create vite@latest my-map-demo -- --template vanilla cd my-map-demo # 安装核心依赖,锁大版本 npm install echarts@5 echarts-gl@2 # 把 china.json 放到 public 目录,构建时不会被处理,直接可访问 mkdir -p public/map # 将下载的 china.json 复制到 public/map/china.json目录结构建议这样组织:public/map/china.json放地理数据,src/main.js写初始化逻辑,index.html里给一个固定宽高的容器。容器必须有明确高度,否则 ECharts 初始化时拿不到尺寸,图表不显示——这是新手最常见的翻车点之一。
3.2 完整初始化代码与参数说明
下面是一个能直接跑起来的最小 Demo,包含地图注册、3D 配置和自适应。
import * as echarts from 'echarts'; import 'echarts-gl'; const chartDom = document.getElementById('map'); const chart = echarts.init(chartDom); // 加载并注册地图 async function loadMap() { const res = await fetch('/map/china.json'); const geoJson = await res.json(); echarts.registerMap('china', geoJson); chart.setOption({ backgroundColor: '#0b1a2b', // 深色底,突出地图 geo3D: { map: 'china', roam: true, regionHeight: 3, // 区域挤出高度,值越大越厚 itemStyle: { color: '#1f4e79', opacity: 0.9, borderWidth: 1, borderColor: '#6ec6ff' }, emphasis: { // 鼠标悬浮高亮 itemStyle: { color: '#ffd166' }, label: { show: true, color: '#fff' } }, label: { show: false, // 默认不显示省名,避免拥挤 formatter: '{b}' }, viewControl: { alpha: 50, beta: 10, distance: 110, autoRotate: false, // 自动旋转,大屏可开 autoRotateSpeed: 5 }, light: { // 光照配置,影响立体明暗 main: { intensity: 1.2, shadow: true }, ambient: { intensity: 0.3 } } } }); } loadMap(); // 窗口变化时自适应 window.addEventListener('resize', () => chart.resize());逐项说下关键参数:regionHeight控制每个省挤出的厚度,设 0 就是平面,设 3 到 8 立体感明显;light.main.shadow开启阴影后,区域之间的层次会清楚很多,但性能开销也上去;autoRotate适合无人值守的大屏,配上autoRotateSpeed控制转速,太快会让人晕。emphasis里的高亮色建议和主色拉开对比,不然悬浮反馈不明显。
3.3 验证运行结果
跑npm run dev之后,浏览器打开对应地址,应该能看到一个深色背景上的立体中国地图,鼠标拖拽能旋转,滚轮能缩放,悬浮到某个省上会变色。如果只看到背景色没有地图,按 F12 看 Network 里china.json是否 200,再看 Console 有没有Map china not exists的报错——有的话就是registerMap没执行成功,多半是 fetch 路径写错了。
4. 常见问题排查:地图不显示、报错、卡顿的 5 个真实坑
4.1 地图一片空白,控制台报 Map not exists
现象是页面只有背景色,Console 提示Map china not exists。原因通常是registerMap在setOption之后才执行,或者 fetch 失败导致注册逻辑没走到。解决办法是把setOption放进registerMap的回调里,确保顺序;同时检查china.json路径,Vite 项目里public下的文件要用/map/china.json这种绝对路径引,不能写相对路径。
4.2 报 geo3D is not a function
这个报错基本就是echarts-gl没装或没引入。现象是setOption时提示geo3D不是有效组件。原因是 ECharts 主包不含 3D 能力,必须额外引入echarts-gl。解决是在入口文件顶部import 'echarts-gl',并确认package.json里两个包的版本匹配,5.x 的 echarts 对应 2.x 的 gl。
4.3 地图能显示但拖不动、缩放没反应
现象是地图出来了,但鼠标交互无效。原因多半是roam没开,或者容器被上层元素挡住了鼠标事件。解决是确认geo3D.roam: true,再检查容器的 CSS 有没有pointer-events: none,以及父级有没有设置overflow: hidden导致事件被截断。
4.4 叠加散点后帧率骤降
现象是单独地图很流畅,加上scatter3D或lines3D后卡顿。原因是 3D 场景里每个数据点都参与光照和深度计算,点数过万就吃力。解决是控制数据量,或者把散点改成effectScatter只渲染关键点;另外关掉light.main.shadow能省不少性能。
4.5 省界边框粗细不一、有锯齿
现象是某些省边界看起来比别的粗,或者边缘有毛刺。原因是 GeoJSON 精度和屏幕像素比不匹配,加上borderWidth设得偏大。解决是把borderWidth降到 1 以内,并确认devicePixelRatio正常;如果数据源本身精度低,可以换更高精度的边界数据,但文件体积会变大。
5. 二次开发改造:从静态地图到业务可视化
5.1 叠加业务数据的三种方式
拿到这份china.json之后,真正让它有价值的是往上叠数据。最常用的是scatter3D打点,适合展示城市级指标;lines3D画飞线,适合展示区域间的流向;bar3D做柱状,适合对比各省数值。这三种可以共存,但要注意图层顺序,geo3D放最底层,业务图层依次往上加。
// 在 geo3D 同级追加散点与飞线 series: [ { type: 'scatter3D', coordinateSystem: 'geo3D', data: [ { name: '某区域A', value: [116.4, 39.9, 100] }, // 经纬度 + 数值 { name: '某区域B', value: [121.5, 31.2, 80] } ], symbolSize: 12, itemStyle: { color: '#ff6b6b' }, label: { show: true, formatter: '{b}' } }, { type: 'lines3D', coordinateSystem: 'geo3D', effect: { show: true, trailWidth: 2, trailLength: 0.3 }, data: [ { coords: [[116.4, 39.9], [121.5, 31.2]] } ], lineStyle: { color: '#4fd1ff', width: 1 } } ]coordinateSystem: 'geo3D'是关键,它告诉 ECharts 这些点要贴到 3D 地图的坐标系上。value数组前两位是经纬度,第三位是高度或权重。lines3D的effect开启后会有流动光效,trailLength控制拖尾长度,0.3 左右比较自然。
5.2 下钻交互与数据联动
3D 地图做下钻比 2D 麻烦,因为点击事件返回的是区域名,你需要再加载对应省份的 GeoJSON 重新注册。常见做法是准备一套省级 json,点击时chart.on('click', params => { ... })拿到params.name,然后 fetch 对应文件、registerMap新名字、更新geo3D.map。注意每次下钻要清空旧图层,否则数据会叠加。
5.3 我踩过的坑与验证习惯
有次改完配置,地图死活不显示,排查半小时才发现是china.json被构建工具当模块处理了,路径变了。从那以后我每次引入地理数据,都强制走一遍 Network 面板确认请求 200,再看 Console 有没有注册成功的日志。另外,3D 地图的配置项很多是“玄学”生效——比如light不设也能跑,但设了之后立体感完全不一样,建议一开始就把光照和阴影配好,别等效果不满意再回头补。希望这份拆解能帮你把这份china.json真正跑起来,也跑出自己想要的效果。
本文还有配套的精品资源,点击获取