☰
ECharts 5 地图数据获取指南:从 GeoJSON 到 china.js 的完整实践
2026/10/13 16:03:43 网站建设 项目流程

简介:这份资源提供ECharts地图功能所必需的核心文件china.js,面向需要在Web项目中实现中国地图可视化的前端开发者与数据分析人员。由于ECharts新版本不再内置地图数据,该文件可解决地图无法渲染、省份坐标缺失等常见问题,适用于数据大屏、区域分布展示等场景。压缩包为rar格式,内含1个js文件,体积约43KB,解压后引入项目即可配合ECharts实例完成地图初始化与数据绑定。目前已有3243人学习下载,说明其在同类资源中具有较高参考价值。通过该文件,读者可快速补齐中国省份与地区的地理坐标信息,结合series中的data配置实现区域数值映射,并利用geo组件的roam、itemStyle、label等属性调整缩放平移与视觉样式,从而搭建出可交互的地图图表,同时规避自行整理坐标数据的繁琐过程。

1. 别再把 china.js 当成一个文件:ECharts 地图数据的真实获取路径

如果你最近在搜「echarts地图china.js下载」,大概率是遇到了同一个场景:项目里要画一张中国地图,按老教程写了import 'echarts/map/js/china',结果控制台直接报模块找不到,或者地图区域一片空白,只剩一个孤零零的标题。这不是你代码写错了,而是 ECharts 5 之后官方不再随包附带地图 JSON/JS 数据,地图数据被拆成了独立资源。很多人第一反应是去搜一个能直接下载的 china.js 文件,但真正靠谱的做法,是搞清楚这份数据从哪来、什么格式、怎么注册进 ECharts。这篇笔记面向正在做数据大屏、区域统计图、省级下钻的开发者,把「下载」这件事拆成数据来源、格式转换、注册渲染、踩坑排查四段,让你不依赖任何来路不明的文件也能把中国地图跑起来。

2. 先搞清楚 ECharts 要的到底是什么数据

2.1 china.js 的本质是一段 registerMap 调用

很多人以为 china.js 是一个「地图文件」,其实它内部就是一段 JavaScript,核心只有一句echarts.registerMap('china', geoJson)。也就是说,ECharts 真正需要的是符合 GeoJSON 规范的地理边界数据,china.js 只是把这份 GeoJSON 包了一层 JS 壳,方便用<script>直接引入。理解这一点非常关键:你不需要死磕某个特定版本的 china.js,只要能拿到合法的中国 GeoJSON,自己就能生成等价文件。

GeoJSON 的结构长这样:一个FeatureCollection,里面每个Feature代表一个省/自治区/直辖市,properties里带name字段(比如「广东省」「北京市」),geometry里是边界坐标点串。ECharts 渲染时靠properties.name和你的 series data 做匹配,名字对不上,那个区域就是灰的或者不显示。这是后面所有坑的根源。

2.2 为什么老教程的引入方式现在会翻车

ECharts 4 时代,echarts/map/js/china.js确实躺在 npm 包里,import 'echarts/map/js/china'就能用。到了 ECharts 5,官方把地图数据从主包里剥离,理由是地图数据体积大、更新频率和主库不一致、还涉及边界合规问题。于是你按老博客操作,路径不存在,webpack 直接报Module not found。这不是玄学,是版本演进的必然结果。

常见做法有两种:一是从可信的数据源拿到 GeoJSON,用registerMap手动注册;二是用第三方维护的地图数据包。我一般推荐第一种,因为数据来源透明,边界和名字可控,出问题能自己查。第二种虽然省事,但包里的数据版本、名字规范你未必清楚,下钻时容易对不上。

2.3 数据源选择:精度、体积、名字规范三者要权衡

拿到中国 GeoJSON 的渠道不少,但选的时候要盯三个指标。第一是精度,边界点越密地图越精细,但文件也越大,一个全国高精度 GeoJSON 可能好几 MB,大屏项目里会拖慢首屏。第二是名字规范,properties.name必须是「广东省」这种全称还是「广东」这种简称,直接决定你 series data 里 name 怎么写。第三是层级,全国图只到省,要做市级下钻就得另外准备各市的 GeoJSON。

我的经验是:全国总览用中等精度就够,点太密在小屏幕上反而糊成一团;下钻用的市级数据按需加载,别一次性全打进主包。名字规范一定要在拿到数据后先打印出来确认,别凭感觉写。

3. 从 GeoJSON 到可用的 china.js:完整生成流程

3.1 用 Node 脚本把 GeoJSON 转成 registerMap 文件

假设你已经拿到一份china.geojson,下面这个脚本把它转成可以直接<script>引入的 china.js。这是最通用的一步,转换逻辑透明,你随时能改。

