欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-08-09 22:46:19
上一章介绍了阈值比例尺:https://www.cnblogs.com/littleSpill/p/10825038.html。到目前所有的定量比例尺已经介绍完了。 现在给大家介绍一下序数比例尺。 定量比例尺的定义域都是连续的,值域有连续的也有离散的。序数比例尺(Ordinal Scale)的定义域 ......

上一章介绍了阈值比例尺: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版本)
 
如上图,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版本)

 

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版本)
 
 
到这一章,比例尺都介绍完了。下一章给大家介绍坐标轴的绘制方法、添加坐标轴的刻度和各比例尺的坐标轴。