完美地圖:使用 D3.js 製作精美的 Web 地圖

已發表: 2022-03-11

Data Driven Documents,或 D3.js,是“一個基於數據操作文檔的 JavaScript 庫”。 或者更簡單地說,D3.js 是一個數據可視化庫。 它是由 Mike Bostock 開發的,旨在彌合靜態數據顯示與交互式和動畫數據可視化之間的差距。

D3 是一個功能強大的庫,具有大量用途。 在本教程中,我將討論 D3 的一個特別引人注目的應用:地圖製作。 我們將討論構建有用且信息豐富的 web 地圖的常見挑戰,並展示在每種情況下,D3.js 如何為有能力的 JavaScript 開發人員提供使地圖看起來和感覺漂亮所需的一切。

D3.js 是做什麼用的?

D3.js 可以將任意數據綁定到文檔對像模型 (DOM),然後通過使用 JavaScript、CSS、HTML 和 SVG,對由該數據驅動的文檔進行轉換。 結果可以是簡單的 HTML 輸出,也可以是具有動態行為(如動畫、過渡和交互)的交互式 SVG 圖表。 所有的數據轉換和渲染都是在客戶端的瀏覽器中完成的。

在最簡單的情況下,D3.js 可用於操作 DOM。 這是一個簡單的示例,其中 D3.js 用於將段落元素添加到空文檔正文中,並帶有“Hello World”文本:

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>D3 Hello World</title> <script src="http://d3js.org/d3.v3.min.js"></script> </head> <body> <script type="text/javascript"> d3.select("body").append("p").text("Hello World"); </script> </body> </html>

然而,D3.js 的優勢在於它的數據可視化能力。 例如,它可用於創建圖表。 它可用於創建動畫圖表。 它甚至可以用於集成和動畫不同的連接圖表。

D3 用於 Web 地圖和地理數據可視化

但是 D3.js 不僅可以用於 DOM 操作,也可以用於繪製圖表。 D3.js 在處理地理信息方面非常強大。 操作和呈現地理數據可能非常棘手,但使用 D3.js 構建地圖非常簡單。

這是一個 D3.js 示例,它將根據以 JSON 兼容數據格式存儲的數據繪製世界地圖。 您只需要定義地圖的大小和要使用的地理投影(稍後會詳細介紹),定義一個 SVG 元素,將其附加到 DOM,並使用 JSON 加載地圖數據。 地圖樣式是通過 CSS 完成的。

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>D3 World Map</title> <style> path { stroke: white; stroke-width: 0.5px; fill: black; } </style> <script src="http://d3js.org/d3.v3.min.js"></script> <script src="http://d3js.org/topojson.v0.min.js"></script> </head> <body> <script type="text/javascript"> var width = 900; var height = 600; var projection = d3.geo.mercator(); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var path = d3.geo.path() .projection(projection); var g = svg.append("g"); d3.json("world-110m2.json", function(error, topology) { g.selectAll("path") .data(topojson.object(topology, topology.objects.countries) .geometries) .enter() .append("path") .attr("d", path) }); </script> </body> </html>
相關:邁向可更新的 D3.js 圖表

D3 的地理數據

對於本 D3.js 教程,請記住,地圖構建最適合 JSON 格式的數據,尤其是 GeoJSON 和 TopoJSON 規範。

GeoJSON 是“一種用於編碼各種地理數據結構的格式”。 它旨在表示離散的幾何對象,這些對像被分組為名稱/值對的特徵集合。

TopoJSON 是 GeoJSON 的擴展,它可以對拓撲進行編碼,其中幾何“從稱為弧的共享線段拼接在一起”。 TopoJSON 通過存儲地理特徵之間的關係信息而不僅僅是空間信息來消除冗餘。 因此,幾何圖形在幾何圖形共享特徵的情況下更加緊湊和組合。 這導致典型的 TopoJSON 文件比其 GeoJSON 等效文件小 80%。

因此,例如,給定一張地圖,其中幾個國家相互接壤,邊界的共享部分將在 GeoJSON 中存儲兩次,一次用於邊界兩側的每個國家。 在 TopoJSON 中,它將只有一行。

地圖庫:谷歌地圖和 Leaflet.js

今天,最流行的地圖庫是谷歌地圖和傳單。 它們旨在快速輕鬆地在網絡上獲取“滑地圖”。 “Slippy maps”是一個術語,指的是現代 JavaScript 驅動的 web 地圖,它允許在地圖上進行縮放和平移。

Leaflet 是 Google 地圖的絕佳替代品。 它是一個開源 JavaScript 庫,旨在製作適合移動設備的交互式地圖,並考慮到簡單性、性能和可用性。 Leaflet 在利用互聯網上可用的大量基於柵格的地圖時處於最佳狀態,並帶來了使用平鋪地圖及其演示功能的簡單性。