// build-china-map.js const fs = require('fs'); // 读取原始 GeoJSON,编码统一用 utf8,避免中文乱码 const geoJson = JSON.parse(fs.readFileSync('./china.geojson', 'utf8')); // 关键校验:确认每个 feature 都有 name,否则地图区域无法匹配 const invalid = geoJson.features.filter(f => !f.properties || !f.properties.name); if (invalid.length > 0) { console.error('存在缺少 name 的 feature,数量:', invalid.length); process.exit(1); } // 打印所有区域名,方便和 series data 对齐 console.log('区域名列表:', geoJson.features.map(f => f.properties.name).join(',')); // 生成 registerMap 调用,挂到全局 echarts 上 const output = `(function (root, factory) { if (typeof define === 'function' && define.amd) { define(['exports', 'echarts'], factory); } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') { factory(exports, require('echarts')); } else { factory({}, root.echarts); } }(this, function (exports, echarts) { if (!echarts) { console.error('未找到 echarts'); return; } echarts.registerMap('china', ${JSON.stringify(geoJson)}); }));`; fs.writeFileSync('./china.js', output, 'utf8'); console.log('china.js 生成完成,大小:', (output.length / 1024).toFixed(1), 'KB');

逻辑说明:脚本先做一次 name 完整性校验,这是防止后面地图「缺块」的第一道防线;然后把 GeoJSON 序列化进一个 UMD 包装里,兼容 script 标签、CommonJS 和 AMD 三种引入方式。参数上,registerMap的第一个参数'china'是地图名,后面series.map或geo.map要写同一个字符串,写错了地图就不显示。输出文件大小直接反映精度,如果超过 2MB,考虑换低精度数据或做简化。

3.2 在页面里注册并渲染第一张中国地图

生成好 china.js 后,引入和渲染的完整代码如下。注意引入顺序,echarts 必须在 china.js 之前加载。

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <!-- 先加载 echarts 主库 --> <script src="./echarts.min.js"></script> <!-- 再加载地图数据,内部会调用 registerMap --> <script src="./china.js"></script> </head> <body> <div id="map" style="width: 900px; height: 600px;"></div> <script> const chart = echarts.init(document.getElementById('map')); // 模拟数据:name 必须和 GeoJSON 里的 properties.name 完全一致 const data = [ { name: '广东省', value: 1200 }, { name: '江苏省', value: 980 }, { name: '北京市', value: 760 }, { name: '四川省', value: 640 } ]; chart.setOption({ tooltip: { trigger: 'item' }, visualMap: { min: 0, max: 1200, left: 20, bottom: 20, text: ['高', '低'], inRange: { color: ['#e0f3f8', '#4575b4'] } }, series: [{ type: 'map', map: 'china', // 必须和 registerMap 的第一个参数一致 roam: true, // 允许缩放和拖拽 label: { show: false }, emphasis: { label: { show: true }, itemStyle: { areaColor: '#ffd700' } }, data: data }] }); </script> </body> </html>

逻辑说明:echarts.init拿到容器后,setOption里series.type设为map,map字段填注册时的名字。visualMap负责把数值映射成颜色深浅,min/max要按你的真实数据范围调,否则颜色全挤在一端。roam: true开启交互,大屏上一般会关掉避免误操作。data 里的 name 只要有一个对不上,那个省就不会着色,这是最常见的「地图缺一块」原因。

3.3 用 npm 包方式在工程化项目里引入

如果是 Vue/React 工程,不想手动维护 china.js,可以用 npm 安装地图数据包,再在入口注册。下面以常见的地图数据包为例,包名以你实际安装的为准。

// main.js 或地图组件内 import * as echarts from 'echarts'; // 引入地图数据包,具体包名按你安装的来 import chinaMap from 'echarts-map-data/china.json'; // 注册地图,名字自定义,后续 series.map 保持一致 echarts.registerMap('china', chinaMap); // 组件内初始化 const chart = echarts.init(dom); chart.setOption({ series: [{ type: 'map', map: 'china', data: regionData }] });

逻辑说明:工程化项目里直接 import JSON 比引入 JS 更干净,打包器会处理成模块。registerMap只需执行一次,放在入口或地图组件的onMounted里都行,但别每次渲染都注册,重复注册同名地图会覆盖,虽然不报错但浪费性能。参数上,map名字自己定,只要注册和引用一致即可。

4. 地图名字对不上、区域缺失怎么排查

4.1 现象:地图能显示但部分省份是灰的

这是最高频的问题。原因几乎都是 series data 里的 name 和 GeoJSON 里的properties.name不一致。比如数据里写「广东」,GeoJSON 里是「广东省」;或者数据里写「内蒙古」,GeoJSON 里是「内蒙古自治区」。解决方法是先把 GeoJSON 的所有 name 打印出来,再逐条比对。

// 在注册地图后,打印所有区域名做核对 const mapData = echarts.getMap('china'); if (mapData) { const names = mapData.geoJson.features.map(f => f.properties.name); console.table(names); }

逻辑说明:echarts.getMap能取回已注册的地图对象,从中读出所有区域名。把这份名单复制出来,和你的数据源做一次 join,对不上的就是问题所在。参数上没什么可调的,关键是养成「先核对名字再写数据」的习惯,能省掉大量返工。

