资讯动态

ECharts 5 地图数据获取指南:从 GeoJSON 到 china.js 的完整实践

发布时间:2026/10/13 16:03:50 来源:尧图企业网站定制
简介这份资源提供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 charsetutf-8 / !-- 先加载 echarts 主库 -- script src./echarts.min.js/script !-- 再加载地图数据内部会调用 registerMap -- script src./china.js/script /head body div idmap stylewidth: 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设为mapmap字段填注册时的名字。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记清楚每份数据的来源、精度、名字规范这比任何后悔药都管用。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