比例函數(shù)(Scale functions)
Scale 函數(shù)是 JavaScript 函數(shù)毫捣,它們:接受輸入(通常是數(shù)字详拙、日期或類別)并返回一個值(例如坐標(biāo)帝际、顏色、長度或半徑)饶辙。它們通常用于將(或“映射”)數(shù)據(jù)值轉(zhuǎn)換為視覺變量(例如位置蹲诀、長度和顏色)。
- 構(gòu)建尺度
要創(chuàng)建線性比例弃揽,您可以使用:
let myScale = d3.scaleLinear();
myScale
.domain([0, 100])
.range([0, 800]);
myScale(0); // returns 0
myScale(50); // returns 400
myScale(100); // returns 800
- 縮放類型
D3 有大約 12 種不同的比例類型(scaleLinear脯爪、scalePow、scaleQuantise矿微、scaleOrdinal 等)痕慢,廣義上講它們可以分為 3 組:
具有連續(xù)輸入和連續(xù)輸出
具有連續(xù)輸入和離散輸出
-
具有離散輸入和離散輸出
-
具有連續(xù)輸入和連續(xù)輸出
- scaleLinear:使用線性函數(shù)y=mx+c在域和范圍內(nèi)進(jìn)行插值。
let linearScale = d3.scaleLinear() .domain([0, 10]) .range([0, 600]); linearScale(0); // returns 0 linearScale(5); // returns 300 linearScale(10); // returns 600
通常用于將數(shù)據(jù)值轉(zhuǎn)換為位置和長度涌矢。它們在創(chuàng)建條形圖掖举、折線圖和許多其他圖表類型時很有用。
輸出范圍也可以指定為顏色:
let linearScale = d3.scaleLinear() .domain([0, 10]) .range(['yellow', 'red']); linearScale(0); // returns "rgb(255, 255, 0)" linearScale(5); // returns "rgb(255, 128, 0)" linearScale(10); // returns "rgb(255, 0, 0)"
- scaleSqrt:對于按面積(而不是半徑)確定圓的大小很有用娜庇。
let sqrtScale = d3.scaleSqrt() .domain([0, 100]) .range([0, 30]); sqrtScale(0); // returns 0 sqrtScale(50); // returns 21.21... sqrtScale(100); // returns 30
- scalePow:是更通用的版本
scaleSqrt
塔次。該比例使用冪函數(shù)y=mxk +c進(jìn)行插值。指數(shù)k
使用.exponent()
名秀。
let powerScale = d3.scalePow() .exponent(0.5) .domain([0, 100]) .range([0, 30]); powerScale(0); // returns 0 powerScale(50); // returns 21.21... powerScale(100); // returns 30
- scaleLog:使用對數(shù)函數(shù)y=m*log(x)+b進(jìn)行插值励负,當(dāng)數(shù)據(jù)具有指數(shù)性質(zhì)時可能很有用。
let logScale = d3.scaleLog() .domain([10, 100000]) .range([0, 600]); logScale(10); // returns 0 logScale(100); // returns 150 logScale(1000); // returns 300 logScale(100000); // returns 600
- scaleTime:類似于匕得,
scaleLinear
除了域表示為日期數(shù)組熄守。(在處理時間序列數(shù)據(jù)時非常有用。)
timeScale = d3.scaleTime() .domain([new Date(2016, 0, 1), new Date(2017, 0, 1)]) .range([0, 700]); timeScale(new Date(2016, 0, 1)); // returns 0 timeScale(new Date(2016, 6, 1)); // returns 348.00... timeScale(new Date(2017, 0, 1)); // returns 700
- scaleSequential:用于將連續(xù)值映射到由預(yù)設(shè)(或自定義)插值器確定的輸出范圍耗跛。(插值器是一個函數(shù)裕照,它接受 0 到 1 之間的輸入并輸出兩個數(shù)字、顏色调塌、字符串等之間的插值晋南。)
let sequentialScale = d3.scaleSequential() .domain([0, 100]) .interpolator(d3.interpolateRainbow); sequentialScale(0); // returns 'rgb(110, 64, 170)' sequentialScale(50); // returns 'rgb(175, 240, 91)' sequentialScale(100); // returns 'rgb(110, 64, 170)'
還有一個插件d3-scale-chromatic,它提供了眾所周知的ColorBrewer配色方案羔砾。
- Clamping:默認(rèn)情況下當(dāng)輸入值超出域時负间,
scaleLinear
、scalePow
姜凄、scaleSqrt
政溃、scaleLog
、scaleTime
和scaleSequential
仍會計算态秧。
let linearScale = d3.scaleLinear() .domain([0, 10]) .range([0, 100]); linearScale(20); // returns 200 linearScale(-10); // returns -100
可以通過使用以下方法限制縮放功能董虱,以便輸入值保持在域內(nèi)
.clamp
:linearScale.clamp(true); linearScale(20); // returns 100 linearScale(-10); // returns 0
您可以使用
.clamp(false)
關(guān)閉。- Nice:如果域是根據(jù)實際數(shù)據(jù)自動計算的(例如,通過使用
d3.extent
)愤诱,則開始值和結(jié)束值可能不是整數(shù)云头。這不一定是個問題,但它可能看起來有點不整潔淫半。因此溃槐,D3.nice()
提供了一個刻度函數(shù),它將域四舍五入到“不錯”的舍入值科吭。
let data = [0.243, 0.584, 0.987, 0.153, 0.433]; let extent = d3.extent(data); let linearScale = d3.scaleLinear() .domain(extent) .range([0, 100]) .nice();
請注意昏滴,
.nice()
每次更新域時都必須調(diào)用。- Multiple segments:
scaleLinear
,scalePow
,scaleSqrt
,scaleLog
andscaleTime
通常由兩個值組成对人,但如果您提供 3 個或更多值谣殊,則會細(xì)分為多個段
let linearScale = d3.scaleLinear() .domain([-10, 0, 10]) .range(['red', '#ddd', 'blue']); linearScale(-10); // returns "rgb(255, 0, 0)" linearScale(0); // returns "rgb(221, 221, 221)" linearScale(5); // returns "rgb(111, 111, 238)"
Inversion:
-
該方法允許您在給定輸出
.invert()
值的情況下確定縮放函數(shù)的輸入值(假設(shè)縮放函數(shù)具有數(shù)值域):let linearScale = d3.scaleLinear() .domain([0, 10]) .range([0, 100]); linearScale.invert(50); // returns 5 linearScale.invert(100); // returns 10
-
具有連續(xù)輸入和離散輸出
- scaleQuantize:接受連續(xù)輸入并輸出由范圍定義的多個離散量。
let quantizeScale = d3.scaleQuantize() .domain([0, 100]) .range(['lightblue', 'orange', 'lightgreen', 'pink']); quantizeScale(10); // returns 'lightblue' quantizeScale(30); // returns 'orange' quantizeScale(90); // returns 'pink'
- scaleQuantile:將連續(xù)數(shù)字輸入映射到離散值规伐。域由數(shù)字?jǐn)?shù)組定義
let myData = [0, 5, 7, 10, 20, 30, 35, 40, 60, 62, 65, 70, 80, 90, 100]; let quantileScale = d3.scaleQuantile() .domain(myData) .range(['lightblue', 'orange', 'lightgreen']); quantileScale(0); // returns 'lightblue' quantileScale(20); // returns 'lightblue' quantileScale(30); // returns 'orange' quantileScale(65); // returns 'lightgreen'
- scaleThreshold:將連續(xù)數(shù)值輸入映射到范圍定義的離散值蟹倾。指定n-1 個域分割點匣缘,其中n是范圍值的數(shù)量(即range的數(shù)量)猖闪。
let thresholdScale = d3.scaleThreshold() .domain([0, 50, 100]) .range(['#ccc', 'lightblue', 'orange', '#ccc']); thresholdScale(-10); // returns '#ccc' thresholdScale(20); // returns 'lightblue' thresholdScale(70); // returns 'orange' thresholdScale(110); // returns '#ccc'
-
具有離散輸入和離散輸出
- scaleOrdinal:將離散值(由數(shù)組指定)映射到離散值(也由數(shù)組指定)。域數(shù)組指定可能的輸入值肌厨,范圍數(shù)組指定輸出值培慌。如果范圍數(shù)組比域數(shù)組短,則范圍數(shù)組將重復(fù)柑爸。
let myData = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] let ordinalScale = d3.scaleOrdinal() .domain(myData) .range(['black', '#ccc', '#ccc']); ordinalScale('Jan'); // returns 'black'; ordinalScale('Feb'); // returns '#ccc'; ordinalScale('Mar'); // returns '#ccc'; ordinalScale('Apr'); // returns 'black';
默認(rèn)情況下吵护,如果將不在域中的值用作輸入,則比例尺將隱式將該值添加到域中表鳍。
如果這不是所需的行為馅而,您可以使用以下命令為未知值指定輸出值
.unknown()
。-
scaleBand:有助于創(chuàng)建條形圖譬圣,同時考慮每個條形之間的間隔瓮恭。域被指定為一組值(每個波段一個值),范圍為波段的最小和最大范圍(例如條形圖的總寬度)厘熟。
實際上
scaleBand
會將范圍拆分為n 個帶區(qū)(其中n是域數(shù)組中的值的數(shù)量)屯蹦,并考慮在指定間隔的情況下計算條形圖的位置和寬度。
let bandScale = d3.scaleBand() .domain(['Mon', 'Tue', 'Wed', 'Thu', 'Fri']) .range([0, 200]); bandScale('Mon'); // returns 0 bandScale('Tue'); // returns 40 bandScale('Fri'); // returns 160
可以使用
.bandwidth()
訪問每個波段的寬度可以配置兩種類型的間隔:1.
paddingInner
它指定(作為帶寬的百分比)每個帶之間的填充量;2.paddingOuter
它指定(作為帶寬的百分比)第一個帶之前和最后一個帶之后的填充量- scalePoint:創(chuàng)建從一組離散值映射到指定范圍內(nèi)等距的點
let pointScale = d3.scalePoint() .domain(['Mon', 'Tue', 'Wed', 'Thu', 'Fri']) .range([0, 500]); pointScale('Mon'); // returns 0 pointScale('Tue'); // returns 125 pointScale('Fri'); // returns 500
可以使用法
.step()
訪問點之間的距離外部填充(間隔)可以指定為填充與點間距的比率绳姨。例如登澜,要使外部填充為點間距的四分之一,請使用值 0.25
-