
简介这份资源提供ECharts地图功能所需的核心文件china.js面向使用ECharts进行Web数据可视化的前端开发者与数据分析人员解决新版ECharts因版权原因不再内置中国地图数据、导致无法直接渲染中国地图的问题。压缩包为rar格式内含1个js文件体积约43KB即包含中国各省份及地区经纬度坐标与边界信息的地理数据文件引入后即可配合ECharts实例的geo与series配置展示中国地图。资源描述中梳理了下载、引入、配置地图实例、加载区域数据、调整样式与交互等完整思路并提醒注意地图数据的版权合规使用对需要快速补齐地图能力的项目有直接参考价值。目前已有3243人学习下载适合希望在新版ECharts中继续使用中国地图的开发者参考取用。1. echarts地图china.js下载一个被低估的离线地图方案做数据大屏的同行大概率都遇到过这个场景内网环境部署可视化项目地图组件加载到一半卡住控制台报 404原因就是 echarts 默认的地图数据依赖在线 CDN。这时候china.js这个文件就成了救命稻草——它是把中国地图的 GeoJSON 数据注册进 echarts 的一个脚本文件引入后echarts.registerMap(china, ...)就能在完全离线的环境下渲染地图。很多人第一次搜「echarts地图china.js下载」其实真正想要的不是文件本身而是搞清楚这个文件从哪来、怎么用、为什么官网找不到了。这篇笔记就按这个思路把下载、注册、配置、排错整条链路讲透适合正在做内网大屏、需要地图下钻、又不想依赖外部接口的前端和数据工程师。2. china.js 到底是什么从 GeoJSON 到 registerMap 的完整链路2.1 为什么 echarts 5 之后不再内置地图数据echarts 在 4.x 时代echarts/map/js/china.js是随包发布的直接import echarts/map/js/china就能用。但从 5.0 开始官方把地图数据从主包里剥离了原因有两个一是地图数据的版权和合规问题需要单独处理二是主包体积太大地图数据对很多项目来说是冗余的。这个变化导致大量老教程失效新手照着 4.x 的写法在 5.x 上跑必然报Map china not exists。常见做法是去 echarts 官方示例仓库或者一些镜像站找china.js但版本参差不齐有的还是 2018 年的老数据省份边界和现在对不上。我一般会先确认自己需要的是「全国地图」还是「省市下钻」前者一个china.js就够后者需要一整套省市 JSON。2.2 GeoJSON、registerMap 和 series-map 三者的关系理解这条链路后面所有配置都不会迷路GeoJSON一种描述地理边界的 JSON 格式包含features数组每个 feature 有properties.name省份名和geometry.coordinates边界坐标。registerMapecharts 提供的注册接口echarts.registerMap(china, geoJson)第一个参数是地图名第二个是 GeoJSON 对象。注册后这个地图名就能在series-map或geo组件里引用。series-map真正渲染地图的系列类型type: map通过map: china关联已注册的地图。china.js的本质就是一段执行了registerMap的脚本它内部把 GeoJSON 数据和一个自执行函数打包在一起。所以你也可以不用china.js直接下载china.json自己调registerMap效果完全一样而且更灵活。2.3 三种获取方式对比npm 包、JSON 文件、自建脚本方式来源优点缺点适用场景npm 包某些第三方 map 数据包安装方便版本可锁包质量参差可能停维护快速原型纯 JSON 文件公开 GeoJSON 数据源数据透明可裁剪需自己写注册逻辑生产项目自建 china.js用 JSON 转脚本一次引入全局可用需构建步骤多页面复用我一般推荐生产项目用第二种把china.json放在public或assets目录在入口文件里注册一次。这样数据来源清晰后续要换数据或裁剪省份也方便。下面给出具体操作。2.4 用 Node 脚本把 GeoJSON 转成可引入的 china.js假设你已经拿到了china.json想把它转成china.js可以写一个简单的构建脚本// build-china-map.js const fs require(fs); const path require(path); // 读取原始 GeoJSON 数据 const geoJson JSON.parse( fs.readFileSync(path.resolve(__dirname, china.json), utf-8) ); // 生成注册脚本UMD 风格兼容 script 标签和模块引入 const content (function (root, factory) { if (typeof define function define.amd) { define([echarts], factory); } else if (typeof exports object) { factory(require(echarts)); } else { factory(root.echarts); } }(this, function (echarts) { var geoJson ${JSON.stringify(geoJson)}; echarts.registerMap(china, geoJson); }));; fs.writeFileSync(path.resolve(__dirname, china.js), content, utf-8); console.log(china.js 生成完成大小, (content.length / 1024).toFixed(1), KB);这段脚本的逻辑很直白读 JSON把 JSON 字符串塞进一个 UMD 包装里调用registerMap。参数说明JSON.stringify(geoJson)会把对象序列化成字符串注意如果 GeoJSON 里有undefined会被丢掉但标准 GeoJSON 不会有这个问题。生成后的china.js可以直接用script引入也可以在 webpack/vite 项目里import ./china.js。提示如果 GeoJSON 文件超过 2MB建议做精度简化否则打包体积会很难看。常见做法是用 mapshaper 这类工具先压缩边界点。3. 在项目里跑通地图从注册到渲染的最小可复现步骤3.1 本地引入 china.js 并注册地图最直接的方式在 HTML 里先引 echarts再引china.js!DOCTYPE html html head meta charsetutf-8 title离线地图示例/title !-- 引入 echarts本地文件或 CDN 均可 -- script src./echarts.min.js/script !-- 引入生成的 china.js内部会自动 registerMap -- script src./china.js/script /head body div idmap stylewidth: 800px; height: 600px;/div script // 初始化实例注意这里不需要再手动 registerMap var chart echarts.init(document.getElementById(map)); var option { series: [{ type: map, map: china, // 对应 registerMap 的第一个参数 roam: true, // 允许缩放和拖拽 label: { show: true, fontSize: 10 }, emphasis: { label: { show: true } } }] }; chart.setOption(option); /script /body /html逻辑说明china.js在加载时已经执行了registerMap(china, geoJson)所以option里直接写map: china即可。参数说明roam: true开启鼠标缩放和平移大屏场景建议开启label.show控制省份名称显示数据量大时可以关掉提升性能。3.2 在 Vue/React 项目里按需注册现代前端项目一般不会用 script 标签而是模块化引入。以 Vue 为例// main.js 或单独的 map-setup.js import * as echarts from echarts; import chinaGeoJson from ./assets/china.json; // 注册地图只执行一次 echarts.registerMap(china, chinaGeoJson); // 组件内使用 export default { mounted() { const chart echarts.init(this.$refs.mapEl); chart.setOption({ tooltip: { trigger: item }, visualMap: { min: 0, max: 1000, left: 20, bottom: 20, text: [高, 低], calculable: true, inRange: { color: [#e0f3f8, #4575b4] } }, series: [{ type: map, map: china, data: [ { name: 广东, value: 800 }, { name: 浙江, value: 600 } ] }] }); } };这里的关键是registerMap只执行一次放在入口文件或单独的初始化模块里。参数说明visualMap的inRange.color控制数据映射的颜色区间min/max要和你的数据范围匹配否则颜色会失真。3.3 数据绑定series-map 的 data 格式与名称匹配规则地图渲染最常见的翻车点就是数据不显示十有八九是name对不上。series-map的data格式是[{ name: 省份名, value: 数值 }]其中name必须和 GeoJSON 里properties.name完全一致。// 正确写法 data: [ { name: 北京, value: 120 }, { name: 内蒙古, value: 45 } ] // 错误写法用了简称或全称不一致 data: [ { name: 北京市, value: 120 }, // GeoJSON 里可能是「北京」 { name: 内蒙, value: 45 } // 简称对不上 ]排查方法在控制台打印echarts.getMap(china).geoJson.features.map(f f.properties.name)看看实际有哪些名称然后对齐。这个坑我踩过不止一次尤其是「新疆」「西藏」「内蒙古」这些名称不同数据源写法不一样。3.4 用 geo 组件做省市下钻的注册流程下钻的本质是点击省份后注册该省的地图并切换map值chart.on(click, function (params) { if (params.componentType series params.seriesType map) { const provinceName params.name; // 假设省市 JSON 已按名称存放在 mapData 对象里 const provinceJson mapData[provinceName]; if (provinceJson) { echarts.registerMap(provinceName, provinceJson); chart.setOption({ series: [{ type: map, map: provinceName, data: provinceData[provinceName] || [] }] }); } } });逻辑说明点击事件拿到省份名从预加载的mapData里取对应 GeoJSON注册后重新setOption。参数说明mapData建议按需加载不要一次性把所有省份 JSON 都打进主包否则首屏体积会爆炸。常见做法是动态import()或放在public目录用 fetch 拉取。4. 避坑指南china.js 下载和使用中的 5 个高频问题4.1 报错 Map china not exists注册时机和顺序问题现象控制台报Map china not exists地图区域空白。原因registerMap没有执行或者执行在setOption之后。模块化项目里如果china.js是异步加载的很容易出现时序问题。解决确保registerMap在setOption之前完成。可以在入口文件同步引入或者在异步加载后用await等待注册完成再初始化图表。检查方式在setOption前打印echarts.getMap(china)如果是undefined就是没注册成功。4.2 地图边界错位或省份缺失数据版本太老现象某些省份边界明显不对或者少了几个省。原因下载到的china.js是多年前的老数据行政区划调整后没有更新。解决换用较新的 GeoJSON 数据源重新生成china.js。判断数据新旧可以看 feature 数量全国地图一般在 34 个左右。如果只有 30 个出头大概率是旧版。4.3 打包体积暴涨GeoJSON 精度过高现象引入china.js后打包体积增加好几 MB首屏加载变慢。原因原始 GeoJSON 的坐标点非常密集精度越高体积越大。解决用 mapshaper 做简化命令示例# 安装 mapshaper 后执行保留 10% 的坐标点 mapshaper china.json -simplify 10% -o formatgeojson china-simple.json参数说明-simplify 10%表示保留 10% 的顶点视觉上几乎看不出差别但体积能降一个数量级。生产环境建议简化到 5%15% 之间根据大屏分辨率调整。4.4 名称匹配失败数据里的 name 和地图对不上现象data里明明有值地图上就是不上色。原因name字段和 GeoJSON 的properties.name不一致常见于简称/全称、空格、特殊字符。解决统一用 GeoJSON 里的名称作为基准在数据侧做映射。可以写一个映射表const nameMap { 北京市: 北京, 内蒙古自治区: 内蒙古, 广西壮族自治区: 广西 }; // 转换数据 const normalized rawData.map(item ({ name: nameMap[item.name] || item.name, value: item.value }));4.5 内网部署时字体和 tooltip 异常现象内网环境下地图能显示但 tooltip 里的中文变成方块或者样式丢失。原因echarts 默认 tooltip 用的是浏览器字体内网机器如果缺少中文字体就会显示异常另外某些 CDN 上的主题文件在内网加载不到。解决在 CSS 里显式指定中文字体栈font-family: Microsoft YaHei, PingFang SC, sans-serif;。主题文件下载到本地引入不要依赖在线地址。这个坑在内网大屏项目里非常典型提前处理能省很多调试时间。5. 进阶技巧让离线地图更接近生产可用5.1 用 geoJSON 裁剪只保留业务需要的省份很多业务只需要展示几个省没必要加载全国数据。可以用脚本过滤 featuresconst fs require(fs); const geoJson JSON.parse(fs.readFileSync(china.json, utf-8)); const keep [广东, 浙江, 江苏, 上海]; // 过滤 features只保留目标省份 geoJson.features geoJson.features.filter(f keep.includes(f.properties.name) ); fs.writeFileSync(china-part.json, JSON.stringify(geoJson)); console.log(裁剪后 feature 数量, geoJson.features.length);逻辑说明filter按properties.name筛选保留目标省份。参数说明keep数组里的名称必须和 GeoJSON 一致。裁剪后体积能降到原来的几分之一对首屏性能帮助明显。5.2 地图与散点图、飞线的组合配置纯地图往往不够生产大屏通常要叠加散点和飞线option { geo: { map: china, roam: true, itemStyle: { areaColor: #0b1c3a, borderColor: #1e90ff } }, series: [ { type: effectScatter, // 带涟漪效果的散点 coordinateSystem: geo, data: [ { name: 广州, value: [113.27, 23.13, 100] } ], symbolSize: 10 }, { type: lines, // 飞线 coordinateSystem: geo, data: [ { coords: [[113.27, 23.13], [121.47, 31.23]] } ], lineStyle: { color: #ffcc00, width: 1, curveness: 0.2 } } ] };参数说明coordinateSystem: geo表示系列使用 geo 组件的坐标系所以地图由geo渲染而不是series-map。curveness控制飞线弯曲程度0 是直线0.2 左右比较自然。注意geo和series-map不要同时用否则会渲染两层地图。5.3 验证地图数据是否正确的三个检查点上线前我一般会做三个检查第一打印 feature 数量全国地图应该在 34 个左右第二随机抽三个省份用echarts.getMap(china).geoJson确认边界坐标存在第三把data里所有name和 GeoJSON 名称做一次交集比对确保没有对不上的。这三个检查能拦住 90% 的地图显示问题。5.4 一个我踩过的坑registerMap 重复注册导致内存泄漏最后说一个血泪经验。早期做多页面应用时我在每个页面都引入了china.js结果registerMap被重复执行地图数据在内存里存了多份页面切换几次后内存明显上涨。后来改成在入口文件注册一次其他页面只引用地图名问题就消失了。如果你用的是 SPA这个问题不明显但如果是多页应用或者微前端一定要把注册逻辑收敛到一处。这个习惯我保持到现在每次做地图项目第一件事就是确认registerMap的调用位置。希望帮到你。本文还有配套的精品资源点击获取