定量比例尺 :
数学上有函数的概念, 不是编程中所说的函数, 如线性函数, 指数函数, 对数函数等, 而指的是一个量随着另一个量的变化而变化. 例如有一下线性函数 : y=2x+1
该函数在二维坐标系中绘制出来的图形是一条直线, 如果限制 x 的范围为[0,2], 则可计算得到 y 的范围为[1,5].
x 的范围 [0,2] 称为该函数的定义域, y 的范围称为该函数的值域. 根据 x 计算得到 y 的方法称为对应法则. 定义域, 值域, 对应法则称为函数的三要素.
在数据可视化中, 常需要像上述函数一样, 将一个量转换为另一个量. D3 提供了这样的转换方法, 称为比例尺(scale).
我们现在所说的定量比例尺, 是指当定义域是连续的情况. 从 0~2 之间的所有值, 称为连续的值. 类似 0,1,2 这样的值, 称为离散的值
定量比例尺包括 : 线性比例尺, 指数比例尺, 对数比例尺, 量子比例尺, 分位比例尺和阈值比例尺.
按上面顺序, 首先先介绍线性比例尺 .
线性比例尺
线性比例尺 (Linear Scale) 是常用比例尺, 与线性函数类似, 计算线性的对应关系. 相关方法有:
- d3.scaleBand.linear() // 创建一个比例尺.
- linear(x) // 输入一个在定义域内的值 x, 返回值域内对应的值.
- linear.invert(y) // 输入一个在值域内的值, 返回定义域内对应的值.
- linear.domain([numbers]) // 设定或获取定义域
- linear.range([values]) // 设定或获取值域
- linear.rangeRound([values]) // 代替 range()使用的话, 比例尺的输出值会进行四舍五入的运算, 结果为整数.
- linear.clamp([boolean]) // 默认被设置为 false, 当该比例尺接受一个超出定义域范围内的值时, 依然能够按照同样的计算方法计算得到一个值, 这个值可能是超出值域范围的. 如果设置为 true, 则任何超出值域的范围的值, 都会被收缩到值域范围内.
- linear.nice([count]) // 将定义域的范围扩展成比较理想的形式. 例如, 定义域为 [0.50000543,0.899995433221], 则使用 nice() 之后, 其定义域变为 [0.5,0.9]. 对于 [0.500000543,69.99998888] 这样的定义域, 则自动将其变为[0,70].
- linear.ticks([count]) // 设定或获取定义域内具有代表性的值得数目. count 默认为 10, 如果定义域[0,70], 则该函数返回[0,10,20,30,40,50,60,70]. 如果 count 设置为 3, 则返回 [0,20,40,60]. 该方法主要用于选取坐标轴刻度.
- linear.tickFormat(count,[format]) // 用于设置定义域内具有代表性的值得表示形式, 如显示到小数点后两位, 使用百分比的形式显示, 主要用于坐标轴上.
以上方法中, linear(x),invert(),domain(),range()是基础方法, 使用形式看代码:
- var linear = d3.scale.linear()
- .domain([0,20]) // 设置定义域为[0,20]
- .range([0,100]) // 设置值域为[0,100]
- console.log(linear(10)) // 返回值 50
- console.log(linear(30)) // 返回值 150
- console.log(linear.invert(80)) // 返回值 16
用 linear()计算的结果是, 输出都是输入值得 5 倍. 而使用 linear.invert()时, 输出都是输入值得五分之一. 要注意的是, 倒数第二行, linear()接收了一个超出定义域范围的值 30, 结果还是正常输出其乘以 5 之后的值 150. 此输出值也超过了值域的范围如果不希望其超出范围, 可以使用 clamp(), 代码如下:
- linear.clamp(true)
- console.log(linear(30)) // 返回值 100
将 clamp()设置为 true 后, 超出值域的值会取值域的上下限作为输出. 对于输出的数值, 如果希望对其进行四舍五入, 要使用 rangRound()来设置:
- linear.rangeRound([0,100]);
- console.log(linear(13.33)) // 返回值 67
如果不用 rangeRound()重新设置值域, 则输出值为 66.649999999999, 其四舍五入后值为 67. 如果定义域中有无穷小数, 可用 nice(), 代码:
- linear.domain([0.123000000,0.488888888])
- .nice()
- console.log(linear.domain()) // 返回值[0.1,0.5]
- linear.domain([33.611111,45.97745])
- .nice()
- console.log(linear.domain()) // 返回值[33,46]
应用 nice()后, 定义域变成了比较工整的形式, 但是并不是四舍五入. 最后讲解 ticks()和 tickFormat()的用法, 它们主要是用在坐标轴上的. 看代码:
- var linear2 = d3.scale.linear()
- .domain([-20,20])
- .range([0,100])
- var ticks = linear2.ticks(5);
- console.log(ticks) // 返回值[-20, -10, 0, 10, 20]
- var tickFormat = linear2.tickFormat(5,"+");
- for (var i = 0; i < ticks.length ; i++){
- //ticks 数组中的每一个值, 都使用一次 tickFormat()函数
- ticks[i] = tickFormat(ticks[i])
- }
- console.log(ticks) // 返回值["-20", "-10", "+0", "+10", "+20"]
这段代码中, 比例尺的定义域为 [-20,20], 调用 ticks(5) 之后返回一个数组, 分别是该定义域内具有代表性的值. 然后, 调用 tickFormat(), 返回值是一个函数, 因此调用时要使用函数的调用方式. 最终结果是, ticks 变成了设定的格式. 此外设定的格式为 "+": 表示如果是正数, 则在前面添加一个加号, 负数则添加一个减号. 除此之外, 常用的格式还有 %,$ 等, 遵循迷你语言格式规范.
比例尺的 domain()和 range()最少放入两个数, 可以超过两个数, 但两者的数量必须相等, 放入三个数的情况如下, 代码:
- var scale = d3.scale.linear();
- scale.domain([0,20,40])
- .range([0,100,150]);
- console.log(scale(30)) // 返回值 125
这表示有两个线性函数, 当输入的值为 30 时, 属于 domain 的 20~40 的范围, 那么输出为 100~150 范围.
下一文章介绍指数比例尺和对数比例尺.
来源: https://www.cnblogs.com/littleSpill/p/10821332.html