上一章介绍了阈值比例尺:https://www.cnblogs.com/littleSpill/p/10825038.html。到目前所有的定量比例尺已经介绍完了。

现在给大家介绍一下序数比例尺

定量比例尺的定义域都是连续的,值域有连续的也有离散的。序数比例尺(Ordinal Scale)的定义域和值域都是离散的。
 
现实中会有这样的需求,通过输入一些离散的值(如名称、序号、ID等),要得到另一些离散的值(如颜色等),这种时候就要考虑序数比例尺了。
序数比例尺的方法有:
 
d3.scaleBand.ordinal()
//构建一个序数比例尺
 
ordinal(x)
//输入定义域内一个离散值,返回值域内一个离散值。
 
ordinal.domain([values])
//设定或获取定义域
 
ordinam.range([values])
//设定或获取值域
 
ordinal.rangePoints(interval[,padding])
//代替range()设定的值域。接受一个连续的区间,然后根据定义域中离散值的数量将其分段,分段值即作为值域的离散值。
 
ordinal.rangeRoundPoints(interval,[,padding])
//和rangePoints()一样,但是结果会取整数。
 
ordinal.rangeBands(interval[,padding[,outerPadding]])
//代替range()设定值域。与rangePoints()一样,也是接收一个连续的区间,然后根据定义域中离散值得数量将其分段,但是其分段方法是不同的。
 
ordinal.rangeRoundBands(interval[,padding,outerPadding])
//和rangeBands()一样,但是会将结果取整。
 
ordinal.rangBand()
//返回使用rangeBands()设定后每一段的宽度、
 
ordinal.rangeExtend()
//返回一个数组,数组里存有值域的最大值和最小值
 
首先举个例子,定义一个序数比例尺,定义域设置为[1,2,3,4,5]五个离散值,值域设置为[10,20,30,40,50]五个离散值。看代码:
 
 1 var ordinal = d3.scale.ordinal()
 2                         .domain([1,2,3,4,5])
 3                         .range([10,20,30,40,50])
 4
 5         console.log(ordinal(1))         //输出10
 6
 7         console.log(ordinal(3))         //输出30
 8
 9         console.log(ordinal(5))         //输出50
10
11         console.log(ordinal(8))         //输出10
由此可见,1对应10,3对应30,5对应50,与定义域和值域排列次序一致。但是最后一行输入值为8,不在定义域内,输出值为10.先不管其输出值有没有道理,总之不要输入超过定义域的值。
 
但是,如果一个一个地设定值域的值,使其对应到定义域上,比较麻烦。D3提供了rangePoints()rangRoundPoints()用于解决此问题:只要接收一个连续的区间,即可自动计算出相应的离散值。这两个方法都有两个参数:intervalpaddinginterval是区间,padding是边界部分留下的空白。可省略,默认为0。意义如图:
 
D3.js比例尺 序数比例尺(v3版本)-LMLPHP
 
如上图,rnage.interval就是rangePoints()的第一个参数interval的值,是一个范围,如[0,100]。padding是第二个参数:step是根据定义域的数值计算得到的值。图中圆圈所代表的点,就是计算得到的离散值。看代码:
 
 1  var ordinal2 = d3.scale.ordinal()
 2                         .domain([1,2,3,4,5])
 3                         .rangePoints([0,100])
 4
 5         console.log(ordinal2.range())        //输出 [0, 25, 50, 75, 100]
 6
 7         console.log(ordinal2(1))             //输出0
 8
 9         console.log(ordinal2(3))             //输出50
10
11         console.log(ordinal2(5))             //输出100
上面代码的序数比例尺中,rangePoints()的第一个参数为[0,100],第二个参数省略。对应到上图的话,则range interval等于[0,100],padding等于0,step等于25.因此,得到了 上面输出的5个离散值,与定义域的5个值是一一对应的。下面来看看padding有设定值的情况:
 
1    ordinal2.rangePoints([0,100],5)
2
3         console.log(ordinal2.range())        //输出[27.77777777777778, 38.888888888888886, 50, 61.11111111111111, 72.22222222222223]
这样设定后,padding等于5,step等于11.111111。则step*padding/2等于27.77777,正是输出数组的第一个值。这样,有时输出的数组是无穷小数,如果希望其都是整数,可用rangeRoundPoints()。代码 :
 
1    ordinal2.rangeRoundPoints([0,100],5)
2
3         console.log(ordinal2.range())        //输出[28, 39, 50, 61, 72]结果被四舍五入取整了
D3还提供了rangeBands()rangRouondBands()。与rangePoints()稍有不同的是,其接收三个参数:intervalpaddingouterPadding。各参数的意义如下图。range interval是范围。paddingouterPadding分别是内部和边界的空白的参数,默认为0。rangePoints方框中的rangBand,表示一个区间。而该区间的起点,就是得到的离散值。图:

D3.js比例尺 序数比例尺(v3版本)-LMLPHP

rangeBand()可返回rangeBand的值。要注意函数名的区别。rangBands()后面有s,用于设置值域。rangeBand()后面没有s,用于返回图中rangBand的值,举个例子:
 
1 var bands = d3.scale.ordinal()
2                     .domain([1,2,3,4,5])
3                     .rangeBands([0,100])
4
5         console.log(bands.range())          //输出[0, 20, 40, 60, 80]
6
7         console.log(bands.rangeBand())      //输出20
这段代码中,paddingouterPadding都没有设定,默认为0.计算可得,rangeBand为20,值域有五个离散的值,分别是每一个rangeBand区域的起点,即[0,20,40,60,80]。下面试一下设定了空白的情况:
 
1 bands.rangeBands([0,100],0.5,0.2)
2
3         console.log(bands.range())          //输出[4.081632653061225, 24.489795918367346, 44.89795918367347, 65.3061224489796, 85.71428571428571]
4
5         console.log(bands.rangeBand())      //输出10.204081632653061
这段代码中,padding为0.5,outerPadding为0.2.对应上图中,step计算的值约等于20,因此左右边界的空白step*outerPadding约等于4即输出数组的第一个值。step*padding约等于10,即每个rangBand之间的空白长度。
 
D3提供了几个获取颜色的序数比例尺。制作图标时,经常需要设定各图形元素的颜色,每次都要手动设定很麻烦,如果对颜色没有特殊要求直接使用这些颜色比例尺即可。并且,它们的颜色都经过精心的色彩搭配,相当美观。颜色比例尺有4个:
 
d3.scale.category10() :
//10种颜色
 
d3.scale.category20() :
//20种颜色
 
d3.scale.category20b() :
//20种颜色
 
d3.scale.category20c() :
//20种颜色
 
这四个都是序数比例尺,输入离散值后返回也是离散值。例如category10()提供了10种颜色,分别为#1f77b4,#ff7f0e,#2ca02,#d62728,#9467bd,#8c564b,#c377c2,#7f7f7f,#bcbd22,#17becf。看代码:
 
1 var color = d3.scale.category10();
2
3         console.log(color(1))                    //输出#1f77b4
4
5         console.log(color("zhangsan"))           //输出#ff7f0e
可以看到,无论输入值是什么样的离散值,该比例尺都按照颜色顺序返回:先返回了#1f77b4,再返回#ff7f0e,如果后面还有则继续返回后面的值。使用这四个比例尺来设定颜色以后会经常见到,比如以下应用:
 
 1      var width = 600;                //svg绘制区域的宽度
 2         var height = 600;               //svg绘制区域的高度
 3         var dataset = d3.range(5);      //返回[0,1,2,3,4,5]
 4
 5         var color2 = d3.scale.category10();             //定义表示颜色的序数比例尺
 6
 7         var svg = d3.select("#body")                    //选择id为body的div
 8                     .append("svg")                      //在<body>中添加<avg>
 9                     .attr("width",width)                //设定<svg>的宽度属性
10                     .attr("height",height)              //设定<svg>的高度属性
11
12         //绘制圆
13          svg.selectAll("circle")        //选择所有的圆
14             .data(dataset)              //绑定数据
15             .enter()                    //获取enter部分
16             .append("circle")           //添加ciecle元素,使其与绑定数组的长度一致
17             .attr("cx",function(d,i){return 30 + i*80})     //设定圆的x方向的位置
18             .attr("cy",100)             //设定圆的y方向的位置
19             .attr("r",30)               //设定圆的半径
20             .attr("fill",function(d,i){ //设定圆的颜色
21                 return color2(i)
22             })
d3.range()返回一个等差数列,但是此处仅使用其长度,不使用数组的各项值。以上代码绘制了5个圆,再给每个圆设置颜色的时候,使用了color2(i)。color2是颜色比例尺。i是被绑定数据的索引号,被当做color2的参数使用。但是不一定非得用索引号,别的离散值也可以,颜色都会按顺序返回。效果图:
 
D3.js比例尺 序数比例尺(v3版本)-LMLPHP
 
 
到这一章,比例尺都介绍完了。下一章给大家介绍坐标轴的绘制方法、添加坐标轴的刻度和各比例尺的坐标轴。
05-08 07:45