比例尺是可視化中一項基本任務的便捷抽象:將抽象數據的維映射到視覺表示。儘管最常用於對定量數據進行位置編碼,例如將以米爲單位的測量值映射到散點圖中點的像素位置,但刻度實際上可以表示任何位置編碼,例如發散的顏色,筆劃寬度或符號大小。
1. 比例尺
比例尺常用方法:
- 給定比例尺一個定義域中的值,返回其對應值域中的值。因爲是連續的,即使給定的是定義域範圍外的也可以返回對應的值。
- .invert(value) 給定值域中的值返回對應的定義域中的值
- .domain([domain]) 設置定義域,該數組必須包含兩個或多個元素。如果給定數組中的元素不是數字,則將其強制爲數字。
- .range([range]) 設置值域,該數組必須包含兩個或多個元素。與定義域不同,給定數組中的元素不必爲數字。
- .clamp(boolean) 設置值域是否閉合,默認不閉合。當值域閉合時,假設插值結果在值域之外。會取值域的邊界值。
- .ticks([count]) 從定義域中取出有代表性的值。通經常使用於座標軸刻度的選取。
- .ticksFormat([count,[format]) 設置刻度的顯示樣式。
- .copy() 複製這個比例尺。
- .nice() 擴展定義域範圍使定義域更規整。
var four = d3
.scaleBand() // 序數比例尺,默認情況下,給定長度的連續定義域([start, end]),
.domain([1, 2, 3, 4])
.range([0, 100])
console.log(four(-1)); // undefined
console.log(four(1)); // 0
console.log(four(2)); // 25
console.log(four(2.5)); // undefined
console.log(four(3)); // 50
console.log(four(4)); // 75
console.log(four(5)); // undefined
var x = d3.scaleLinear()
.domain([5, 16])
.range([0, 260]);
console.log(x(4));
console.log(x(15));
console.log(x.invert(-23.636363636363637)); // 3.9999999999999996
console.log(x.invert(236.36363636363635)); // 15
x.clamp(true); // 設置邊界
x.unknown()
console.log(x(-10));
console.log(x(20));
var ticks = x.ticks(6),
tickFormat = x.tickFormat(6, "+%");
console.log(ticks.map(tickFormat)); // ["+600%", "+800%", "+1000%", "+1200%", "+1400%", "+1600%"]
var linear = d3.scaleLinear().domain([0, 81]).rangeRound([0, 210]).clamp(true);
console.log(linear(95)); // 100
console.log("調用nice方法前" + linear.ticks(5)); // 0,20,40,60,80
console.log("調用nice方法後" + linear.nice().ticks(9)); // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
2 d3.scaleLinear 線性比例尺
d3.scaleLinear 其函數爲y = mx + b.
// 線性比例尺y = kx + b
var linear = d3.scaleLinear()
.domain([min, max]) // 設置定義域
.range([0, 300]); // 設置值域
console.log(linear(0.9)) ; //返回 0
console.log(linear(1.8)) ; //返回 149.99999999997
console.log(linear(2.7)) ; //返回 300
3 d3.scalePow 指數比例尺
var powerScale = d3.scalePow()
.exponent(0.5) // 定義指數
.domain([0, 100]) // 定義底數
.range([0, 30]); // 定義值域
console.log(powerScale(0)); // returns 0
console.log(powerScale(50)); // returns 21.21...
console.log(powerScale(100)); // returns 30
4 d3.scaleSqrt 開方比例尺
5 d3.scaleLog 對數比例尺
6 d3.scaleDiverging 發散尺
沿兩個相反方向(正負,頂部和底部)行進可視化。定義域包含三個值:兩個極端和一箇中心點。分度標度的默認域爲[0,0.5,1],習慣將其設置爲[–1、0、1]或[最小,中性,最大]。
7 d3.scaleIdentity
構造一個定義域和值域一樣的比例尺。如果未指定範圍,則默認爲[0,1]。
8 d3.scaleTime 線性時間變換
定義域的值被強制爲日期而不是數字,並且取反也返回日期。
var x = d3.scaleTime()
.domain([new Date(2020, 1, 1), new Date(2020, 4, 22)]) // 注意月是從0開始計數的
.range([0, 960]);
var x1 = x(new Date(2020, 2, 1, 0));
var x2 = x(new Date(2020, 4, 21, 0));
var x3 = x(new Date(2020, 4, 22, 0));
var x4 = x.invert(0);
var x5 = x.invert(1000);
console.log(x1); // 0
console.log(x2); // 948.2926829268292
console.log(x3); // 960
console.log(x4); // Sat Feb 01 2020 00:00:00 GMT+0800 (中國標準時間)
console.log(x5); // Mon May 25 2020 10:00:00 GMT+0800 (中國標準時間)
9 d3.scaleSequential 順序比例尺
定義域和內插器函數或數組構造的比例尺。如果未指定domain,則默認爲[0,1]。如果未指定插值器,則默認爲標識函數。當應用時,將使用通常在[0,1]範圍內的值調用內插器,其中0表示最小值,而1表示最大值。
10 d3.scaleSymlog
提供了雙對稱log轉換。它的定義域可以跨越幾個數量級,具有負值和正值。參數**.constant(num)**可以設置(或讀取)斜率,其值默認爲1。
// 歷史事件軸
days = [
{ l: "宇宙大爆炸", v: -13.8e9 * 365.24 },
{ l: "恐龍滅絕", v: -65e6 * 365.24 },
{ l: "羅馬建國", v: -(800 + 2019) * 365.24 },
{ l: "去年", v: -365 },
{ l: "昨天", v: -1 },
{ l: "現在", v: +0 },
{ l: "明天", v: +1 },
{ l: "明年", v: +365 },
{ l: "2200年", v: +365.24 * 91 },
{ l: "UNSC無盡號", v: +700 * 365.24 },
{ l: "太陽消亡", v: 6e9 * 365 }
]
const scale = d3.scaleSymlog() // 設置比例尺
.domain(d3.extent(days, d => d.v)) // d3.extent - d3.extent(array),把數組的最小最大值放在一個數組裏返回
.constant(0.1)
.range([1, 950]);
const svg = d3.select("svg") // 設置畫布
.attr("width", 1000)
.attr("height", 100)
.attr("style", "outline: 1px solid red;");
svg.append("line") // 劃線
.attr("x1", scale.range()[0])
.attr("x2", scale.range()[1])
.attr("y1", 50)
.attr("y2", 50)
.attr("stroke", "#999");
const g = svg.selectAll("g")
.data(days)
.join("g")
// 平移操作,2個參數,第一個參數是向右平移的像素,第二個是向下平移的像素。
.attr("transform", d => `translate(${scale(d.v)}, 50)`);
g.append("circle")
.attr("r", 4)
.attr("fill", d => (d.l === "現在" ? "red" : "black"))
.attr("transform", "translate(4, 0)");
g.append("text")
.attr("y", (_val, i) => -8 + 30 * (i % 2))
.attr("x", 1)
.attr("font-size", 10)
.text(d => d.l);
11 d3.scaleQuantize 量化比例尺
var color = d3.scaleQuantize()
.domain([0, 1]) // 默認定義域爲[0, 1]
.range(["brown", "steelblue"]);
var c1 = color(0.49);
var c2 = color(0.51); // "steelblue"
var c3 = color(1.5);
console.log(c1); // "brown"
console.log(c2); // "steelblue"
console.log(c3); // "steelblue"
12 d3.scaleThreshold
13 d3.scaleOrdinal
var index = [0, 1, 2, 3, 4];
var color = ["red", "blue", "green", "yellow", "black"];
var ordinal = d3.scaleOrdinal()
.domain(index)
.range(color);
console.log(ordinal(0)) ;//返回 red
console.log(ordinal(1)) ;//返回 red
console.log(ordinal(2)) ;//返回 red
console.log(ordinal(3)) ;//返回 green
console.log(ordinal(4)) ;//返回 black
console.log(ordinal(5)) ;//返回 red
console.log(ordinal(6)) ;//返回 red
console.log(ordinal(7)) ;//返回 black
14 d3.scaleBand
創建直方圖的好幫手。如果未指定domain,則默認爲空域。如果未指定range,則默認爲單位範圍[0,1]。scaleBand會將range劃分爲n個bandwidth(n是domain數組的數值個數)並且在考慮padding的情況下計算出每個bandwidth的位置和寬度.
- .align([align])
如果指定align,則將對齊設置爲指定的值,該值必須在[0,1]範圍內。如果未指定align,則返回當前對齊方式,默認爲0.5。對齊方式指定外部填充在範圍內的分佈方式。值爲0.5表示外部填充應該在第一個頻段之前和最後一個頻段之後平均分配;即,頻段應在範圍內居中。可以使用0或1的值將頻段移到一側,例如將其放置在軸附近。
config = ({
domain: ["A", "B", "C","D","E"], //
paddingInner: 0.1, //
paddingOuter: 0.2, //
round: true, //
align: 0.5, //
range: [100, 800]
});
scale = d3.scaleBand()
.domain(config.domain)
.range(config.range)
.paddingInner(config.paddingInner)
.paddingOuter(config.paddingOuter)
.align(config.align)
.round(config.round)
15 d3.scalePoint
將離散的輸入數值映射爲在range內等距的點
var pointScale = d3.scalePoint()
.domain(['a', 'b', 'c', 'd', 'e'])
.range([0, 100]);
pointScale('a'); // 0
pointScale('b'); // 20
pointScale('e'); // 100
pointScale('w'); // undefined