在圖表當中不可或缺的除了基本的資料與圖表之外,另一項就是比例尺的部分。在 D3.js 中,開發者可以透過比例尺將一段範圍的某個數值對應到另一段範圍的數值,這麼做的好處在於我們可以將資料轉換成一個具有比例意義的圖表,並且依比例縮放成我們所要的大小而不是毫無比例根據的作圖。
線性比例尺 d3.scaleLinear
線性比例尺指的是一段連續的數值可以依照一個線性函數來換算出數值:
例如區間
[0,20]
依照y=2x
可以換算出[0, 40]
,因此假如今天有一個值為10
,我們便可以帶入函數y=2*10
來求出 Y 值為20
。
而使用方法很簡單,我們透過 D3.js 4版以後的語法 d3.scaleLinear
來創造一段比例尺,並由 domain()
定義範圍(如設為資料最大最小範圍),再使用 range()
定義一個取值的範圍(如圖表中的軸長),如此一來就可以將資料的大小比例對應到圖表中的 X 軸、Y 軸內:
1 | let dataset = [10, 40, 30, 20, 50] |
另一個以 Vue.js in D3.js 的例子:
1 | <div id="#app"> |
1 | let vm = new Vue({ |
顯示結果:
圖中可以看到 SVG 畫布 長高各為 200px
的情況,我們設定資料範圍為 0
至 50
(資料集最大值),並把輸出範圍設定為 0
至 200
,因此最後一筆資料 50
經由比例尺轉換後繪製出高度為 200
的矩形,可以看到確實撐滿了整個 SVG 的高。
由此範例可以看出比例尺在 D3.js 中潛力,像是 RWD 網頁透過 JavaScript 監聽視窗大小變動時,便可以藉由將視窗比例等等資訊傳遞進 D3.js 來調整比例尺,達到圖表縮放的功能。
而比例尺的功能除了簡單的依比例輸出外還有其他的 API 可供調整:
rangeRound()
:替換range()
使用,使最後輸出的數值會四捨五入到個位數。
1 | let dataset = [10, 40, 30, 20, 50] |
clamp()
:啟用後會將輸入超過範圍的數值,輸出時縮放為範圍的最大、最小值。
1 | let dataset = [10, 40, 30, 20, 50] |
nice()
:將定義範圍中的無窮小數捨去至合理的範圍,用以資料集當domain
範圍時若遇到無窮小數需要整理時可使用此函數。1
2
3
4
5
6let linear = d3
.scaleLinear()
.domain([0.62271947 , 0.13879428])
.range([0, 100])
linear.nice()
console.log(linear.domain()) // [0.65, 0.1]ticks()
:將比例尺的定義範圍切成數段,並且返回一個較有意義段落的陣列,用來製作座標軸數值非常方便。tickFormat()
:如同ticks
用法,但是可以在第二個傳送參數中定義返回的數值格式。1
2
3
4
5
6
7
8
9
10
11
12
13
14let dataset = [10, 40, 30, 20, 50]
let linear = d3
.scaleLinear()
.domain([0, d3.max(dataset)])
.range([0, 100])
let ticks = linear.ticks(2)
console.log(ticks) // [0, 20, 40]
let tickFormat = linear.tickFormat(0, '+')
for(i=0; i<ticks.length; i++){
ticks[i] = tickFormat(ticks[i])
}
console.log(ticks) // ["+0", "+20", "+40"]
以上是線性比例尺的用法,而除此之外還有像是 序列比例尺、量化比例尺、分位數比例尺等等不同的比例尺以供不同時機使用,這裡舉出一個比較常用到的比例尺來作為例子,往後圖表中若有用到其他比例尺時再仔細好好來介紹它們的細項,另外以下是 D3.js 比例尺在三版與四版的 API 差異表!
附註 D3.js 比例尺 3 版與 4 版差異補充
- d3.scale.linear ↦ d3.scaleLinear
- d3.scale.sqrt ↦ d3.scaleSqrt
- d3.scale.pow ↦ d3.scalePow
- d3.scale.log ↦ d3.scaleLog
- d3.scale.quantize ↦ d3.scaleQuantize
- d3.scale.threshold ↦ d3.scaleThreshold
- d3.scale.quantile ↦ d3.scaleQuantile
- d3.scale.identity ↦ d3.scaleIdentity
- d3.scale.ordinal ↦ d3.scaleOrdinal
- d3.time.scale ↦ d3.scaleTime
- d3.time.scale.utc ↦ d3.scaleUtc
明天颱風天只好跟貓咪一起在家繼續研究 D3.js 啦!附上黑黑美照一張: