1. 程式人生 > >ECharts系列 (01):地圖三級下鑽

ECharts系列 (01):地圖三級下鑽

# 前言 最近專案中用到了`地圖下鑽`功能,GitHub上找到了一個輪子 - [echarts3-chinese-map-drill-down](https://github.com/touxing/echarts3-chinese-map-drill-down.git),啟動專案看了一下Demo,動畫銜接的很流暢,感覺做的非常棒:thumbsup::thumbsup::thumbsup:,膜拜大佬:pray::pray::pray: 我用VScode開啟這個專案的時候,發現註冊地圖用的部分原始JSON資料亂碼了,但不影響專案執行,不知道是不是自己的鍋:cry:,菜即是原罪:triumph:,粗略看了一下原始碼,技術棧用的是`jQuery + EChars`,本著與時俱進的想法,打算用`Vue + EChars`寫一個新輪子,哈哈哈哈,其實是我不太想在專案中用JQuery這種遠古時代的JavaScript庫,傲嬌臉:confused: 此篇文章用於記錄柏成從零開發一個`地圖下鑽Demo`的歷程 # 初始化地圖例項 ## 初始化香港18區人口密度 由於之前沒有接觸過ECharts的地理座標/地圖,本著官網是第一手學習資料原則,柏成首先初始化了一個官網示例 - [香港18區人口密度](https://echarts.apache.org/examples/zh/editor.html?c=map-HK),並根據 [文件配置項手冊](https://echarts.apache.org/zh/option.html#title) 自定義了地圖樣式,註冊地圖用到了一個方法:[registerMap](https://echarts.apache.org/zh/api.html#echarts.registerMap) > registerMap(mapName: string, geoJson: Object) - `mapName` 地圖名稱,在 [geo](https://echarts.apache.org/zh/option.html#geo) 元件或者 [map](https://echarts.apache.org/zh/option.html#series-map) 圖表型別中設定的 `map` 對應的就是該值 - `geoJson` GeoJson 格式的資料,具體格式見 https://geojson.org/,ECharts 使用 geoJSON格式的資料作為地圖的輪廓 ## 初始化中國地圖 通過官網示例柏成了解了地圖相關的屬性及API,對ECharts地圖有了一個大概認知,接下來我們初始化一箇中國地圖,此時我們需要中國地圖的 geoJSON格式的資料,通過ECharts官網得知 [地圖下載](https://echarts.apache.org/zh/download-map.html) >
ECharts 之前提供下載的向量地圖資料來自第三方,由於部分資料不符合國家《測繪法》規定,目前暫時停止下載服務。 好傢伙,看到官網通告我差點嗝屁了:scream:,本來想用輪子 [echarts3-chinese-map-drill-down](https://github.com/touxing/echarts3-chinese-map-drill-down.git) 中的 geoJSON資料,結果發現註冊地圖用的部分原始 geoJSON資料亂碼了:astonished:,雖然不影響使用,強迫症患者表示不可以:expressionless:,查閱了好久的資料,**最終在碼雲上找到了中國所有行政區的GeoJson資料 - [中國 GeoJson 資料](https://gitee.com/huanggefan/chinaGeoJson#https://cdn.huanggefan.cn/geojson/demo.html)**:clap::clap::clap: **&& github上意外發現了加強版GeoJson資料 [最新中國省市區縣geoJSON格式地圖資料](https://github.com/lyhmyd1211/GeoMapData_CN)**:sparkles::sparkles::sparkles:
註冊渲染地圖之後發現文字標籤位置並不理想,部分標籤偏移到了地圖之外,例如內蒙古,部分標籤揉擠作一團,例如北京天津河北,此時我們需要修改china.json原始 geoJSON資料,給每個省份的`properties`屬性下新增`cp`屬性,即文字居中位置,例如新疆維吾爾族自治區資料,詳細china.json資料請移步 [china-map-drill-down](https://gitee.com/lbcjs/china-map-drill-down/blob/master/public/geoJsonColl/china.json) 檢視 ```json { "type": "Feature", "properties": { "adcode": 650000, "name": "新疆", "cp": [86.9023, 41.148], ... }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [79.039649, 34.33427], [78.958961, 34.386132], [78.878273, 34.391563], ... ] ] ] } }, } ``` 噔噔噔噔:sunglasses::sunglasses::sunglasses:,這樣看著就舒服多了
# 自定義滑鼠事件 ## 自定義單擊事件 點選某個區域高亮,滑鼠移出地圖後高亮並沒有消失,搞了好半天,竟是ECharts V5新版本的特性:no_mouth:,如果不想要此效果,安裝 ECharts V4 or V3 即可 `npm i echarts@4 -S` ```js // 繫結自定義單擊事件 bindOnClickChart () { this.myChart.on('click', params => { console.log(params) }) }, ``` ## 自定義右擊事件 **首先要阻止預設右擊事件彈窗【圖片另存為,複製圖片 ... 】**:boom::boom::boom:,然後再自定義右擊事件,查閱 ECharts 官方API文件 [ECharts - API - 滑鼠事件](https://echarts.apache.org/zh/api.html#events.%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6) 得知右擊事件為:`myChart.on('contextmenu', function (params) { })` ```js // 繫結自定義右擊事件 bindOnContextmenuChart () { // 取消右擊預設事件 const body = document.getElementsByTagName('body')[0] body.oncontextmenu = e => e.preventDefault() // 繫結自定義右擊事件 this.myChart.on('contextmenu', params => { console.log(params) }) }, ``` # 下鑽思路 **地圖下鑽用到了棧先入後出的思想** **大體思路:**左擊進入地圖下一級,獲取註冊渲染地圖所需的 geoJSON資料 和 seriesData資料,然後註冊渲染地圖,並把當前地圖資料入棧;右擊返回地圖上一級,資料出棧,然後註冊渲染地圖 如果按照此思路嚴格執行的話,會發現我們需要建立一個額外的變數去儲存當前的地圖資料,用以左擊地圖入棧使用 **優化:**只要渲染地圖完畢,立即把當前地圖資料入棧,而不是左擊地圖時才進行入棧操作,但這樣會導致棧中最頂層的資料即是當前地圖資料,所以我們右擊返回時,需要先把最頂層資料pop,然後再次pop用以獲取上層地圖資料 # 下鑽動效 **開發前的預期效果:**當我重新註冊並渲染地圖時,想當然的認為ECharts會自動處理地圖上下級關係並注入切換動效,畢竟官網對`setOption`方法的介紹: > 設定圖表例項的配置項以及資料,萬能介面,所有引數和資料的修改都可以通過 `setOption` 完成,ECharts 會合並新的引數和資料,然後重新整理圖表。**如果開啟[動畫](https://echarts.apache.org/v4/zh/option.html#option.animation)的話,ECharts 找到兩組資料之間的差異然後通過合適的動畫去表現資料的變化。** 而我使用 V4 - 4.9.0 版本實際操作時發現,地圖層級之間毫無過渡動畫,生硬至極,what:question::question::question:,難道地圖註冊`registerMap`不相容`setOption`動畫:exclamation::exclamation::exclamation:,不應該吧:question:,不會吧:question:,馬上就薅成:older_man:時,我隱隱感覺可能是ECharts版本的鍋,於是我更新了Echarts最新 V5 -5.0.2 版本`npm i echarts@latest -S`,重啟專案發現還是不行,重來,之後我將Echarts降級到了V3版本`npm i echarts@3 -S`,大功告成:ok_hand::ok_hand::ok_hand: **經親自嘗試,只要ECharts版本 <= 4.3.0,即帶下鑽動效** 為什麼版本更新會把地圖下鑽的動效給去掉,很是不能理解,也可能是我太菜了,沒找到新版本地圖開啟動效的正確方式,如有大佬知道,請指點一二:sparkles::sparkles::sparkles: # 原始碼 地圖下鑽demo程式碼:[china-map-drill-down](https://gitee.com/lbcjs/china-map-dri