D3.js 比例尺的使用


比例尺是 D3 中很重要的一個概念,直接用數值的大小來代表像素不是一種好方法

 

一、為什么需要比例尺

  制作一個柱形圖,會有一個數組:var dataset = [ 250 , 210 , 170 , 130 , 90 ];

  繪圖時,直接使用 250 給矩形的寬度賦值,即矩形的寬度就是 250 個像素。此方式非常具有局限性,如果數值過大或過小,例如:

    var dataset_1 = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];
    var dataset_2 = [ 2500, 2100, 1700, 1300, 900 ];

  對以上兩個數組,絕不可能用 2.5 個像素來代表矩形的寬度,那樣根本看不見;也不可能用 2500 個像素來代表矩形的寬度,因為畫布沒有那么長。

  於是,我們需要一種計算關系,能夠:將某一區域的值映射到另一區域,其大小關系不變。這就是比例尺(Scale)。

    

    

二、有哪些比例尺

  比例尺,很像數學中的函數。例如,對於一個一元二次函數,有 x 和 y 兩個未知數,當 x 的值確定時,y 的值也就確定了。

  在數學中,x 的范圍被稱為定義域,y 的范圍被稱為值域

  D3 中的比例尺,也有定義域和值域,分別被稱為 domain 和 range。開發者需要指定 domain 和 range 的范圍,如此即可得到一個計算關系。

  D3 提供了多種比例尺,下面介紹最常用的兩種。

  

  1、線性比例尺

    線性比例尺,能將一個連續的區間,映射到另一區間。要解決柱形圖寬度的問題,就需要線性比例尺。假設有以下數組:var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];  

    現有要求如下:

    將 dataset 中最小的值,映射成 0;將最大的值,映射成 300。

var min = d3.min(dataset);
var max = d3.max(dataset);

var linear = d3.scale.linear()
        .domain([min, max])
        .range([0, 300]);

linear(0.9);    //返回 0
linear(2.3);    //返回 175
linear(3.3);    //返回 300

     其中,d3.scale.linear() 返回一個線性比例尺。domain() 和 range() 分別設定比例尺的定義域和值域。在這里還用到了兩個函數,它們經常與比例尺一起出現:

      • d3.max()
      • d3.min()

    這兩個函數能夠求數組的最大值和最小值,是 D3 提供的。按照以上代碼,

    比例尺的定義域 domain 為:[0.9, 3.3]

    比例尺的值域 range 為:[0, 300]

    因此,當輸入 0.9 時,返回 0;當輸入 3.3 時,返回 300。當輸入 2.3 時呢?返回 175,這是按照線性函數的規則計算的。   

    有一點請大家記住:

      d3.scale.linear() 的返回值,是可以當做函數來使用的。因此,才有這樣的用法:linear(0.9)。

 

  2、序數比例尺

    有時候,定義域和值域不一定是連續的。例如,有兩個數組:

      var index = [0, 1, 2, 3, 4];
      var color = ["red", "blue", "green", "yellow", "black"];

    我們希望 0 對應顏色 red,1 對應 blue,依次類推。

    但是,這些值都是離散的,線性比例尺不適合,需要用到序數比例尺。

var ordinal = d3.scale.ordinal()
        .domain(index)
        .range(color);

ordinal(0); //返回 red
ordinal(2); //返回 green
ordinal(4); //返回 black

 

 

 

 

三、給柱形圖添加比例尺

<body>  

    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>  
    <script>

    var width = 300;    //畫布的寬度
    var height = 300;    //畫布的高度

    var svg = d3.select("body")                //選擇文檔中的body元素
                .append("svg")                //添加一個svg元素
                .attr("width", width)        //設定寬度
                .attr("height", height);    //設定高度
    
    var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];

    var linear = d3.scale.linear()
                    .domain([0, d3.max(dataset)])
                    .range([0, 250]);

    var rectHeight = 25;    //每個矩形所占的像素高度(包括空白)

    svg.selectAll("rect")
          .data(dataset)
          .enter()
          .append("rect")
          .attr("x",20)
          .attr("y",function(d,i){
                return i * rectHeight;
          })
          .attr("width",function(d){
                   return linear(d);//在這里用比例尺
          })
          .attr("height",rectHeight-2)
          .attr("fill","steelblue");


    </script>  

</body>  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM