美國 1990 至 2018 恐攻事件|創作紀錄
歐嗨優~今天想跟大家分享最近用 d3.js 做的新作品 — 結合極座標氣泡圖和樹狀圖的自創圖表。(看作品,點這裡)
這次的創作過程比較不按常規。我不是從數據洞察開始思考圖表設計,而是心中先有了草圖才去尋找我需要的數據。
我很喜歡看不同大小、顏色的圓圓圈圈排列在一起,所以一直想挑戰用 D3.js 畫極座標氣泡圖(Polar Bubble Chart)。
初步構想是用圓形格線代表年份,直格線代表月份,網格之上再放置代表某種數據的圓圈。
數據
平常在網路上看到有趣或高品質的數據,我就會隨手記下來,並備註一兩個故事點子,所以這次很快就找到了適合的數據 — 馬里蘭大學提供的全球恐攻事件資料庫(GTD)。
這份數據記載 1970 到 2018 的全球恐攻事件,包括日期、地點、組織團體、死傷人數等。我把資料範圍縮小到「1990 年後發生在美國本土的恐攻事件」。
我也查閱其他紀錄恐攻事件的數據,和 GTD 的交叉比對後發現 GTD 未記載的漏網之魚,所以自己重拉了 Excel 手動補上。
數據處理得差不多後,我開始用 D3 一步步打造這個作品。
圖表
我跟著 Amelia Wattenberger 在 Fullstack D3 and Data Visualization 裡頭的範例,畫出背景格線。畫背景格線時的重點就是把抽象的年份和日期轉化成具象的座標。
例如下面這串程式碼就是把日期轉化為「圓圈上的一點」:
簡單解釋:你可以想像在畫布上放一個圓圈,把 1/1 到 12/31 的每一天化作一個個點放置在這個圓圈上。如果你仔細看上面的 dayAxisAngleScale,會發現我用了一個偷吃步的方法來轉化日期。我直接假設每個月的天數都是 31 天,沒有大小月之分。
最後一個 angleToCoorsScale 負責把弧度轉為 x-y 座標,概念就是我們每個人國高中就學過的三角函數啦!
接著我再把年份轉換為由小到大的「圓形格線」。
畫完背景格線後,就可以開始視覺化恐攻數據了。我讓每個圓圈代表一個事件,圓圈的大小代表死傷人數。「零死亡」或者「沒有死傷紀錄」的數據也一併被我繪製上去。
交互
遵循著 Schneiderman 的格言(”Overview first, zoom and filter, the details-on-demand”),我的大部分作品都是在揭開全局之後,給讀者自行探索的空間。
這次也是。我希望讀者滑過圓圈時可以看到更多相關資料。原先我打算直接繪製文字方塊在圓圈旁邊就好。但試了幾次後覺得剛硬的線條就是無法融入充滿圓圈的畫布上。我需要更「彈性、柔軟」的元素。最後我畫出了下面的草稿:
每次的恐攻事件背後都是不同的組織,他們的犯案動機遠比我們想像地複雜。所以我希望讀者滑到某個代表恐攻事件的圓圈時,相關的背景資訊能「像樹葉一樣延伸、展開」。
D3 能畫出類似的樹狀圖。但我很少看到有人把樹狀圖與其他圖形結合在一起,這意味著我必須調整一些參數,讓樹狀圖的「原點」跟代表恐攻事件的圓形有相同的 x-y 座標。
由於 D3 樹狀圖需要有「層級結構」的數據,所以我第一步先把資料改造成有 parent 和 children 的格式:
接著把改造後的資料餵給 d3.hierachy(),然後就能叫 d3.tree() 幫我們算出樹狀圖每個元素的相對位置了:
下一步就是重頭戲:自行調整參數,讓樹狀圖的「原點」跟代表恐攻事件的圓形有相同的 x-y 座標。我先找到被選取圓圈的圓心座標,如下:
再依上面的 cx、cy 去調整樹狀圖裡頭點和線的位置: