:下載、注冊與排查指南)
簡介為使用Echarts進行數(shù)據(jù)可視化的前端開發(fā)者與數(shù)據(jù)分析師提供可直接復(fù)用的世界地圖JSON文件解決繪制世界地圖時地理數(shù)據(jù)難搜集、格式不兼容、版本不匹配等問題。壓縮包為RAR格式內(nèi)含1個JSON文件包體僅279KB解壓后可直接嵌入項目適用于全球業(yè)務(wù)分布、大屏數(shù)據(jù)展示、國際物流軌跡等可視化場景在搭建跨國業(yè)務(wù)看板、統(tǒng)計海外用戶分布或展示全球合作伙伴時尤為實用。JSON數(shù)據(jù)涵蓋世界主要國家邊界與區(qū)域信息結(jié)構(gòu)清晰經(jīng)過實際項目驗證可配合Echarts地圖組件快速渲染支持自定義樣式、區(qū)域選中和數(shù)據(jù)下鉆等常見交互需求內(nèi)置的邊界數(shù)據(jù)可滿足常見國家的頁面展示與數(shù)據(jù)聯(lián)動。無需重新整理或轉(zhuǎn)換數(shù)據(jù)格式下載后即可將精力集中于業(yè)務(wù)邏輯與視覺效果優(yōu)化也便于團隊內(nèi)部統(tǒng)一維護和復(fù)用。目前已有1705人學(xué)習(xí)/下載適合中級開發(fā)者快速調(diào)用也可作為團隊通用的地圖數(shù)據(jù)資產(chǎn)沉淀復(fù)用。 做數(shù)據(jù)可視化這幾年跟 ECharts 世界地圖 JSON 文件打交道的次數(shù)比我吃過的夜宵還多。尤其是大屏項目十有八九要把業(yè)務(wù)數(shù)據(jù)落到地圖上。前陣子接了個全球業(yè)務(wù)分布的大屏需求很普通世界地圖上按國家染色再掛幾條飛線。結(jié)果第一步就卡住了——ECharts 從 5.x 開始不再內(nèi)置世界地圖數(shù)據(jù)官方示例里那個 world 地圖需要你自己準備 JSON 文件。這期間我把世界地圖和十幾個主要國家的 GeoJSON 文件翻來覆去折騰了一遍今天就把這件事徹底講透地圖 JSON 是什么、從哪下載、怎么接進 ECharts、以及最容易踩的坑。不管你是剛接觸 ECharts 的新人還是已經(jīng)做過多個大屏的老手這份實操筆記應(yīng)該都用得上。1. 地圖 JSON 到底是什么——先搞明白你下載的文件里裝的是啥1.1 GeoJSON 結(jié)構(gòu)拆解ECharts 用的地圖文件本質(zhì)上就是 GeoJSON。GeoJSON 是一種用 JSON 描述地理空間數(shù)據(jù)的標準格式它最常見的頂層結(jié)構(gòu)叫 FeatureCollection翻譯過來是“要素集合”。一個要素對應(yīng)一個圖形區(qū)域世界地圖里的要素是各個國家中國地圖里的要素是各個省級行政區(qū)。一個典型的 feature 看起來是這樣{ type: FeatureCollection, features: [ { type: Feature, properties: { name: China, cp: [104.1954, 35.8617], adcode: 100000 }, geometry: { type: MultiPolygon, coordinates: [ [ [[110.2, 21.5], [110.4, 21.8], [110.6, 21.3]] ] ] } } ] }這里最關(guān)鍵的是 coordinates 字段。它是一組經(jīng)緯度坐標數(shù)組每個坐標寫成 [經(jīng)度, 緯度] 的形式。對于一個多邊形區(qū)域坐標按順序圍成一個閉合形狀如果區(qū)域跨越了 180 度經(jīng)線或者國家有海外領(lǐng)地數(shù)據(jù)源會用 MultiPolygon 記錄多個獨立的多邊形。ECharts 在渲染時會逐個讀取 coordinates 生成幾何路徑再用 properties.name 作為區(qū)域名字。所以拿到一份地圖 JSON你只需要關(guān)心三點第一coordinates 描述形狀不能亂動第二properties.name 是區(qū)域名必須唯一第三如果文件里有兩個 feature 重名渲染時后一個會把前一個覆蓋掉。這三點是排查地圖問題的基礎(chǔ)后面會反復(fù)用到。1.2 為什么從 ECharts 5 開始地圖數(shù)據(jù)要自己找2019 年之前接觸 ECharts 的朋友應(yīng)該有印象4.x 時代內(nèi)置了 world.json、china.json 和不少省份地圖引入一個包就能畫。但從 ECharts 5 開始官方策略變了內(nèi)置地圖數(shù)據(jù)被移除你需要自己準備、自己注冊。官方解釋是地圖數(shù)據(jù)維護成本高邊界和產(chǎn)權(quán)問題不應(yīng)跟著框架一起發(fā)布。這個變化帶來的直接后果是網(wǎng)上大量老教程里的示例代碼跑不起來了。你把代碼原樣抄下來地圖區(qū)域一片空白控制臺還不報錯原因就是少了 registerMap 這一步。所以現(xiàn)在做地圖可視化第一步永遠是解決數(shù)據(jù)源而不是急著調(diào) option。1.3 世界地圖文件比想象中“大”世界地圖 JSON 不像普通配置那么輕量。我自己常用的帶中文標注的世界地圖文件體積通常在 800KB 到 1.5MB 之間主要是多邊形邊界點太細有些數(shù)據(jù)源光是中國一個區(qū)域就有幾千個坐標點。如果打包進主包或者直接 script 引文件加載體驗都不會太好這塊我在性能優(yōu)化小節(jié)展開。還有一個容易忽略的點世界地圖和國家地圖通常是“分而治之”的。你下載的 world.json 包含全世界所有國家的要素但是要單獨展示美國、日本、德國這種大國時業(yè)內(nèi)主流做法是下載對應(yīng)國家的獨立 JSON而不是從 world.json 里按 name 去篩。雖然技術(shù)上篩得出來但世界地圖里單個國家的邊界裁剪精度、坐標范圍未必適合做國家級別的可視化所以各大開源項目都會按國家把文件拆好。2. 從哪搞到靠譜的世界地圖和國家地圖 JSON含渠道對比2.1 首選阿里云 DataV.GeoAtlas第一個要推薦的渠道是阿里云 DataV 的 GeoAtlas 地理小工具。它提供世界地圖、中國地圖到每個市區(qū)縣的 GeoJSON 數(shù)據(jù)界面很樸素左邊選區(qū)域右側(cè)給出 JSON API 地址和下載按鈕。它最大的優(yōu)勢是規(guī)范。每個 feature 的 properties 都帶 name中文、adcode行政區(qū)劃代碼、cp中心點經(jīng)緯度等字段。adcode 在國內(nèi)省市地圖的聯(lián)動場景里非常有用比如你可以拿它做地市下鉆。世界地圖也是完整中文名省去手動翻譯的麻煩。不過GeoAtlas 的世界地圖在正式環(huán)境使用前我還是建議人工核對一遍邊界。這類數(shù)據(jù)源會持續(xù)更新但地圖邊界這種事上線前自己驗證一次比出了問題再補救成本低得多。2.2 GitHub 開源倉庫里的“國家獨立包”如果你需要“主要國家的獨立 JSON”GitHub 上最常用的就是 echarts-maps 這類倉庫。它把世界地圖按國家拆開文件命名基本是英文國家名比如 usa.json、japan.json、germany.json?;A(chǔ)地理信息變化不頻繁這類倉庫的更新頻率參差也不影響使用。下載時我建議選未壓縮的源碼版本別直接用 dist 目錄里的壓縮產(chǎn)物。壓縮后的文件字段名會變短比如 properties 變成 p調(diào)試時非常難受。先用原始 GeoJSON 做開發(fā)上線前再考慮通過 gzip 或傳輸層壓縮來減體積前端代碼里不需要做二次壓縮。2.3 五分鐘數(shù)據(jù)源自查清單不管從哪下載我拿到地圖文件后都會先做一遍檢查避免做了一半才發(fā)現(xiàn)數(shù)據(jù)有坑用編輯器或在線校驗工具打開確認是合法 JSON不是 HTML 錯誤頁。搜索 properties.name確認包含你要展示的國家/地區(qū)名稱。確認中國邊界完整。國外一些開源數(shù)據(jù)源可能會在邊界上缺斤少兩這個必須在開發(fā)前盯一眼。檢查經(jīng)緯度范圍經(jīng)度應(yīng)該在 -180 到 180 之間緯度在 -90 到 90 之間。如果出現(xiàn)三位數(shù)緯度或超過 180 的經(jīng)度這份數(shù)據(jù)基本是壞的。查看文件體積超過 5MB 直接考慮換精簡版。2.4 常見渠道橫向?qū)Ρ惹栏采w范圍語言優(yōu)點注意點阿里云 GeoAtlas世界/中國/省市區(qū)中文為主規(guī)范、含 adcode上線前自檢邊界GitHub 開源倉庫世界國家獨立包英文為主國家獨立文件好找更新不固定官網(wǎng)示例世界地圖 demo英文能快速跑通只有世界沒有國家自制/裁剪工具按需定制自定義體積最小學(xué)習(xí)成本高我的建議很直接做世界地圖優(yōu)先用 GeoAtlas做某個國家的詳細地圖去 GitHub 對應(yīng)倉庫找獨立 JSON做國內(nèi)省市下鉆GeoAtlas 一把梭。3. 從文件到可視化注冊地圖與核心配置實操3.1 registerMap 是接入的第一行代碼拿到 JSON 文件后第一件事是注冊。ECharts 提供了全局方法 registerMapimport * as echarts from echarts; import worldJson from ./map/world.json; echarts.registerMap(world, worldJson);registerMap 的名字這里是world是后續(xù)所有配置引用的 key。注冊完成后geo 組件和 map 系列都可以直接用這個名字option { geo: { map: world, roam: true, itemStyle: { areaColor: #1a2a6c, borderColor: #fff } } };兩個細節(jié)容易踩一是同一個頁面重復(fù)注冊同名 key 會覆蓋之前的地圖二是如果你要同時展示世界地圖和中國地圖注冊名要起成world和china配置時別串。3.2 中英文名稱對齊新手翻車重災(zāi)區(qū)世界地圖里 properties.name 可能是英文也可能是中文這取決于你下載的版本。ECharts 的 map 系列按名稱匹配數(shù)據(jù)項如果 JSON 里是 China 而你數(shù)據(jù)里叫“中國”這個國家就顯示不了數(shù)值只有默認底色。解決辦法無非三種換用帶中文 name 的 JSON、寫腳本把數(shù)據(jù)源轉(zhuǎn)換成中文、或者用 nameMap 做映射。我個人的習(xí)慣是統(tǒng)一中文名。寫一個簡單的 Node 腳本遍歷 features把 properties.name 從英文翻譯成中文存成新 JSON。這樣做的好處是后續(xù) option 里寫起來直觀也不用每次都做中英文對照。注意腳本跑完要重新檢查一遍 name 是否有重名或空值。3.3 visualMap 上色與 pieces 分段數(shù)據(jù)掛上之后最常用的就是給地圖染色。連續(xù)漸變用 visualMap 的 continuous 類型就行但如果要按業(yè)務(wù)閾值分段用 pieces 更合適visualMap: { type: piecewise, pieces: [ { min: 500, label: 高, color: #ff4d4f }, { min: 100, max: 500, label: 中, color: #faad14 }, { max: 100, label: 低, color: #52c41a } ], left: 20, bottom: 20 }配置之后會自動生成圖例非常直觀。有個小坑pieces 數(shù)組里的順序會直接影響圖例顯示順序建議從高到低寫讓圖例靠上的就是高值段。另外visualMap 默認取 series.data 里的 value。如果你的字段叫 count 或 sales要么在數(shù)據(jù)接入時重構(gòu)成 { name, value }要么在 series 里做一次映射。前者更簡單直觀。3.4 在地圖上疊加散點和飛線大部分地圖項目不會只畫一個純色底圖。要在世界地圖上標業(yè)務(wù)點、畫航線我的方案是 geo scatter/lines 組合而不是把所有東西塞進 map 系列。散點的核心配置如下series: [ { type: scatter, coordinateSystem: geo, data: [ { name: 北京點, value: [116.4, 39.9, 100] }, { name: 紐約點, value: [-74.0, 40.7, 80] } ], symbolSize: function (val) { return val[2] / 10; } } ]散點 data 的 value 是 [經(jīng)度, 緯度, 數(shù)值] 的組合geo 坐標系會自動把點放到正確位置。飛線用 lines 系列加 effect 做流動效果坐標同樣是 [經(jīng)度, 緯度]。這個組合的好處是地圖本體和業(yè)務(wù)數(shù)據(jù)分離換地圖時業(yè)務(wù)數(shù)據(jù)不用大改。4. 地圖不顯示、點不動常見問題與排查技巧實錄4.1 區(qū)域空白、沒邊框先查 name地圖區(qū)域渲染成空白九成是名稱沒對上。排查順序先 console.log 一個 feature 的 properties.name再去看 series.data 的 name兩者一致才有數(shù)值。如果文件本身有問題用地圖形工具預(yù)覽一下就能看出來預(yù)覽正常說明問題一定在 name 匹配。4.2 DOM 尺寸為 0 的報錯頁面隱藏或移動端初始化時ECharts 經(jīng)常報 Cant get DOM width or height。根因是容器還沒渲染出來寬度是 0。常見觸發(fā)場景是 tab 切換、v-if 控制顯示時調(diào)用 init。解決辦法很簡單等容器可見之后再初始化或手動觸發(fā) resizeconst chart echarts.init(dom); setTimeout(() chart.resize(), 200); new ResizeObserver(() { chart.resize(); }).observe(dom);在 uniapp 或者 web-view 環(huán)境里用 ECharts 時這個問題出現(xiàn)得更頻繁記得在頁面 onReady 且當(dāng)前 tab 被激活后再初始化。4.3 移動端地圖點不動、手勢沖突地圖在移動端經(jīng)常出現(xiàn)滑動沒反應(yīng)、點不到點的問題通常是 touch 事件和頁面滾動沖突。我的三個處理方向把 roam 改成scale只允許縮放不允許平移。通過按鈕控制縮放級別直接關(guān)掉 roam。在容器樣式上加touch-action: pan-y把縱向滾動留給頁面縮放和橫向手勢交給圖表。實測下來第三種方案在 H5 里最穩(wěn)。但 native app 的 webview 兼容性因系統(tǒng)而異建議多拿幾臺真機測。4.4 地圖加載慢從文件瘦身開始世界地圖 JSON 文件動輒幾百 KB弱網(wǎng)下體驗很差。四條路按優(yōu)先級排列開啟 gzip 或 br 壓縮傳輸。GeoJSON 是純文本壓縮率很高1MB 文件 gzip 后能到 200KB 左右。按需加載進入地圖頁才 fetch JSON不要打進主包。用 mapshaper 降低坐標精度把小數(shù)位從 6 位壓到 2-3 位體積能再砍一半。渲染側(cè)開 large: true但世界地圖一般用不上主要還是靠文件瘦身。4.5 排查速查表現(xiàn)象可能原因解決方向整片空白無邊框數(shù)據(jù)未注冊或 name 不匹配檢查 registerMap 和 data name有邊框但不上色series.data 與地圖 name 不一致統(tǒng)一命名格式拖動/縮放失靈手勢沖突或 roam 設(shè)置錯誤調(diào)整 roam、touch-action小島或飛地消失坐標精度被過度壓縮降低壓縮比例瀏覽器報跨域本地 file 協(xié)議直接打開起本地靜態(tài)服務(wù)器從我個人的使用習(xí)慣來說ECharts 地圖數(shù)據(jù)這塊沒有高深技術(shù)就是“數(shù)據(jù)準、名稱對、注冊好”三件事。但網(wǎng)上教程大多停留在老版本照搬容易踩坑。我自己的習(xí)慣是拿到任何一份 GeoJSON先寫個十來行的腳本統(tǒng)計 features 數(shù)量、name 列表、文件體積做到心里有數(shù)再接圖表上線前再逐個核對關(guān)鍵地區(qū)的邊界。地圖文件就單獨放在項目 assets 或 public 目錄里方便后續(xù)替換。如果你也正在做地圖可視化希望這篇能幫你少走幾步彎路。本文還有配套的精品資源點擊獲取