運用 D3.js 手把手繪製台灣地圖 & 標示資料
📋 目錄
實作練習介紹
🏆 2021年7月23日 — 8月8日適逢東京奧運
培訓好的運動員需要良好的場地!
目標:製作台灣地圖,並標上全國運動場館資料 🏊
此練習需具備基礎 D3.js 概念,若不清楚建議先看這篇:
🚪 D3.js 資料視覺化工具(上)
另外,也將運用 SVG 工具製圖,若不清楚建議先看這篇:
🚪 D3.js 資料視覺化工具(中)
匯入及處理資料集部分,若不清楚建議先看這篇:
🚪 D3.js 資料視覺化工具(下)
使用 D3.js 搭配台灣地圖資料,根據經緯度繪製到畫布上,再結合全國運動場館的資訊,標上運動場館的位置。提供 zoom 縮放功能,hover 在點上會出現客製 tooltip!
請先準備好一個 index.html 檔案,以及在資料夾同一層加入一個空的 index.js 檔案。 index.html 檔案完整程式碼如下:
準備好了,就開始實作吧 🚀
[實作] 繪製台灣地圖
準備台灣地圖資料,從政府資料開放平台取得台灣經緯度資料 🔍
下載 SHP 檔案,藉由地圖編輯器 Mapshaper 將檔案輸出 GeoJSON 檔案。檔名為:COUNTY_MOI_1090820.json (檔名請依真實情況調整),將檔案放入資料夾中。詳細步驟可以參考 ShawnL 撰寫的這篇文章 (感謝 ShawnL 🙌 )
開始繪製地圖,程式碼如下:
首先先選定 svg,綁定 g 以便於後續操作。d3.geoMercator()
表示用橫麥卡托的方式投影。d3 官方提供許多投影方式,可以參考這邊。 .center()
指定為台灣的座標,.scale()
設定放大的倍率。下方引入剛剛準備好的 json 檔案,將 data 印出來看一下:
看起來要的資料已經取到了!接著使用 topojson.feature()
是 topoJSON 去創造 GeoJSON object 的方法。查看一下取到的 geometries:
🔖 補充說明
1.GeoJSON:是一種對各種地理數據結構進行編碼的格式。GeoJSON支持下面幾何類型:點、線、面、多點、多線、多面和幾何集合。
2.TopoJSON:以 GeoJSON 為基礎,以拓樸學的科學基礎編碼而成的格式。原先描述地理訊息的邊緣,會以共同邊所表示,並且消除掉一些較為冗贅的地理資訊後而產生。
🔦 附上xcatliu(作者)撰寫的 GeoJSON 和TopoJSON 文章
接著把取到的資料繪製上去,程式碼如下:
其中加上county class,還有加上簡易版本的 tooltip,希望 hover 時可以出現相對應的縣市名稱。
在 index.html 加上 style 樣式,程式碼如下:
此時,開啟瀏覽器,畫面如下:
看起來很不錯呢!👏
[實作] 標記運動場館資料
準備台灣運動場館資料,先從全國運動場館資訊網取得場館資訊 🔍
下載 ODS 檔案,請自行轉為 CSV 檔案。檔名為:全國運動場館資訊.csv,將檔案放入資料夾中。(筆者撰寫時間取得最新資訊為 民國 110年 4月的資訊)
開始繪製地圖前,先講上方設定的 .county:hover style 以及縣市的tooltip 註解掉,因為標記場館不會用到。在原始 index.js 檔案加入以下程式碼:
查看一下 data 資訊如下:
此時,全國運動場館資訊已經標記上去。由於數量不少,幾個縣市的點很密集,希望可以增加畫布放大的功能。在 index.js 檔案最上面加上 d3.zoom
功能。
此時,畫布可以隨著使用者操作有放大縮小的功能!接下來希望在原點上標示出場館名稱。使用跟剛剛一樣的作法:
畫面可以看到已經有標示出場館的名稱 🎈
如果想要客製化自己的 tooltip,像是制定樣式、放更多資訊等等。可以藉由下方作法:
新增 tooltip id,下方加上 mouse 控制,藉由 opacity 控制出現或消失。另外 index.html 檔案 style 部分加上 custom_tooltop 樣式設定。
看起來非常完整!台灣地圖結合標示運動場館已完成 🎉
不過多 reload 幾次頁面,其實會發現有時候會先繪製地圖檔案,有時候會先繪製運動場檔案。面對這樣的情況,可以利用 async 及 await 實現非同步程式。修改後完整的程式碼如下:
修改之後,每一次 reload 都會先繪製地圖,再標示場館 🙆
🌟 大功告成了!
小結
具備 D3.js 基礎後,練習處理、介接不同型態的資料,搭配不同工具完成此地圖標記運動館實作。附上此練習的 GitHub 檔案連結 🔗 ,專案資料夾名稱:d3-practice-GYM
。分享筆者很喜歡的一句名言:
有任何指點或建議都可以在下方留言~🙏
🍡 Thanks for reading!