news 2026/11/4 23:21:07

ECharts中国地图china.js资源:直接引入与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ECharts中国地图china.js资源:直接引入与避坑指南

简介:这份资源提供ECharts地图功能所需的核心文件china.js,面向使用ECharts进行Web数据可视化的前端开发者与数据分析人员,解决新版ECharts因版权原因不再内置中国地图数据、导致地图图表无法直接渲染的问题。压缩包为rar格式,内含1个js文件,体积约43KB,即包含中国各省份及地区经纬度坐标与边界信息的地理数据文件,引入后即可配合geo组件与map属性绘制中国地图。资源描述中同步梳理了下载引入、实例配置、数据加载、样式与交互调整等关键环节,并提示地图数据使用需符合版权规定,便于读者快速定位问题、完成地图可视化开发。目前已有3243人学习下载,适合需要在新版ECharts中实现中国地图展示、按省份关联数据并支持缩放平移等交互效果的开发者参考使用。

1. 别在 npm 里翻 china.js 了:一份能直接跑起来的 ECharts 地图资源

上周帮一个做数据看板的朋友排查问题,页面里中国地图死活渲染不出来,控制台报Map china not exists。他第一反应是去 npm 搜echarts-map-china,装了三四个包,要么版本对不上,要么里面塞的是压缩过的旧版 geoJSON,边界数据还是 2019 年的老轮廓。折腾一晚上没搞定,最后发现真正缺的只是一个china.js文件——ECharts 从 4.x 开始就把地图数据从主包里拆出去了,官方示例里那个echarts/map/js/china.js早就不在主包内。这份资源就是解决这个问题的:一份可直接引入的 ECharts 中国地图数据文件,配合registerMap或全局echarts.maps使用,覆盖省级行政区划边界,适合做数据大屏、区域热力图、迁徙流向图的从业者。新手能照着下面的步骤十分钟跑通,熟手可以关注后面坐标系和边界精度的取舍。

2. 先搞懂 china.js 到底装了什么:geoJSON、投影与注册机制

2.1 它不是一个普通 JS 库,而是地图数据的载体

很多人把china.js当成一个功能库来理解,这是第一个认知偏差。它本质上是把一份 geoJSON 格式的地理边界数据,包装成一段可执行脚本,通过echarts.registerMap('china', geoJson)把地图注册进 ECharts 的全局地图池。你打开文件会看到类似这样的结构:

