上一章介绍了阈值比例尺: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]五个离散值。看代码:
 
 var ordinal = d3.scale.ordinal()
.domain([1,2,3,4,5])
.range([10,20,30,40,50]) console.log(ordinal(1)) //输出10 console.log(ordinal(3)) //输出30 console.log(ordinal(5)) //输出50 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是根据定义域的数值计算得到的值。图中圆圈所代表的点,就是计算得到的离散值。看代码:
 
  var ordinal2 = d3.scale.ordinal()
.domain([1,2,3,4,5])
.rangePoints([0,100]) console.log(ordinal2.range()) //输出 [0, 25, 50, 75, 100] console.log(ordinal2(1)) //输出0 console.log(ordinal2(3)) //输出50 console.log(ordinal2(5)) //输出100
上面代码的序数比例尺中,rangePoints()的第一个参数为[0,100],第二个参数省略。对应到上图的话,则range interval等于[0,100],padding等于0,step等于25.因此,得到了 上面输出的5个离散值,与定义域的5个值是一一对应的。下面来看看padding有设定值的情况:
 
    ordinal2.rangePoints([0,100],5)

         console.log(ordinal2.range())        //输出[27.77777777777778, 38.888888888888886, 50, 61.11111111111111, 72.22222222222223]
这样设定后,padding等于5,step等于11.111111。则step*padding/2等于27.77777,正是输出数组的第一个值。这样,有时输出的数组是无穷小数,如果希望其都是整数,可用rangeRoundPoints()。代码 :
 
    ordinal2.rangeRoundPoints([0,100],5)

         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的值,举个例子:
 
 var bands = d3.scale.ordinal()
.domain([1,2,3,4,5])
.rangeBands([0,100]) console.log(bands.range()) //输出[0, 20, 40, 60, 80] console.log(bands.rangeBand()) //输出20
这段代码中,paddingouterPadding都没有设定,默认为0.计算可得,rangeBand为20,值域有五个离散的值,分别是每一个rangeBand区域的起点,即[0,20,40,60,80]。下面试一下设定了空白的情况:
 
 bands.rangeBands([0,100],0.5,0.2)

         console.log(bands.range())          //输出[4.081632653061225, 24.489795918367346, 44.89795918367347, 65.3061224489796, 85.71428571428571]

         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。看代码:
 
 var color = d3.scale.category10();

         console.log(color(1))                    //输出#1f77b4

         console.log(color("zhangsan"))           //输出#ff7f0e
可以看到,无论输入值是什么样的离散值,该比例尺都按照颜色顺序返回:先返回了#1f77b4,再返回#ff7f0e,如果后面还有则继续返回后面的值。使用这四个比例尺来设定颜色以后会经常见到,比如以下应用:
 
      var width = 600;                //svg绘制区域的宽度
var height = 600; //svg绘制区域的高度
var dataset = d3.range(5); //返回[0,1,2,3,4,5] var color2 = d3.scale.category10(); //定义表示颜色的序数比例尺 var svg = d3.select("#body") //选择id为body的div
.append("svg") //在<body>中添加<avg>
.attr("width",width) //设定<svg>的宽度属性
.attr("height",height) //设定<svg>的高度属性 //绘制圆
svg.selectAll("circle") //选择所有的圆
.data(dataset) //绑定数据
.enter() //获取enter部分
.append("circle") //添加ciecle元素,使其与绑定数组的长度一致
.attr("cx",function(d,i){return 30 + i*80}) //设定圆的x方向的位置
.attr("cy",100) //设定圆的y方向的位置
.attr("r",30) //设定圆的半径
.attr("fill",function(d,i){ //设定圆的颜色
return color2(i)
})
d3.range()返回一个等差数列,但是此处仅使用其长度,不使用数组的各项值。以上代码绘制了5个圆,再给每个圆设置颜色的时候,使用了color2(i)。color2是颜色比例尺。i是被绑定数据的索引号,被当做color2的参数使用。但是不一定非得用索引号,别的离散值也可以,颜色都会按顺序返回。效果图:
 
D3.js比例尺 序数比例尺(v3版本)-LMLPHP
 
 
到这一章,比例尺都介绍完了。下一章给大家介绍坐标轴的绘制方法、添加坐标轴的刻度和各比例尺的坐标轴。
05-14 09:02