上一章介紹了閾值比例尺: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的引數使用。但是不一定非得用索引號,別的離散值也可以,顏色都會按順序返回。效果圖:
到這一章,比例尺都介紹完了。下一章給大家介紹座標軸的繪製方法、新增座標軸的刻度和各比例尺的座標軸。