比例尺是可视化中一项基本任务的便捷抽象:将抽象数据的维映射到视觉表示。尽管最常用于对定量数据进行位置编码,例如将以米为单位的测量值映射到散点图中点的像素位置,但刻度实际上可以表示任何位置编码,例如发散的颜色,笔划宽度或符号大小。
比例尺常用方法:
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]
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
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
沿两个相反方向(正负,顶部和底部)行进可视化。定义域包含三个值:两个极端和一个中心点。分度标度的默认域为[0,0.5,1],习惯将其设置为[–1、0、1]或[最小,中性,最大]。
构造一个定义域和值域一样的比例尺。如果未指定范围,则默认为[0,1]。
定义域的值被强制为日期而不是数字,并且取反也返回日期。
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 (中国标准时间)
定义域和内插器函数或数组构造的比例尺。如果未指定domain,则默认为[0,1]。如果未指定插值器,则默认为标识函数。当应用时,将使用通常在[0,1]范围内的值调用内插器,其中0表示最小值,而1表示最大值。
提供了双对称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);
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"
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
创建直方图的好帮手。如果未指定domain,则默认为空域。如果未指定range,则默认为单位范围[0,1]。scaleBand会将range划分为n个bandwidth(n是domain数组的数值个数)并且在考虑padding的情况下计算出每个bandwidth的位置和宽度.
range与rangeBand 、paddingInner和outerPadding的关系式:
range = N bandwidth + (N-1)paddingInner + 2 * paddingOuter;
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)
将离散的输入数值映射为在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