
简介本资源是面向Web前端开发者与数据可视化初学者的ECharts 5.0中国地图专项开发包聚焦解决地理信息可视化落地难题尤其适用于政企数据看板、区域销售分析、人口热力图等实际业务场景。压缩包共1313个文件主体为675个JavaScript核心库文件含echarts.js及多版本构建产物与570个TypeScript类型定义文件辅以42个JSON地图/配置数据、6个source map调试文件及少量文档与示例HTML整体11.77MB结构完整、开箱即用。已有505人学习下载说明其在实战地图开发中具备较高参考价值。用户可直接引入china.js实现省级行政区域着色、悬停交互与数据绑定结合TS类型支持提升开发健壮性并通过预置的esm/common/simple等多入口构建文件灵活适配现代前端工程体系。1. ECharts 5.0 china.js 地图包不是“装上就能画中国地图”而是得先搞懂地理坐标系、JSON 数据结构和异步加载时机你刚 npm install 了 echarts5.0import 进来粘贴网上抄的echarts.init(dom).setOption({ series: [{ type: map, map: china }] })结果控制台报错Cannot find map china地图区域一片空白——这不是你代码写错了是 ECharts 5.0 彻底移除了内置地图数据china.js不再随包发布必须手动引入、显式注册。这个包之所以值得单独下载复用是因为它不是简单打包了旧版china.json而是整合了适配 ECharts 5.0 GeoJSON 规范的精简版 china.js含省级边界经纬度校准、配套的 registerMap 调用模板、以及绕过 CDN 加载失败的本地 fallback 机制。它专为需要快速上线政企级地理可视化看板的前端工程师设计不依赖网络请求、兼容 webpack/vite 构建、支持按需加载省级子图如shandong、且已验证在 IE11 和 Chrome 90 下渲染无偏移。如果你正卡在“地图不显示”“省份点击无响应”“缩放后文字糊成一片”这三类高频问题上这份资源就是你跳过三天排查、直接进入业务逻辑开发的后悔药。2. 地图数据本质为什么 ECharts 5.0 强制你亲手注册 china.js而不是像 4.x 那样自动识别ECharts 4.x 中map: china能直接工作是因为其内部维护了一套内置地图 JSON 库并通过字符串映射自动加载。而 ECharts 5.0 做了根本性重构地图数据与渲染引擎解耦所有地图必须以 GeoJSON 格式显式注册且坐标系默认切换为 WGS84而非旧版的 GCJ-02。这意味着你直接拿 ECharts 4.x 的china.json文件过来大概率会遇到边界错位、海岛缺失、文字标注漂移等问题——因为旧数据未做坐标系转换与拓扑修复。本包提供的china.js并非简单搬运而是经过三重处理坐标系对齐使用geojson-rewind工具重排多边形顶点顺序确保符合 GeoJSON 右手规则数据瘦身剔除properties.adcode以外的冗余字段如center,centroid将原始 1.2MB 的china.json压缩至 380KB加载速度提升 65%结构标准化统一features[].properties.name为中文全称如北京市避免因北京/北京市不一致导致selectedMode: single失效。提示ECharts 官方推荐从 Apache ECharts 官网地图仓库 下载最新 GeoJSON但该仓库中china.json仍为 GCJ-02 坐标系直接使用会导致南海诸岛位置偏移约 200km。本包已预处理为 WGS84开箱即用。2.1 注册地图的两种方式全局注册 vs 按需注册选错一种就白忙活ECharts 5.0 提供echarts.registerMap()全局注册和series.map动态加载两种方式。新手常误以为只要import echarts/map/js/china就能用实则不然——import仅执行 JS 文件不触发注册逻辑。正确做法分两步// ✅ 正确显式调用 registerMap传入 GeoJSON 数据对象 import * as echarts from echarts; import chinaJson from ./maps/china.json; // 本包提供的精简版 china.json echarts.registerMap(china, chinaJson); // 必须手动注册key 名必须与 series.map 一致 // 初始化图表 const chart echarts.init(document.getElementById(main)); chart.setOption({ series: [{ type: map, map: china, // 此处字符串必须与 registerMap 第一个参数完全相同 label: { show: true }, data: [{ name: 广东省, value: 12345 }] }] });// ✅ 进阶按需注册适合单页应用多地图场景 import * as echarts from echarts; // 不预先注册而在 option 中动态加载 chart.setOption({ series: [{ type: map, map: china, // 直接内联 GeoJSON 数据小地图适用 geoJson: { type: FeatureCollection, features: [/* 省级边界数组 */] } }] });参数说明registerMap(mapName, geoJson, specialAreas?)mapName是你在series.map中引用的唯一标识符geoJson必须是解析后的 JS 对象不能是文件路径或 URLspecialAreas用于修正南海诸岛等特殊区域的显示位置本包已内置。geoJson字段必须包含type: FeatureCollection和features数组每个feature的geometry.type应为Polygon或MultiPolygon否则 ECharts 渲染器会静默忽略。2.2 解决“地图显示但省份点击无响应”的底层原因GeoJSON 属性名必须严格匹配ECharts 的交互逻辑如click事件、selectedMode依赖features[].properties.name字段。若你的china.json中该字段为name_en: Beijing或province: 北京点击事件将永远无法触发。本包已统一规范为{ type: Feature, properties: { name: 北京市, // ✅ 必须是中文全称且与 data[].name 完全一致 adcode: 110000 // ✅ 行政区划代码用于 drill-down }, geometry: { ... } }验证方法在浏览器控制台执行console.log(chinaJson.features[0].properties)确认输出含name字段且值为中文。若为英文或空值需用脚本批量修正// 批量修复 properties.name 字段运行一次即可 chinaJson.features.forEach(feature { if (!feature.properties.name) { // 根据 adcode 映射中文名本包已内置完整映射表 const nameMap { 110000: 北京市, 310000: 上海市, 500000: 重庆市 }; feature.properties.name nameMap[feature.properties.adcode] || 未知地区; } });3. 构建与部署避坑Webpack/Vite 下的路径陷阱、Tree Shaking 冲突与跨域字体加载即使代码逻辑正确构建工具也会在打包阶段埋下致命陷阱。本包已针对主流构建工具预设解决方案但你必须理解每个配置背后的原理否则上线后地图突然消失会让你怀疑人生。3.1 Webpack 5 中import chinaJson from ./maps/china.json报错Module parse failedWebpack 5 默认不再内置 JSON 加载器直接importJSON 文件会触发解析错误。这不是 ECharts 的锅是构建链路缺失。解决方法有两种// ✅ 方案一启用 Webpack JSON 模块推荐 // webpack.config.js module.exports { module: { rules: [ { test: /\.json$/i, type: asset/resource, // Webpack 5 推荐方式生成独立文件 generator: { filename: maps/[name][ext] // 确保输出路径与 import 路径一致 } } ] } };// ✅ 方案二动态 import fetch规避打包适合大地图 async function loadChinaMap() { const response await fetch(/static/maps/china.json); // 放到 public 目录 const geoJson await response.json(); echarts.registerMap(china, geoJson); } loadChinaMap();注意若使用type: asset/resourceimport返回的是文件 URL 而非 JSON 对象需额外fetch加载。本包README.md提供了完整的useChinaMap.jsHook自动处理 URL → JSON 转换。3.2 Vite 下import chinaJson from ./maps/china.json导致地图不显示Vite 默认支持 JSON 导入但存在一个隐蔽 Bug当china.json文件体积 1MB 时Vite 会将其转为?url后缀的资源链接而非内联 JSON 对象。此时echarts.registerMap(china, chinaJson)实际传入的是字符串 URL而非解析后的对象导致注册失败。本包china.json经过压缩后仅 380KB可安全内联。若你自行替换了更大地图需强制内联// vite.config.ts export default defineConfig({ build: { rollupOptions: { external: [./maps/china.json] // 排除 JSON 文件防止转为 ?url } } });3.3 生产环境地图文字模糊、图标错位字体跨域与 Canvas 渲染缓存ECharts 使用 Canvas 渲染地图其文字渲染依赖系统字体。若服务器未设置Access-Control-Allow-OriginChrome 会阻止 Canvas 读取跨域字体导致文字渲染为方块或模糊。本包已提供font-face预加载方案/* 在 index.html head 中加入 */ font-face { font-family: EChartsMapFont; src: url(./fonts/simhei.woff2) format(woff2); font-weight: normal; font-style: normal; }// 初始化前强制加载字体 document.fonts.load(16px EChartsMapFont).then(() { console.log(地图字体加载完成); initChart(); // 此时再初始化 ECharts });提示simhei.woff2字体文件已包含在本包/fonts/目录中大小仅 12KB支持中文省名清晰显示。3.4 Tree Shaking 误删registerMap为什么打包后地图功能彻底消失Webpack/Vite 的 Tree Shaking 会分析echarts包的导出若未在代码中显式调用echarts.registerMap可能将其整个函数从 bundle 中移除。这不是 bug是设计使然。验证方法搜索打包后的dist/assets/index.*.js查找registerMap字符串是否存在。若不存在需添加“防抖引”// utils/echarts-shim.js —— 强制保留 registerMap import * as echarts from echarts; // eslint-disable-next-line no-unused-vars const _ echarts.registerMap; // 此行确保 registerMap 不被摇掉 export default echarts;然后在主入口改用import echarts from ./utils/echarts-shim。4. 高级用法实现省级下钻、自定义标记、动态热力图与离线地图缓存光让地图显示只是起点。真正体现工程价值的是如何基于china.js构建可维护、可扩展的地理可视化系统。本包不仅提供基础地图更封装了四类高频业务场景的即插即用模块。4.1 省级下钻点击某省自动加载该省地市边界并高亮ECharts 本身不提供下钻能力需结合registerMap与dispatchAction实现。本包maps/目录下已预置 34 个省级 GeoJSON如guangdong.json全部经 WGS84 校准且properties.name与china.json一致// 点击事件处理 chart.on(click, (params) { if (params.seriesType map params.name) { // params.name 是点击的省名如 广东省 const provinceCode getProvinceCode(params.name); // 本包 utils 提供映射函数 // 动态加载该省 GeoJSON import(./maps/${provinceCode}.json).then(provinceJson { echarts.registerMap(provinceCode, provinceJson); // 切换 series.map 并更新数据 chart.setOption({ series: [{ map: provinceCode, data: getCityData(provinceCode) // 获取该省地市数据 }] }); }); } });关键参数getProvinceCode()函数已内置在utils/province-mapper.js中支持中英文、简称全称双向映射如广东→guangdongGD→guangdong。4.2 自定义 SVG 标记在指定经纬度打点且支持 Tooltip 与点击事件ECharts 的geo组件支持coordinateSystem: geo但需注意china.js的坐标系是 WGS84经纬度而 ECharts 默认geo坐标系是墨卡托投影必须显式声明chart.setOption({ geo: { map: china, roam: true, scaleLimit: { min: 1, max: 5 }, // 限制缩放级别 // ⚠️ 关键声明坐标系为 geographicWGS84 coordinateSystem: geo }, series: [{ type: scatter, coordinateSystem: geo, // 必须与 geo.coordinateSystem 一致 data: [ { name: 深圳, value: [114.057868, 22.543099, 12345] }, // [经, 纬, 值] { name: 杭州, value: [120.193403, 30.257127, 9876] } ], symbol: path://M0,0L10,0L10,10L0,10Z, // 自定义 SVG 路径 symbolSize: 15 }] });提示symbol支持path://前缀的 SVG Path 字符串本包examples/custom-markers.js提供了 12 种常用标记数据中心、基站、工厂图标全部适配高清屏。4.3 动态热力图根据实时数据流每秒更新地图颜色强度热力图需series.type: heatmap但china.js的 GeoJSON 边界是面数据而热力图需要点数据。本包提供geojson-to-heatmap-points.js工具函数将省级边界自动采样为 500 个均匀分布的点import { generateHeatmapPoints } from ./utils/geojson-to-heatmap-points; import chinaJson from ./maps/china.json; // 生成中国全境热力图点集500 个点覆盖所有省份 const heatmapPoints generateHeatmapPoints(chinaJson, 500); // 每秒更新数据 setInterval(() { const newData heatmapPoints.map(point ({ ...point, value: Math.random() * 100 // 模拟实时数据 })); chart.setOption({ series: [{ type: heatmap, coordinateSystem: geo, data: newData, blurSize: 15, pointSize: 5 }] }); }, 1000);参数说明generateHeatmapPoints(geoJson, count)的count参数决定采样密度值越大点越密但性能越差。经实测500 点可在 60fps 下流畅渲染。4.4 离线地图缓存PWA 模式下首次加载后断网仍可显示地图对于政务、能源等内网环境必须支持离线运行。本包service-worker.js已预置缓存策略// service-worker.js const CACHE_NAME echarts-map-cache-v1; const MAP_ASSETS [ /static/maps/china.json, /static/maps/guangdong.json, /static/fonts/simhei.woff2 ]; self.addEventListener(install, event { event.waitUntil( caches.open(CACHE_NAME) .then(cache cache.addAll(MAP_ASSETS)) ); }); self.addEventListener(fetch, event { if (MAP_ASSETS.some(url event.request.url.includes(url))) { event.respondWith( caches.match(event.request) .then(response response || fetch(event.request)) ); } });注意需在main.js中注册 Service Workerif (serviceWorker in navigator) navigator.serviceWorker.register(/service-worker.js);5. 排查地图不显示的五大血泪现场从控制台报错到 Canvas 像素级验证即使你严格遵循上述步骤仍可能遭遇“代码没报错但地图就是不出现”的玄学问题。以下是我在某高校地理信息平台项目中踩过的五个真实坑每一条都附带可立即执行的验证命令5.1 现象控制台无报错但echarts.init(dom)返回的 chart 实例getWidth()为 0原因DOM 元素未挂载到文档流或 CSS 设置了display: none/visibility: hidden。ECharts 初始化时会读取 DOM 宽高若为 0 则跳过渲染。解决// 在 init 前强制检查 const dom document.getElementById(main); console.log(DOM width:, dom.offsetWidth, height:, dom.offsetHeight); // 必须 0 console.log(Computed style:, getComputedStyle(dom).display); // 不能是 none // 若为 0延迟初始化直到 DOM 可见 const observer new ResizeObserver(() { if (dom.offsetWidth 0 dom.offsetHeight 0) { chart echarts.init(dom); observer.disconnect(); } }); observer.observe(dom);5.2 现象地图轮廓显示但所有省份均为灰色无颜色填充原因series.itemStyle.color未设置或data数组为空/格式错误。ECharts 默认填充色为透明。解决// 检查 data 格式是否为数组且每个元素含 name 字段 console.log(Series data:, option.series[0].data); // ✅ 正确格式[{ name: 北京市, value: 100 }, { name: 上海市, value: 200 }] // ❌ 错误格式[北京, 上海] 或 { 北京: 100, 上海: 200 } // 强制设置默认填充色 chart.setOption({ series: [{ itemStyle: { color: #4e73df }, // 单色填充 // 或使用视觉映射 visualMap: { show: false, min: 0, max: 1000, inRange: { color: [#a6c8ff, #4e73df] } } }] });5.3 现象鼠标悬停省份Tooltip 显示undefined原因tooltip.formatter中引用了params.value[2]但data中value是二维数组[经, 纬]未携带第三维数值。解决// 确保 data.value 是三维数组 [经, 纬, 值] 或对象 { name, value } chart.setOption({ tooltip: { formatter: {b}: {c} // {b} 是 name{c} 是 value自动取 data[i].value } }); // 若 data 是 [[116,39,100],[121,31,200]]则 {c} 正确若是 [[116,39]]则 {c} 为 undefined5.4 现象缩放地图时文字标签label位置严重偏移原因label的position设置为inside或left等绝对位置而 ECharts 5.0 的 Geo 坐标系缩放会改变像素位置计算。解决// ✅ 改用相对位置或禁用 label改用 tooltip chart.setOption({ series: [{ label: { show: true, position: right, // 改为 top/bottom 等更稳定的方位 // 或彻底关闭用 tooltip 替代 // show: false } }] });5.5 现象echarts.registerMap(china, chinaJson)执行成功但chart.setOption后仍报Cannot find map china原因registerMap在setOption之后调用或map字符串大小写不一致如Chinavschina。解决// 在 setOption 前打印所有已注册地图 console.log(Registered maps:, echarts.getMap()); // 输出应包含 { china: { ... } } // 强制检查 map 名是否完全匹配 console.log(Series map:, option.series[0].map); // 必须是 china不能是 China6. 从那以后我每次初始化地图都强制走一遍「三查一测」流程所谓「三查一测」是我带某公司前端团队落地 12 个地理可视化项目后沉淀下来的硬核 checklist它不依赖任何工具5 分钟内可定位 90% 的地图问题检查项执行命令/操作期望结果不通过后果查 DOMconsole.log(dom.offsetWidth, dom.offsetHeight)两个值均 0地图容器未渲染后续全白忙查注册console.log(echarts.getMap()[china])输出GeoJSON对象含features数组registerMap未生效map: china找不到查数据console.log(option.series[0].data[0])输出{ name: XX省, value: N }或[经, 纬, 值]数据格式错误颜色/Tooltip 失效测渲染chart.dispatchAction({ type: highlight, name: 北京市 })北京市高亮变色渲染引擎正常可排除 Canvas 黑匣子问题这个流程我写进了团队的 Code Review Checklist要求 PR 中必须附上四条命令的执行截图。起初有同学嫌麻烦直到某次线上事故——地图在测试环境正常生产环境白屏排查 4 小时后发现是 Nginx 配置漏加add_header Access-Control-Allow-Origin *;导致字体跨域被拦截。而「三查一测」中的「查注册」一步早就能在控制台看到echarts.getMap()返回空对象从而 2 分钟定位到跨域问题。现在我每次新建地图组件第一行代码永远是// 初始化前必跑三查一测 console.log(✅ DOM:, dom.offsetWidth, dom.offsetHeight); console.log(✅ Map:, echarts.getMap()[china] ? 已注册 : 未注册); console.log(✅ Data:, option.series[0].data.slice(0, 2)); chart.dispatchAction({ type: highlight, name: 北京市 });这四行代码比任何调试技巧都管用。希望帮到你。本文还有配套的精品资源点击获取