當前內容所在位置:
- 第五章 餅圖布局與堆疊布局 ??
- 5.1 餅圖和環形圖的創建 ??
- 5.1.1 準備階段(一)
- 5.1.2 餅圖布局生成器(二)
- 5.1.3 圓弧的繪制(三) ??
- 5.1.4 數據標簽的添加(四)
文章目錄
- 5.1.4 數據標簽的添加 Adding labels
《D3.js in Action》全新第三版封面
譯者按
繼上一小節利用全新的 D3 餅圖布局實現圓弧的繪制后,這一節再趁熱打鐵,看看如何從增強圖表的可讀性出發,再進行一些細節調整。
5.1.4 數據標簽的添加 Adding labels
第四章曾經提過,餅圖理解起來偶爾也會很費勁,因為人的大腦并不擅長將角度值轉為對應的比例大小。為此,可以通過在每段圓弧的中心添加一個表示對應百分數的數據標簽,旨在增強環形圖的可讀性,就像之前在第四章中實現的環形圖那樣。
如代碼清單 5.5 所示,我們稍微修改了一下用于生成圓弧部分的代碼(根據代碼清單 5.4)。首先利用 D3 數據綁定機制新增一個 SVG 分組而非路徑元素 path
。然后再將 path
元素(用于繪制圓弧)和 SVG 文本元素(代表標簽)添加到剛才的分組元素內。由于父級元素會將綁定的數據傳給它的子級,因此在繪制圓弧與數據標簽時可以直接訪問到綁定的數據項。
與上一章類似,這里同樣通過調用圓弧生成器來繪制圓弧。至于數據標簽的具體內容,則需要算出每段圓弧對應的比例或百分比。該比值可以通過圓弧終止角減去起始角、并將結果除以 2π
(即一個整圓的弧度值)算得。注意,這里用到了括號表示法(即 d["percentage"]
)將百分比值存入綁定數據項。當需要對不同屬性進行相同的計算時,這個操作技巧會非常實用,可以避免大量的重復運算。要返回數據標簽的文本內容,需要將算得的百分數傳入格式化函數 d3.format(".0%")
中,得到一個四舍五入后的結果,然后在末尾追加一個百分號即可。
每段圓弧的形心,即數據標簽放置的具體位置,也是應用與上一章相同的方法求取。在設置數據標簽的 x
屬性(attribute)時,需要提前算出對應形心的坐標(具體用法詳見第 4 章)并存入綁定數據項中(即 d[""centroid]
)。這樣在設置 y
屬性的值時,就能直接通過 d.centroid
拿到圓弧形心的坐標數組了。
為了確保數據標簽在圓弧形心位置居中對齊(包括水平及垂直方向),需要分別將其 text-anchor
屬性和 dominant-baseline
屬性指定為 middle
。同時還要利用 fill
屬性將文字顏色設置為白色、字號設為 16px
、字體粗細為 500
,以進一步提高文本標簽的可讀性。
保存代碼并重新加載示例頁面,會發現數據標簽在大段圓弧上顯示良好,但在圓弧較短時根本看不清楚讀數。在專業級可視化項目中,可以通過將圓弧較短的標簽移至環形圖外圍來解決這個問題。在本例中,我們只需在百分比值小于 5% 時,將其 fill-opacity
的屬性值設為 0
即可,這樣就實現了數據標簽的隱藏。最終效果如圖 5.8 所示。
代碼清單 5.5 在每段圓弧的形心位置添加數據標簽(詳見 donut-charts.js
文件)
const arcs = donutContainer.selectAll(`.arc-${year}`).data(annotatedData).join("g") // 利用數據綁定機制添加 SVG 分組元素而非 path 元素.attr("class", `arc-${year}`);arcs // 在每個分組內添加一個 path 元素,并調用圓弧生成器來繪制圓弧。然后利用顏色比例尺設置其 fill 屬性值.append("path") .attr("d", arcGenerator) .attr("fill", d => colorScale(d.data.format)); arcs.append("text") // 再給每個分組添加一個 text 文本元素.text(d => {d["percentage"] = (d.endAngle - d.startAngle) // 計算每段圓弧的百分數占比作為文本標簽的值,并存入綁定數據項中(d["percentage"])/ (2 * Math.PI); return d3.format(".0%")(d.percentage); }).attr("x", d => { // 獲取每段圓弧的形心位置并存入綁定數據項,然后分別用于數據標簽 x 與 y 屬性的賦值d["centroid"] = arcGenerator.startAngle(d.startAngle).endAngle(d.endAngle).centroid();return d.centroid[0];}) .attr("y", d => d.centroid[1]).attr("text-anchor", "middle").attr("dominant-baseline", "middle").attr("fill", "#f6fafc")// 隱藏圓弧上百分比小于 5% 的數據標簽.attr("fill-opacity", d => d.percentage < 0.05 ? 0 : 1) .style("font-size", "16px").style("font-weight", 500);
【圖 5.8 添加了百分比數據標簽的環形圖效果】
最后,還需要將環形圖的中心位置用一個文本標簽來顯示其代表的年份。同理,這可以通過給每個環形圖容器添加一個 text
文本元素來實現。由于當前仍處于年份數組的 For 循環中,因此可以直接將當前年份設為標簽的文本內容。此外,由于環形圖容器已經位于圖標的中心位置,文本元素會自動定位到指定為止,我們要做的僅僅是將其 text-anchor
屬性和 dominant-baseline
屬性指定為水平和垂直居中即可。最終效果如圖 5.9 所示。
donutContainer.append("text").text(year).attr("text-anchor", "middle").attr("dominant-baseline", "middle").style("font-size", "24px").style("font-weight", 500);
至此,示例頁環形圖部分的實現就大功告成啦!
【圖 5.9 繪制完成的帶年份標簽的環形圖最終效果】
最后再來復盤一下 D3 餅圖或環形圖的繪制流程,如圖 5.10 所示。首先,利用 D3 的布局函數 d3.pie()
對數據進行預處理,得到含有各片段角度值信息的帶注解的數據集;其次,利用圓弧生成器來繪制圓弧,該函數會從帶注解的數據集中提取相關的角度值信息,并返回每個路徑元素的 d
屬性值;最后,我們通過添加數據標簽來提高圖表的可讀性,需要用到 SVG 的 text
文本元素。
【圖 5.10 創建 D3 餅圖或環形圖的主要步驟】
另附:專欄文章連載期間 完全免費,后續 不排除 調整為收費專欄。對 D3.js 感興趣、或者想要從零開始徹底掌握 D3 的朋友們強烈建議及時關注本專欄,一起學習交流,共同進步!
目前譯好的其他章節內容如下(可進入專欄查看詳情):
- 第一部分 D3.js 基礎知識
- 第一章 D3.js 簡介(已完結)
- 1.1 何為 D3.js?
- 1.2 D3 生態系統——入門須知
- 1.3 數據可視化最佳實踐(上)
- 1.3 數據可視化最佳實踐(下)
- 1.4 本章小結
- 第二章 DOM 的操作方法(已完結)
- 2.1 第一個 D3 可視化圖表
- 2.2 環境準備
- 2.3 用 D3 選中頁面元素
- 2.4 向選擇集添加元素
- 2.5 用 D3 設置與修改元素屬性
- 2.6 用 D3 設置與修改元素樣式
- 2.7 本章小結
- 第三章 數據的處理(已完結)
- 3.1 理解數據
- 3.2 準備數據
- 3.3 將數據綁定到 DOM 元素
- 3.3.1 利用數據給 DOM 屬性動態賦值
- 3.4 讓數據適應屏幕
- 3.4.1 比例尺簡介(上篇)
- 3.4.2 線性比例尺(中篇)
- 3.4.2.1 基于 Mocha 測試 D3 線性比例尺(DIY 實戰)
- 3.4.3 分段比例尺(下篇)
- 3.4.3.1 使用 Observable 在線繪制 D3 條形圖(DIY 實戰)
- 3.5 加注圖表標簽(上篇)
- 3.5.1 人物專訪:Krisztina Sz?cs(下篇)
- 3.6 本章小結
- 第四章 直線、曲線與弧線的繪制
- 4.1 坐標軸的創建(上篇)
- 4.1.1 D3 中的邊距約定(中篇)
- 4.1.2 坐標軸的生成(中篇)
- 4.1.2.1 比例尺的聲明(中篇)
- 4.1.2.2 坐標軸的添加(下篇)
- 4.1.2.3 軸標簽的添加(下篇)
- 4.2 D3 折線圖的繪制
- 4.2.1 直線生成工具的使用
- 4.2.2 對數據點作曲線插值處理
- 4.3 D3 面積圖的繪制
- 4.3.1 面積圖生成工具的用法
- 4.3.2 用標簽提高圖表的可讀性
- 4.4 D3 弧形圖的繪制
- 4.4.1 D3 中的極坐標系
- 4.4.2 圓弧生成器的使用
- 4.4.3 圓弧形心的計算
- 4.4.4 人物專訪:Francis Gagnon、Patricia Angkiriwang 和 Olivia Gélinas
- 4.5 本章小結