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

柏成發表於2021-03-15

前言

最近專案中用到了地圖下鑽功能,GitHub上找到了一個輪子 - echarts3-chinese-map-drill-down,啟動專案看了一下Demo,動畫銜接的很流暢,感覺做的非常棒???,膜拜大佬???

我用VScode開啟這個專案的時候,發現註冊地圖用的部分原始JSON資料亂碼了,但不影響專案執行,不知道是不是自己的鍋?,菜即是原罪?,粗略看了一下原始碼,技術棧用的是jQuery + EChars,本著與時俱進的想法,打算用Vue + EChars寫一個新輪子,哈哈哈哈,其實是我不太想在專案中用JQuery這種遠古時代的JavaScript庫,傲嬌臉?

此篇文章用於記錄柏成從零開發一個地圖下鑽Demo的歷程

初始化地圖例項

初始化香港18區人口密度

由於之前沒有接觸過ECharts的地理座標/地圖,本著官網是第一手學習資料原則,柏成首先初始化了一個官網示例 - 香港18區人口密度,並根據 文件配置項手冊 自定義了地圖樣式,註冊地圖用到了一個方法:registerMap

registerMap(mapName: string, geoJson: Object)

  • mapName

    地圖名稱,在 geo 元件或者 map 圖表型別中設定的 map 對應的就是該值

  • geoJson

    GeoJson 格式的資料,具體格式見 https://geojson.org/,ECharts 使用 geoJSON格式的資料作為地圖的輪廓

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

初始化中國地圖

通過官網示例柏成了解了地圖相關的屬性及API,對ECharts地圖有了一個大概認知,接下來我們初始化一箇中國地圖,此時我們需要中國地圖的 geoJSON格式的資料,通過ECharts官網得知 地圖下載

ECharts 之前提供下載的向量地圖資料來自第三方,由於部分資料不符合國家《測繪法》規定,目前暫時停止下載服務。

好傢伙,看到官網通告我差點嗝屁了?,本來想用輪子 echarts3-chinese-map-drill-down 中的 geoJSON資料,結果發現註冊地圖用的部分原始 geoJSON資料亂碼了?,雖然不影響使用,強迫症患者表示不可以?,查閱了好久的資料,最終在碼雲上找到了中國所有行政區的GeoJson資料 - 中國 GeoJson 資料??? && github上意外發現了加強版GeoJson資料 最新中國省市區縣geoJSON格式地圖資料✨✨✨

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

註冊渲染地圖之後發現文字標籤位置並不理想,部分標籤偏移到了地圖之外,例如內蒙古,部分標籤揉擠作一團,例如北京天津河北,此時我們需要修改china.json原始 geoJSON資料,給每個省份的properties屬性下新增cp屬性,即文字居中位置,例如新疆維吾爾自治區資料,詳細china.json資料請移步 china-map-drill-down 檢視

 {
      "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],
			  ...
            ]
          ]
        ]
      }
    },
 }

噔噔噔噔???,這樣看著就舒服多了

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

自定義滑鼠事件

自定義單擊事件

點選某個區域高亮,滑鼠移出地圖後高亮並沒有消失,搞了好半天,竟是ECharts V5新版本的特性?,如果不想要此效果,安裝 ECharts V4 or V3 即可 npm i echarts@4 -S

// 繫結自定義單擊事件
bindOnClickChart () {
   this.myChart.on('click', params => {
      console.log(params)
   })
},

自定義右擊事件

首先要阻止預設右擊事件彈窗【圖片另存為,複製圖片 ... 】???,然後再自定義右擊事件,查閱 ECharts 官方API文件 ECharts - API - 滑鼠事件 得知右擊事件為:myChart.on('contextmenu', function (params) { })

// 繫結自定義右擊事件
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 會合並新的引數和資料,然後重新整理圖表。如果開啟動畫的話,ECharts 找到兩組資料之間的差異然後通過合適的動畫去表現資料的變化。

而我使用 V4 - 4.9.0 版本實際操作時發現,地圖層級之間毫無過渡動畫,生硬至極,what❓❓❓,難道地圖註冊registerMap不相容setOption動畫❗❗❗,不應該吧❓,不會吧❓,馬上就薅成?時,我隱隱感覺可能是ECharts版本的鍋,於是我更新了Echarts最新 V5 -5.0.2 版本npm i echarts@latest -S,重啟專案發現還是不行,重來,之後我將Echarts降級到了V3版本npm i echarts@3 -S,大功告成???

經親自嘗試,只要ECharts版本 <= 4.3.0,即帶下鑽動效

為什麼版本更新會把地圖下鑽的動效給去掉,很是不能理解,也可能是我太菜了,沒找到新版本地圖開啟動效的正確方式,如有大佬知道,請指點一二✨✨✨

原始碼

地圖下鑽demo程式碼:china-map-drill-down

相關文章