上一章介紹了閾值比例尺: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()用於解決此問題:只要接收一個連續的區間,即可自動計算出相應的離散值。這兩個方法都有兩個參數:interval和padding。interval是區間,padding是邊界部分留下的空白。可省略,默認為0。意義如圖:

如上圖,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()稍有不同的是,其接收三個參數:interval、padding、outerPadding。各參數的意義如下圖。range interval是范圍。padding和outerPadding分別是內部和邊界的空白的參數,默認為0。rangePoints方框中的rangBand,表示一個區間。而該區間的起點,就是得到的離散值。圖:
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
這段代碼中,padding和outerPadding都沒有設定,默認為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的參數使用。但是不一定非得用索引號,別的離散值也可以,顏色都會按順序返回。效果圖:

到這一章,比例尺都介紹完了。下一章給大家介紹坐標軸的繪制方法、添加坐標軸的刻度和各比例尺的坐標軸。