4.2 现象:控制台报 Map china not exists

这个报错说明registerMap没执行,或者执行在setOption之后。常见于异步加载场景:地图数据还在请求中,图表已经初始化了。解决办法是把setOption放到地图注册完成的回调里,或者用Promise串起来。

// 异步加载地图数据后再渲染 async function initMap() { const geoJson = await fetch('/static/china.json').then(r => r.json()); echarts.registerMap('china', geoJson); // 先注册 const chart = echarts.init(dom); chart.setOption({ series: [{ type: 'map', map: 'china' }] }); // 后渲染 } initMap();

逻辑说明:顺序不能反,注册是渲染的前提。用 fetch 动态加载的好处是地图数据不占主包体积,首屏更快。参数上注意 fetch 的路径要对,跨域时后端要配好响应头。

4.3 现象:地图整体变形或被拉伸

地图比例失真通常是容器宽高比和地图数据不匹配,或者aspectScale参数没设对。ECharts 地图默认按容器自适应,如果容器是个很扁的横条,地图就会被压扁。解决方法是给容器一个接近地图原始比例的宽高,或者调整aspectScale。

chart.setOption({ geo: { map: 'china', aspectScale: 0.85, // 默认 0.75,适当调大缓解纵向压缩 layoutCenter: ['50%', '50%'], layoutSize: '100%' } });

逻辑说明:aspectScale控制地图的纵横比,值越大纵向越舒展。layoutCenter和layoutSize配合使用能让地图在容器里居中且不溢出。参数没有万能值,得对着你的容器尺寸微调,一般 0.8 到 0.9 之间比较自然。

5. 避坑清单:五个让我返工过的细节

坑一:name 用了简称,地图缺块。现象是部分省份不着色。原因是数据源和 GeoJSON 的名字规范不统一。解决是统一用全称,或者写一个映射表在渲染前转换。

坑二:重复 registerMap 导致内存上涨。现象是页面切换多次后卡顿。原因是每次进地图组件都注册一遍。解决是把注册逻辑提到入口,或用标志位判断只注册一次。

坑三:高精度 GeoJSON 拖慢首屏。现象是地图加载要好几秒。原因是边界点太密,文件几 MB。解决是总览用简化版数据,下钻再按需加载高精度。

坑四:下钻时市级名字和省级对不上。现象是点击省份后市级地图空白。原因是市级 GeoJSON 的 name 是「深圳市」,而你的数据写「深圳」。解决是下钻前先核对市级数据的名字列表。

坑五:打包后地图数据丢失。现象是本地正常,部署后地图不显示。原因是地图 JSON 没被正确打包或路径写成了绝对路径。解决是把数据放静态目录用相对路径引用,或确认打包配置包含该资源。

6. 进阶:按需加载与省级下钻的实用写法

做到这一步,全国图基本没问题了。但真实项目往往要做「点击省份下钻到市级」,这时候一次性把所有市级数据打进主包就不现实了。我的习惯是按需加载:全国图只加载 china.json,用户点击某个省时,再动态请求该省的 GeoJSON 并注册。

// 点击省份后动态加载对应市级地图 chart.on('click', async (params) => { const province = params.name; // 例如「广东省」 const code = provinceCodeMap[province]; // 省份名到编码的映射 if (!code) return; // 动态请求该省数据,路径按你的静态资源组织 const geoJson = await fetch(`/static/map/${code}.json`).then(r => r.json()); echarts.registerMap(province, geoJson); // 用省名作为地图名注册 chart.setOption({ series: [{ type: 'map', map: province, // 切换到新注册的省地图 data: cityData[province] || [] }] }); });

逻辑说明:chart.on('click')拿到点击的区域名,通过一张映射表转成编码,再去请求对应的市级 GeoJSON。注册时用省名当 map 名,setOption里同步切换。参数上,provinceCodeMap需要你自己维护一份省份到编码的对照,这是下钻能跑通的关键。返回上一级时,重新setOption回map: 'china'即可,不用重新注册全国数据。

这里有个容易忽略的点:下钻后visualMap的min/max还是全国的范围,市级数据值域小,颜色会全挤在浅色端。正确做法是下钻时同步更新visualMap的范围,或者干脆用series级别的itemStyle手动控制。

验证下钻是否正常,我一般会做两件事:一是打印每次注册的地图名,确认没有重复;二是在市级数据里故意留一个对不上的名字,看它是否如预期不着色,以此确认匹配逻辑生效。这套流程跑顺之后,全国到省到市的三级下钻都能用同一套模式套出来,区别只是数据文件和映射表。

最后说个血泪经验:地图数据这东西,来源一定要留档。我吃过一次亏,项目上线半年后要改边界,结果当初从哪拿的数据、什么版本全忘了,只能重新找一份,名字规范一变,所有数据都得跟着改。现在我习惯在项目里放一个map-data/README,记清楚每份数据的来源、精度、名字规范,这比任何后悔药都管用。希望帮到你。

本文还有配套的精品资源,点击获取

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

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

立即咨询