(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) { var log = function (msg) { if (typeof console !== 'undefined') console.error(msg); }; if (!echarts) { log('ECharts is not Loaded'); return; } // 核心:把 geoJSON 注册为名为 china 的地图 echarts.registerMap('china', { "type": "FeatureCollection", "features": [ /* ... */ ] }); }));

这段 UMD 包装做了三件事:判断运行环境(AMD / CommonJS / 浏览器全局)、检查 ECharts 是否已加载、调用registerMap完成注册。注册名china就是你后面在series.map或geo.map里要填的字符串。理解这一点很关键——如果你注册时写的是china,配置里写China,一样会报Map China not exists,大小写敏感这个坑我见过不止一次。

2.2 geoJSON 里的 coordinates 和 ECharts 坐标系的关系

china.js里的features数组,每个元素是一个省级行政区,geometry.coordinates存的是经纬度点串。ECharts 拿到这些经纬度后,默认用一套内置的墨卡托近似投影把它映射到画布坐标。你不需要手动做投影转换,但要知道两个参数会影响最终观感:geo.center和geo.zoom。默认情况下 ECharts 会根据地图数据的 bounding box 自动适配,但南海诸岛那块如果数据里带了九段线,自动适配会把主图压得很小。常见做法是手动指定:

geo: { map: 'china', center: [104.5, 35.5], // 大致把主图居中 zoom: 1.2, // 放大一点,避免边缘留白过多 roam: true // 允许鼠标缩放拖拽 }

center的经纬度不是随便填的,它对应的是你希望出现在画布中心的地理位置。zoom大于 1 放大,小于 1 缩小。这两个参数配合layoutCenter和layoutSize用效果更稳,后者用百分比控制地图在容器里的占比,比纯 zoom 更好预测。

2.3 为什么不用 npm 上的地图包

npm 上确实有一些第三方打包的地图数据包,但普遍存在三个问题:一是更新滞后,行政区划调整后边界没跟上;二是包体积不可控,有的把全国县级数据都塞进去,一个文件十几兆;三是注册名不统一,有的注册成china,有的注册成中国,换一个包就得改配置。直接拿一份china.js放项目里,版本可控、体积可控、注册名可控,这是我在多个看板项目里最终选择的方案。代价是需要自己管理文件更新,但对于大多数只用到省级边界的场景,一份稳定的文件用一两年没问题。

3. 三种引入方式实测:script 标签、模块化 import 与按需注册

3.1 浏览器 script 标签直接引入

这是最省事的方式,适合传统多页应用或者快速验证。把china.js和echarts.min.js放在同一目录,按顺序引入:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>地图验证</title> <!-- 先引入 ECharts 主包 --> <script src="./echarts.min.js"></script> <!-- 再引入地图数据,顺序不能反 --> <script src="./china.js"></script> </head> <body> <div id="map" style="width: 800px; height: 600px;"></div> <script> var chart = echarts.init(document.getElementById('map')); chart.setOption({ series: [{ type: 'map', map: 'china', // 必须和 registerMap 的注册名一致 label: { show: true }, emphasis: { label: { show: true } } }] }); </script> </body> </html>

顺序是硬约束:china.js内部会检查echarts是否存在,如果 ECharts 还没加载,它会打印ECharts is not Loaded然后直接 return,地图注册失败。我见过有人把两个 script 写反,页面白屏查了半天。另外chart.setOption里series.type用map时,map字段的值就是注册名,这里写china。

3.2 模块化项目里用 import 引入

Vue、React 项目里通常用构建工具,china.js这种 UMD 文件可以直接 import,但要注意它依赖echarts作为外部模块。以 Vue 为例:

import * as echarts from 'echarts'; // 关键:import 进来会执行文件内的注册逻辑 import './assets/map/china.js'; 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 }, series: [{ type: 'map', map: 'china', data: [ { name: '广东', value: 800 }, { name: '江苏', value: 620 } ] }] }); } };

这里有个容易翻车的点:import './assets/map/china.js'必须放在import * as echarts from 'echarts'之后,因为 UMD 包装在 CommonJS 分支里会require('echarts'),如果构建工具把它解析成独立模块,可能拿到的是另一个 echarts 实例,导致注册到了错误的实例上。稳妥做法是在入口文件里统一注册一次,业务组件里只 import echarts 和地图数据文件,不要重复注册。

3.3 手动 registerMap 的按需方案

如果你不想引入整个china.js文件,而是想从 geoJSON 原始数据按需注册,可以这样写:

import * as echarts from 'echarts'; import chinaGeoJson from './china.geo.json'; // 纯 geoJSON 数据 // 手动注册,注册名自己定 echarts.registerMap('china-custom', chinaGeoJson); // 使用时 chart.setOption({ geo: { map: 'china-custom' }, series: [{ type: 'map', map: 'china-custom' }] });

这种方式的好处是注册名完全自定义,多个地图可以共存不冲突;坏处是你得自己准备一份干净的 geoJSON,而china.js里已经帮你包装好了。我一般做多地图切换的看板时用这种,比如同时要显示全国和某个省,注册成china和guangdong两个名字,切换时改map字段即可。

提示:无论哪种方式,注册名一旦确定,配置里所有引用它的地方都要保持一致,包括geo.map、series.map、visualMap关联的seriesIndex等。

4. 避坑排查:地图不显示、边界错位、性能卡顿的五个真实案例

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

原因通常有三种:地图文件没引入、引入顺序在 ECharts 之前、注册名大小写不一致。排查时先在控制台执行echarts.getMap('china'),如果返回 undefined 说明没注册成功。解决方法是检查 script 顺序,确认china.js在echarts.min.js之后加载;模块化项目里确认 import 语句执行了。还有一种隐蔽情况:构建工具把china.js当成了纯数据模块 tree-shaking 掉了,因为它的导出是空的。解决办法是在文件里加一行export default {}或者用import './china.js'这种副作用引入方式,确保它被执行。

4.2 现象:地图出来了但位置偏到画布角落

原因是geo.center或layoutCenter设置不当,或者容器宽高比和地图 bounding box 不匹配。ECharts 默认按容器尺寸等比缩放,如果容器是宽扁的,地图会缩得很小。解决方法是给容器设置合理的宽高比,或者用layoutCenter: ['50%', '50%']配合layoutSize: '80%'让地图在容器内居中占 80%。我一般还会加aspectScale: 0.75微调,这个参数控制经纬度到画布的纵横比,默认 0.75 对大多数中国地图观感合适,改成 1 会显得纵向拉伸。

4.3 现象:省份名称对不上,数据映射不上色

china.js里每个 feature 的properties.name是省份名,比如广东、内蒙古、新疆。你的数据里如果写的是广东省或者内蒙古自治区,就对不上,地图上那块不会着色。解决方法是统一用简称,或者在series.data里做一次名称映射:

const nameMap = { '广东省': '广东', '内蒙古自治区': '内蒙古', '新疆维吾尔自治区': '新疆' }; const seriesData = rawData.map(item => ({ name: nameMap[item.name] || item.name, value: item.value }));

这个坑在做省市级联动时特别常见,市级数据里的名称往往带「市」字,而地图数据里不带。

4.4 现象:地图渲染出来但鼠标悬浮无反应

检查series.type是不是写成了map之外的类型,或者geo和series同时配置了导致事件被 geo 层拦截。如果用了geo组件又用了series.map,两者会叠加渲染,鼠标事件可能落在 geo 上。解决方法是二选一:要么只用series.map,要么只用geo配合series的coordinateSystem: 'geo'。另外emphasis里如果没开label.show,悬浮时也不会有视觉反馈,看起来像没反应。

4.5 现象:数据量大时地图拖拽卡顿

china.js本身只有省级边界,数据量不大,卡顿通常来自series.data里塞了几千个散点或者迁徙线。解决方法是开启progressive渐进渲染:

series: [{ type: 'map', map: 'china', progressive: 200, // 每帧渲染 200 个 progressiveThreshold: 1000 // 超过 1000 个才启用渐进 }]

另外roam: true时每次拖拽都会重绘,如果不需要缩放可以关掉,用roam: 'scale'只允许缩放不允许平移,减少重绘开销。

5. 进阶技巧:用 visualMap 做分级着色与南海诸岛的正确处理

5.1 分级着色让数据差异一眼可见

默认的visualMap是连续渐变,做区域对比时不如分段着色直观。用pieces把数值切成几档:

visualMap: { type: 'piecewise', pieces: [ { min: 800, label: '800 以上' }, { min: 500, max: 799, label: '500-799' }, { min: 200, max: 499, label: '200-499' }, { max: 199, label: '200 以下' } ], inRange: { color: ['#e0f3f8', '#abd9e9', '#74add1', '#4575b4'] }, left: 20, bottom: 20 }

pieces数组从上到下匹配,第一个满足条件的生效,所以要把大区间写在前面。inRange.color的颜色数量不要求和分段数一致,ECharts 会自动插值。这个配置在做区域销售对比、人口密度分布时比连续渐变清晰得多。

5.2 南海诸岛那块怎么处理才不别扭

china.js里通常包含南海诸岛的边界数据,但它的经纬度跨度很大,自动适配时会把主图挤到左上角。两种处理方式:一是用geo.layoutCenter和layoutSize手动控制主图位置,让南海诸岛自然落在右下角;二是单独用一个geo组件渲染南海诸岛,主图用另一个geo,两者通过map注册名区分。我一般用第一种,配置简单:

geo: { map: 'china', layoutCenter: ['50%', '50%'], layoutSize: '90%', roam: true, label: { show: false }, itemStyle: { areaColor: '#f3f3f3', borderColor: '#999' } }

layoutSize: '90%'让地图占容器 90%,留出边距。如果发现南海诸岛还是被裁掉,检查容器高度是否足够,地图的 bounding box 包含南海时纵向跨度会变大,容器太扁就会裁切。

5.3 一个我踩过的坑:地图文件更新后注册名冲突

有次项目里同时引入了两个版本的china.js,一个来自旧项目拷贝,一个来自新下载,两个文件都执行了registerMap('china', ...),后注册的覆盖先注册的,但两个文件的边界精度不一样,导致地图渲染出来一部分是旧边界一部分是新边界,看起来像错位。排查时在控制台执行echarts.getMap('china')看返回的 feature 数量,如果和预期不符就是被覆盖了。从那以后我每次引入地图文件前,都会先确认项目里没有同名的注册,注册名统一加项目前缀,比如proj-china,避免冲突。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 12:26:51

RIP路由协议从入门到实战:原理、配置与排错指南

搞网络的人迟早会碰到RIP这个协议&#xff0c;尤其是在学习路由交换或者维护早期网络设备的时候。RIP路由信息协议算是最古老也最容易理解的一种动态路由协议&#xff0c;就算现在生产环境里用得少了&#xff0c;它背后的距离矢量思想、防环机制、计时器设计仍然是理解其他路由…

作者头像 李华
网站建设 2026/10/23 13:35:24

用工波动常态化下的排班考勤数智化转型

用工波动这个词&#xff0c;前几年说出来还像是一个阶段性难题&#xff0c;这两年已经没人再用"阶段性"来描述了——它已经常态化。做过连锁门店、制造业工厂、物流中心或者客服外包的人应该都有同感&#xff1a;业务量像心电图一样起伏&#xff0c;今天爆单缺人到抓…

作者头像 李华
网站建设 2026/11/4 1:25:40

Linux开机启动全流程解析:固件、引导、内核与systemd排错指南

按下电源键到屏幕上出现登录提示&#xff0c;这短短几秒钟里&#xff0c;Linux 其实走完了一段相当复杂的接力赛。我最初真正搞懂 Linux 开机启动流程&#xff0c;不是从文档里读来的&#xff0c;而是某台服务器某天重启后直接停在 GRUB 救援提示符&#xff0c;满屏只有一个res…

作者头像 李华
网站建设 2026/10/20 22:17:53

快速排序原理与工业级优化实战指南

1. 为什么今天还要死磕快速排序&#xff1f;——它不是“老古董”&#xff0c;而是思维压舱石你可能在刷短视频时看到过这样的标题&#xff1a;“三行代码搞定排序&#xff01;”、“Python一行sort秒杀所有算法&#xff01;”——然后顺手点开&#xff0c;看完觉得“哦&#x…

作者头像 李华
网站建设 2026/10/23 6:20:54

网工修炼手册:从VLAN排障到Wireshark抓包与自动化实战

做了这么多年网络工程师&#xff0c;回头看最有用的不是那一摞证书&#xff0c;而是踩坑踩出来的判断力。所谓“网工修炼手册”&#xff0c;其实就是一门靠实操喂出来的手艺活——从最简单的VLAN划分&#xff0c;到故障现场抓包定位&#xff0c;再到用脚本把重复劳动交给机器去…

作者头像 李华