當與 D3.js 的數據操作功能結合使用時,Leaflet 可以非常成功地使用,並且可以將 D3.js 用於基於矢量的圖形。 將它們結合在一起可以在兩個庫中發揮出最好的效果。

谷歌地圖更難與 D3.js 結合,因為谷歌地圖不是開源的。 可以同時使用 Google Maps 和 D3,但這主要限於在 Google Maps 背景地圖上使用 D3.js 覆蓋數據。 如果沒有黑客攻擊,更深層次的集成是不可能的。

投影 - 超越球形墨卡托

如何將 3 維球形地球的地圖投影到 2 維表面上的問題是一個古老而復雜的問題。 為地圖選擇最佳投影是每個 web 地圖的重要決定。

在我們上面的簡單世界地圖 D3.js 教程中,我們通過調用d3.geo.mercator()來使用球形墨卡托投影坐標系。 此投影也稱為 Web Mercator。 谷歌在推出谷歌地圖時推廣了這種投影。 後來,其他網絡服務也採用了投影,即 OpenStreetMap、Bing Maps、Here Maps 和 MapQuest。 這使得 Spherical Mercator 成為在線滑圖的非常流行的投影。

所有映射庫都支持開箱即用的球形墨卡托投影。 如果您想使用其他投影,則需要使用例如 Proj4js 庫,它可以進行從一個坐標係到另一個坐標系的任何轉換。 對於 Leaflet,有一個 Proj4Leaflet 插件。 就谷歌地圖而言,什麼都沒有。

D3.js 將製圖投影提升到一個全新的水平,內置支持許多不同的地理投影。 D3.js 將地理投影建模為完整的幾何變換,這意味著當直線投影到曲線時,D3.js 應用可配置的自適應重採樣來細分線並消除投影偽影。 Extended Geographic Projections D3 插件使支持的投影數量超過 40 個。甚至可以使用d3.geo.projectiond3.geo.projectionMutator創建一個全新的自定義投影。

柵格地圖

如前所述,D3.js 的主要優勢之一是處理矢量數據。 要使用柵格數據,可以選擇將 D3.js 與 Leaflet 結合使用。 但也有一個選項可以使用 d3.geo.tile 僅使用 D3.js 來創建滑動地圖。 即使僅使用 D3.js,人們也可以使用柵格地圖做出令人驚奇的事情。

即時矢量操作

經典製圖的最大挑戰之一是地圖泛化。 您希望擁有盡可能詳細的幾何圖形,但這些數據需要適應顯示地圖的比例。 數據分辨率太高會增加下載時間並減慢渲染速度,而分辨率太低會破壞細節和拓撲關係。 使用矢量數據的易滑地圖可能會遇到地圖泛化的大問題。

一種選擇是預先進行地圖泛化:擁有不同分辨率的不同數據集,然後針對當前選擇的比例顯示適當的數據集。 但這會增加數據集,使數據維護複雜化,並且容易出錯。 然而,大多數映射庫僅限於此選項。

更好的解決方案是動態進行地圖泛化。 D3.js 又來了,它具有強大的數據處理功能。 D3.js 允許在瀏覽器中進行行簡化。

我想要更多!

D3.js 不易掌握,學習曲線陡峭。 需要熟悉很多技術,即 JavaScript 對象、jQuery 鍊式語法、SVG 和 CSS,當然還有 D3 的 API。 最重要的是,需要有一點設計技巧才能最終創造出漂亮的圖形。 幸運的是,D3.js 有一個很大的社區,有很多資源可供人們挖掘。 這些教程是學習 D3 的一個很好的起點。

如果您喜歡通過查看示例來學習,Mike Bostock 在他的網頁上分享了 600 多個 D3.js 示例。 所有 D3.js 示例都有用於版本控制的 git 存儲庫,並且是可分叉、可克隆和可註釋的。

如果您使用 CartoDB,您會很高興聽到 CartoDB 讓 D3 地圖變得輕而易舉。

最後,為了一點獎勵,這是我最喜歡的例子之一,展示了 D3 的驚人能力:

  • earth,一個使用 D3.js 製作的全球動畫 3D 風圖。 Earth 是全球天氣狀況的可視化,基於國家環境預測中心、NOAA / 國家氣象局的超級計算機做出的天氣預報並轉換為 JSON。 您可以自定義顯示的數據,例如風速讀數的高度、更改疊加數據,甚至更改地球投影。
相關:針對 Web 開發人員的最佳在線製圖工具調查:路線圖的路線圖