
简介这份资源是面向数据可视化开发者与前端工程师的中国地图 JavaScript 文件集合核心解决在 ECharts 中绘制中国及各省地图时缺少地理数据的问题。压缩包共 35 个 js 文件约 841KB其中 china.js 封装全国地图配置其余文件按省份逐一提供地理信息覆盖北京、上海、广东、新疆、西藏、港澳台等全部省级行政区便于按需引入、精准渲染。已有 5705 人学习下载说明其在 ECharts 地图开发场景中具有较高参考价值。使用时只需引入对应 js 文件在 ECharts 实例中设置地图类型为 china 或具体省份即可配置颜色、标注、交互行为并支持动态数据更新与动画效果。对于需要展示区域数据分布、实现点击下钻或按省份分组统计的项目这套文件能省去自行整理地理数据的成本快速搭建可交互的中国地图可视化页面。1. china.js 地图数据包ECharts 中国地图渲染绕不开的那块拼图如果你用 ECharts 做过中国地图大概率遇到过这个场景代码写完了echarts.init也跑了控制台却冷冷地抛出一句Map china not exists。不是配置写错了也不是版本装歪了而是 ECharts 从某个版本开始把内置地图数据拆了出去——中国地图和各省地图的 GeoJSON 不再随主包一起发布。你得自己找到对应的china.js或各省 js 文件手动注册进去地图才能渲染出来。这份「china.js 中国及各地 js 文件压缩包」解决的就是这个问题。它把中国全国地图以及各省、自治区、直辖市的 js 格式地图数据打包在一起直接script引入或import后调用echarts.registerMap就能用。适合正在做数据大屏、区域热力图、省份下钻分析的前端和数据分析从业者。不需要你去 GeoJSON 仓库里一个个翻文件、转格式、对坐标省掉的是最枯燥的那段准备工作。2. 地图数据怎么选、怎么注册从文件结构到第一张图2.1 先搞清楚压缩包里有什么拿到压缩包后别急着往项目里塞先解压看一眼目录结构。常见做法是根目录下有一个china.js然后按省份分文件夹或平铺一堆beijing.js、guangdong.js、zhejiang.js这样的文件。每个 js 文件的本质是一段可执行脚本内部把一份 GeoJSON 对象赋给某个变量或者直接调用echarts.registerMap(省份名, geoJson)。这里有个选型判断如果你只需要全国地图那china.js一个文件就够了如果要做「点击省份下钻到市级」的交互就得把目标省份的 js 也引进来。我一般会先确认两件事——文件里的地图名称字符串是什么比如是china还是中国以及坐标参考系是不是标准 WGS84 或 GCJ02。名称对不上registerMap注册了也白搭。注意不同来源的 china.js 内部注册名称不统一有的用中文「中国」有的用英文china注册前先打开文件搜一下registerMap的参数。2.2 在原生页面里引入并注册最直接的用法是在 HTML 里用script标签引入。假设你把china.js放在了libs/目录下!-- 先引入 ECharts 主包 -- script srchttps://cdn.example.com/echarts.min.js/script !-- 再引入地图数据文件顺序不能反 -- script srclibs/china.js/script script // 初始化图表实例容器需要提前给好宽高 var chart echarts.init(document.getElementById(map-container)); // 如果 china.js 内部没有自动注册需要手动注册一次 // 参数一为地图名称必须和 series.map 里的值一致 echarts.registerMap(china, chinaGeoJson); var option { series: [{ type: map, map: china, // 与 registerMap 的名称严格对应 roam: true, // 允许缩放和拖拽 label: { show: true }, data: [ { name: 广东, value: 1200 }, { name: 浙江, value: 980 } ] }] }; chart.setOption(option); /script这段代码的逻辑链条是ECharts 主包提供渲染引擎china.js提供地理边界数据registerMap把两者桥接起来。关键参数有三个——map的值必须和注册名称一字不差roam控制是否允许用户交互缩放data里的name必须和 GeoJSON 里的地区属性名匹配否则那个省份就是灰的数据挂不上去。2.3 在模块化项目里按需引入现在大部分项目走的是 webpack 或 Vite用import更自然。但要注意这类地图 js 文件通常不是标准 ES Module可能没有export。常见做法是把它当作副作用脚本引入或者用构建工具的raw-loader把内容读成字符串再eval。import * as echarts from echarts; // 方式一如果文件内部有 registerMap 调用直接引入即生效 import ./maps/china.js; // 方式二如果文件只暴露了一个全局变量手动注册 // import chinaJson from ./maps/china.json; // 若同时有 json 版本 // echarts.registerMap(china, chinaJson); const chart echarts.init(document.getElementById(map)); chart.setOption({ tooltip: { trigger: item }, visualMap: { min: 0, max: 2000, inRange: { color: [#e0f3f8, #4575b4] } // 颜色梯度 }, series: [{ type: map, map: china, data: [] // 后续通过 setOption 动态填充 }] });模块化引入的坑在于构建工具的处理策略。有的打包器会把china.js当成普通模块 tree-shaking 掉因为它没有导出任何东西。解决办法是在package.json的sideEffects字段里声明该文件有副作用或者改用require方式引入。参数上visualMap的min/max要按你的实际数据范围调设得太窄会导致所有省份颜色挤在一起看不出差异。2.4 省份下钻的基本实现思路全国地图只是起点真正的大屏需求往往是点某个省就切到该省的地图。实现逻辑不复杂监听click事件拿到省份名去压缩包里找对应的 js 文件注册后更新series.map。chart.on(click, function (params) { // params.name 是点击的省份名如「广东」 var provinceName params.name; // 假设压缩包内文件名与省份拼音对应需提前建立映射表 var fileMap { 广东: guangdong, 浙江: zhejiang }; var fileName fileMap[provinceName]; if (!fileName) return; // 动态加载对应省份的地图数据 import(./maps/ fileName .js).then(function () { echarts.registerMap(provinceName, window[fileName GeoJson]); chart.setOption({ series: [{ type: map, map: provinceName, data: [] }] }); }); });这段代码的核心是「按需加载 重新注册」。参数fileMap是省份中文名到文件名的映射因为压缩包里的文件名通常是拼音而 ECharts 事件返回的是中文名中间必须做一次转换。实际项目中这个映射表可能很长建议单独抽成一个配置文件维护。3. 数据绑定与视觉映射让地图真正「说话」3.1 地区名称匹配是数据绑定的命门地图渲染出来只是第一步把业务数据正确挂到每个省份上才是关键。ECharts 的匹配规则是拿series.data[].name去和 GeoJSON 里properties.name做全等比较。问题在于不同来源的 GeoJSON 对同一地区的命名可能不同——「内蒙古」和「内蒙古自治区」、「北京」和「北京市」、「新疆」和「新疆维吾尔自治区」差一个字就匹配不上。我一般会先打印一份 GeoJSON 里的名称列表然后拿业务数据的地区字段去比对找出差异项做映射修正。// 假设已注册地图先取出所有地区名称 var geoJson echarts.getMap(china).geoJson; var regionNames geoJson.features.map(function (f) { return f.properties.name; }); console.log(regionNames); // 打印出来核对命名规范 // 建立业务数据名称到地图名称的修正映射 var nameFix { 内蒙古自治区: 内蒙古, 广西壮族自治区: 广西, 新疆维吾尔自治区: 新疆, 北京市: 北京 }; // 对业务数据做一次预处理 var rawData [ { region: 内蒙古自治区, value: 320 }, { region: 北京市, value: 1500 } ]; var fixedData rawData.map(function (item) { return { name: nameFix[item.region] || item.region, value: item.value }; });这段预处理逻辑看起来笨但能省掉后面大量「为什么这个省没颜色」的排查时间。参数nameFix需要根据你实际拿到的 GeoJSON 命名来维护没有万能表。3.2 visualMap 的分段与连续模式怎么选visualMap决定了数据到颜色的映射方式分连续型和分段型两种。连续型适合展示趋势和梯度分段型适合做等级划分如高/中/低。// 连续型颜色随数值平滑过渡 visualMap: { type: continuous, min: 0, max: 2000, calculable: true, // 显示拖拽手柄 inRange: { color: [#e8f4f8, #b3d9e8, #6baed6, #2171b5, #08306b] }, text: [高, 低], // 两端文字 left: 20, bottom: 20 } // 分段型按区间给颜色适合等级数据 visualMap: { type: piecewise, pieces: [ { min: 1000, label: 高 }, { min: 500, max: 999, label: 中 }, { min: 0, max: 499, label: 低 } ], inRange: { color: [#fee0d2, #fc9272, #de2d26] } }选哪种取决于你的数据语义。如果是 GDP、人口这类连续量用连续型如果是风险等级、预警级别这类离散分类用分段型更直观。参数calculable只在连续型下有效开启后用户能手动拖拽筛选范围做交互大屏时比较实用。3.3 自定义 tooltip 和标签格式默认的 tooltip 只显示名称和数值信息密度太低。实际项目里通常要加单位、百分比、排名等。tooltip: { trigger: item, formatter: function (params) { // params.value 可能是 undefined该地区无数据 var val params.value ? params.value : 暂无数据; return params.name br/ 数值 val 万元br/ 占比 (params.percent || 0) %; } }formatter支持字符串模板和回调函数两种形式。回调函数更灵活但要注意params.value在无数据地区可能是NaN或undefined不做判空会显示成undefined大屏上很难看。4. 避坑与排查地图渲染中最容易翻车的五个地方4.1 地图一片空白控制台报 Map not exists现象图表容器有大小代码没报错但地图区域是空的控制台提示Map china not exists。原因ECharts 主包不再内置地图数据china.js没有引入或引入顺序不对也可能是registerMap的名称和series.map不一致。解决先确认china.js在网络面板里加载成功状态码 200再检查registerMap的第一个参数和series.map的值是否完全一致。如果用的是模块化引入确认构建工具没有把文件 tree-shaking 掉。4.2 省份有轮廓但没颜色数据挂不上去现象地图能显示但所有省份都是默认灰色data里的数值没有体现。原因九成是名称不匹配。data[].name和 GeoJSON 里的properties.name不一致ECharts 找不到对应地区就跳过。解决用echarts.getMap(china).geoJson.features打印所有地区名称和业务数据逐一比对建立修正映射。特别注意「省」「市」「自治区」后缀的差异。4.3 缩放拖拽后地图跑偏或变形现象开启roam: true后用户拖拽或缩放地图位置偏移或者省份形状被拉长。原因通常是容器的宽高比和地图数据的投影比例不匹配。ECharts 默认使用等距圆柱投影如果容器是极端宽扁或窄高的地图会变形。解决给容器设置合理的宽高比常见 4:3 或 16:9或者在series里配置aspectScale参数微调。另外检查layoutCenter和layoutSize是否被误设。4.4 省份下钻后返回全国数据丢失现象点击省份进入下级地图再点返回按钮回到全国地图之前的数据和颜色全没了。原因每次setOption时没有保留之前的配置或者registerMap重复注册导致状态混乱。解决把全国和各省的 option 分别缓存起来切换时用setOption(option, true)的第二个参数控制是否合并。重复注册同名地图前先判断是否已注册。4.5 打包后文件体积暴涨现象开发环境正常构建产物比预期大了好几 MB。原因把全部省份的 js 文件一次性引入了每个文件少则几十 KB多则上百 KB三十多个省份加起来很可观。解决只引入当前需要的省份文件下钻时用动态import()按需加载。如果构建工具支持代码分割确认地图文件被拆成了独立 chunk。5. 进阶技巧用 GeoJSON 做自定义区域与性能优化5.1 从压缩包提取 GeoJSON 做二次加工压缩包里的 js 文件本质是包裹了 GeoJSON 的脚本。如果你想对边界做简化、合并区域或者转成其他格式可以先把 GeoJSON 抽出来。// 在浏览器控制台或 Node 环境中执行 // 假设 china.js 已经把数据挂到了全局变量 var geoJson window.chinaGeoJson; // 变量名以实际文件为准 // 提取所有省份名称和中心点坐标 var features geoJson.features; var centroids features.map(function (f) { return { name: f.properties.name, center: f.properties.cp || f.properties.center // 不同数据源字段名不同 }; }); console.log(JSON.stringify(centroids, null, 2)); // 如果需要简化边界减少坐标点可以引入 simplify-js 之类的库 // 这里只做结构说明不展开具体算法拿到 GeoJSON 后你可以做很多压缩包里没直接提供的事——比如把几个相邻省份合并成一个经济区、给边界加缓冲区、或者转成 TopoJSON 减小体积。参数cp或center是省份中心点坐标做散点图叠加时经常用到。5.2 大数据量下的渲染性能调优当data有几千条、或者要做实时刷新时地图渲染可能变卡。几个实用的优化方向优化项做法效果关闭标签label.show: false减少文本渲染开销降低边界精度用简化后的 GeoJSON减少顶点计算量关闭动画animation: false避免频繁重绘使用 canvas 渲染默认即是无需改比 SVG 更适合大数据节流 setOption用setOption合并更新减少重渲染次数我一般会在数据量超过 500 条时关掉label超过 2000 条时考虑用large: true模式。这些参数不是万能的得根据实际帧率表现来调。5.3 一个我踩过的坑地图名称里的隐藏字符有次从某数据源导出的地区名称里混入了不可见的零宽空格肉眼看着是「广东」实际字符串长度是 3 而不是 2。结果就是数据死活挂不上去排查了两个小时。从那以后我每次做地图数据绑定前都强制走一遍trim()和字符编码检查确认没有隐藏字符再往下走。// 清洗地区名称的常规操作 function cleanName(name) { return name .replace(/[\u200b-\u200d\ufeff]/g, ) // 去除零宽字符 .replace(/\s/g, ) // 去除所有空白 .trim(); }这个函数不长但能挡掉大部分「看起来一样但匹配不上」的玄学问题。希望帮到你。本文还有配套的精品资源点击获取