D3.js - 繪製圖表

D3.js 用於建立靜態 SVG 圖表。它有助於繪製以下圖表 -

  • 條形圖
  • 圓圖
  • 餅形圖
  • 圓環圖
  • 折線圖
  • 氣泡圖等

本章介紹 D3 中的繪圖。讓我們詳細瞭解每一個。

條形圖

條形圖是最常用的圖形型別之一,用於顯示和比較不同離散類別或組的數量,頻率或其他度量(例如平均值)。該圖以這樣的方式構造,即不同條的高度或長度與它們所代表的類別的大小成比例。

x 軸(水平軸)表示沒有比例的不同類別。y 軸(垂直軸)具有刻度,這表示測量單位。可以垂直或水平繪製條,這取決於類別的數量和類別的長度或複雜性。

繪製條形圖

讓我們使用 D3 在 SVG 中建立條形圖。對於此示例,我們可以使用條形和文字元素的 rect 元素來顯示與條形對應的資料值。

要使用 D3 在 SVG 中建立條形圖,請按照下面給出的步驟操作。

步驟 1 - 在 rect 元素中新增樣式 - 讓我們將以下樣式新增到 rect 元素。

svg rect {
   fill: gray;
}

步驟 2 - 在文字元素中新增樣式 - 新增以下 CSS 類以將樣式應用於文字值。將此樣式新增到 SVG 文字元素。它定義如下 -

svg text {
   fill: yellow;
   font: 12px sans-serif;
   text-anchor: end;
}

這裡,Fill 用於應用顏色。文字錨用於將文字定位到條的右端。

步驟 3 - 定義變數 - 讓我們在指令碼中新增變數。這將在下面解釋。

<script>
   var data = [10, 5, 12, 15];
   var width = 300,
      scaleFactor = 20,
      barHeight = 30;
</script>

這裡,

  • width - SVG 的寬度。

  • Scalefactor - 縮放到螢幕上可見的畫素值。

  • Barheight - 這是水平條的靜態高度。

步驟 4 - 新增 SVG 元素 - 讓我們使用以下程式碼在 D3 中新增 SVG 元素。

var graph = d3.select("body")
   .append("svg")
   .attr("width", width)
   .attr("height", barHeight * data.length);

在這裡,我們將首先選擇文件正文,建立一個新的 SVG 元素然後追加它。我們將在此 SVG 元素中構建條形圖。然後,設定 SVG 的寬度和高度。高度計算為條形高度 * 資料值的。

我們將條形高度設為 30,資料陣列長度為 4.然後 SVG 高度計算為 barheight * datalength,即 120 px。

步驟 5 - 應用轉換 - 讓我們使用以下程式碼在 bar 中應用轉換。

var bar = graph.selectAll("g") 
   .data(data)
   .enter()
   .append("g")
   .attr("transform", function(d, i) {
      return "translate(0," + i * barHeight + ")";
   });

這裡,每個欄內部對應一個元素。因此,我們建立組元素。我們的每個組元素都需要一個位於另一個之下,以構建一個水平條形圖。讓我們採用轉換公式索引*條高度。

步驟 6 - 將矩形元素附加到條形圖 - 在上一步中,我們附加了組元素。現在使用以下程式碼將 rect 元素新增到欄中。

bar.append("rect")
   .attr("width", function(d) {
      return d * scaleFactor;
   })
   .attr("height", barHeight - 1);

這裡,寬度是(資料值*比例因子),高度是(條形高度 - 邊距)。

步驟 7 - 顯示資料 - 這是最後一步。讓我們使用以下程式碼在每個條上顯示資料。

bar.append("text")
   .attr("x", function(d) { return (d*scaleFactor); })
   .attr("y", barHeight / 2)
   .attr("dy", ".35em")
   .text(function(d) { return d; });

這裡,寬度定義為(資料值*比例因子)。文字元素不支援填充或邊距。出於這個原因,我們需要給它一個 dy 偏移量。這用於垂直對齊文字。

步驟 8 - 工作示例 - 完整的程式碼清單顯示在以下程式碼塊中。建立網頁 barcharts.html 並新增以下更改。

barcharts.html

<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
      <style>
         svg rect {
            fill: gray;
         }
         
         svg text {
            fill: yellow;
            font: 12px sans-serif;
            text-anchor: end;
         }
      </style>
   </head>

   <body>
      <script>
         var data = [10, 5, 12, 15];
         
         var width = 300 
            scaleFactor = 20, 
            barHeight = 30;
         
         var graph = d3.select("body")
            .append("svg")
            .attr("width", width)
            .attr("height", barHeight * data.length);
         
         var bar = graph.selectAll("g")
            .data(data)
            .enter()
            .append("g")
            .attr("transform", function(d, i) {
               return "translate(0," + i * barHeight + ")";
            });
         bar.append("rect").attr("width", function(d) {
            return d * scaleFactor;
         })
         
         .attr("height", barHeight - 1);
         
         bar.append("text")
            .attr("x", function(d) { return (d*scaleFactor); })
            .attr("y", barHeight / 2)
            .attr("dy", ".35em")
            .text(function(d) { return d; });
      </script>
   </body>
</html>

圓圖

圓形圖是圓形統計圖形,它被分成切片以說明數字比例。

繪製圓圖

讓我們使用 D3 在 SVG 中建立一個圓形圖。要做到這一點,我們必須遵守以下步驟 -

步驟 1 - 定義變數 - 讓我們在指令碼中新增變數。它顯示在下面的程式碼塊中。

<script>
   var width = 400;
   var height = 400;
   var data = [10, 20, 30];
   var colors = ['green', 'purple', 'yellow'];
</script>

這裡,

  • width - SVG 的寬度。

  • height - SVG 的高度。

  • 資料 - 資料元素陣列。

  • 顏色 - 將顏色應用於圓形元素。

步驟 2 - 附加 SVG 元素 - 讓我們使用以下程式碼在 D3 中新增 SVG 元素。

var svg = d3.select("body")
   .append("svg")
   .attr("width", width)
   .attr("height", height);

步驟 3 - 應用轉換 - 讓我們使用以下程式碼在 SVG 中應用轉換。

var g = svg.selectAll("g")
   .data(data)
   .enter()
   .append("g")
   .attr("transform", function(d, i) {
      return "translate(0,0)";
   })

這裡,

var g = svg.selectAll(g - 建立用於保持圓圈的組元素。

.data(data) - 將我們的資料陣列繫結到組元素。

.enter() - 為我們的組元素建立佔位符。

.append(g - 將組元素新增到我們的頁面。

.attr("transform", function(d, i) {
   return "translate(0,0)";
})

這裡,translate 用於相對於原點定位元素。

步驟 4 - 附加圓形元素 - 現在,使用以下程式碼將圓形元素附加到組中。

g.append("circle")

現在,使用以下程式碼將屬性新增到組中。

.attr("cx", function(d, i) {
   return i*75 + 50;
})

在這裡,我們使用每個圓的中心的 x 座標。我們將圓的索引乘以 75 並在圓之間新增 50 的填充。

接下來,我們設定每個圓的中心的 y 座標。這用於統一所有圓圈,並在下面定義。

.attr("cy", function(d, i) {
   return 75;
})

接下來,設定每個圓的半徑。它定義如下,

.attr("r", function(d) {
   return d*1.5;
})

這裡,半徑乘以資料值以及常數 1.5 以增加圓的大小。最後,使用以下程式碼填充每個圓圈的顏色。

.attr("fill", function(d, i){
   return colors[i];
})

步驟 5 - 顯示資料 - 這是最後一步。讓我們使用以下程式碼顯示每個圓圈上的資料。

g.append("text")
   .attr("x", function(d, i) {
      return i * 75 + 25;
   })
   .attr("y", 80)
   .attr("stroke", "teal")
   .attr("font-size", "10px")
   .attr("font-family", "sans-serif")
   .text(function(d) {
      return d;
   });

步驟 6 - 工作示例 - 完整的程式碼清單顯示在以下程式碼塊中。建立一個網頁 circlecharts.html 並在其中新增以下更改。

circlecharts.html

<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
   </head>

   <body>
      <script>
         var width = 400;
         
         var height = 400;
         
         var data = [10, 20, 30];
         
         var colors = ['green', 'purple', 'yellow'];
         
         var svg = d3
            .select("body")
            .append("svg")
            .attr("width", width)
            .attr("height", height);
         
         var g = svg.selectAll("g")
            .data(data)
            .enter()
            .append("g")
            .attr("transform", function(d, i) {
               return "translate(0,0)";
            })
         
         g.append("circle").attr("cx", function(d, i) {
            return i*75 + 50;
         })
         
         .attr("cy", function(d, i) {
            return 75;
         })
  
         .attr("r", function(d) {
            return d*1.5;
         })
         
         .attr("fill", function(d, i){
            return colors[i];
         })
         
         g.append("text").attr("x", function(d, i) {
            return i * 75 + 25;
         })
         
         .attr("y", 80)
         .attr("stroke", "teal")
         .attr("font-size", "10px")
         .attr("font-family", "sans-serif").text(function(d) {
            return d;
         });
      </script>
   </body>
</html>

現在,請求你的瀏覽器,以下將是響應。

餅形圖

餅圖是圓形統計圖。它被分成片來顯示數字比例。讓我們瞭解如何在 D3 中建立餅圖。

畫一個餅圖

在開始繪製餅圖之前,我們需要了解以下兩種方法 -

  • d3.arc() 方法和
  • d3.pie() 方法。

讓我們詳細瞭解這兩種方法。

d3.arc() 方法 - d3.arc() 方法生成一個弧。你需要為弧設定內半徑和外半徑。如果內半徑為 0,則結果將為餅圖,否則結果將為圓環圖,將在下一節中討論。

d3.pie() 方法 - d3.pie() 方法用於生成餅圖。它從資料集中獲取資料並計算餅圖的每個楔形的起始角度和結束角度。

讓我們使用以下步驟繪製餅圖。

步驟 1 - 應用樣式 - 讓我們將以下樣式應用於 arc 元素。

.arc text {
   font: 12px arial;
   text-anchor: middle;
}

.arc path {
   stroke: #fff;
}

.title {
   fill: green;
   font-weight: italic;
}

這裡,填充用於應用顏色。文字錨用於將文字定位到弧的中心。

步驟 2 - 定義變數 - 在指令碼中定義變數,如下所示。

<script>
   var svg = d3.select("svg"),
      width = svg.attr("width"),
      height = svg.attr("height"),
      radius = Math.min(width, height) / 2;
</script>

這裡,

  • width - SVG 的寬度。

  • height - SVG 的高度。

  • radius - 可以使用 Math.min(width,height)/ 2 的函式計算;

步驟 3 - 應用轉換 - 使用以下程式碼在 SVG 中應用以下轉換。

var g = svg.append("g")
   .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

現在使用 d3.scaleOrdinal 函式新增顏色,如下所示。

var color = d3.scaleOrdinal(['gray', 'green', 'brown', 'orange']);

步驟 4 - 生成餅圖 - 現在,使用下面給出的函式生成餅圖。

var pie = d3.pie()
   .value(function(d) { return d.percent; });

在這裡,你可以繪製百分比值。需要匿名函式來返回 d.percent 並將其設定為餅值。

步驟 5 - 定義餅形楔形的弧形 - 生成餅圖後,現在使用下面給出的函式為每個餅形楔形定義弧形。

var arc = d3.arc()
   .outerRadius(radius)
   .innerRadius(0);

這裡,該弧將被設定為路徑元素。計算出的半徑設定為 outerradius,而 innerradius 設定為 0。

步驟 6 - 在楔形中新增標籤 - 通過提供半徑在餅形楔中新增標籤。它的定義如下。

var label = d3
   .arc()
   .outerRadius(radius)
   .innerRadius(radius - 80);

步驟 7 - 讀取資料 - 這是重要的一步。我們可以使用下面給出的函式讀取資料。

d3.csv("populations.csv", function(error, data) {
   if (error) {
      throw error;
   }
});

在這裡,populations.csv 包含的資料檔案。該 d3.csv 功能從資料集讀取資料。如果資料不存在,則會引發錯誤。我們可以在 D3 路徑中包含此檔案。

步驟 8 - 載入資料 - 下一步是使用以下程式碼載入資料。

var arc = g.selectAll(".arc")
   .data(pie(data))
   .enter()
   .append("g")
   .attr("class", "arc");

在這裡,我們可以為資料集中的每個資料值的組元素分配資料。

步驟 9 - 追加路徑 - 現在,追加路徑並將一個類’arc’分配給組,如下所示。

arcs.append("path")
   .attr("d", arc)
   .attr("fill", function(d) { return color(d.data.states); });

這裡,fill 用於應用資料顏色。它取自 d3.scaleOrdinal 函式。

步驟 10 - 附加文字 - 使用以下程式碼在標籤中顯示文字。

arc.append("text")
   .attr("transform", function(d) { 
      return "translate(" + label.centroid(d) + ")"; 
   })
.text(function(d) { return d.data.states; });

這裡,SVG 文字元素用於在標籤中顯示文字。我們之前使用 d3.arc() 建立的標籤弧返回一個質心點,它是標籤的位置。最後,我們使用 d.data.browser 提供資料。

步驟 11 - 追加組元素 - 新增組元素屬性並新增類標題以使文字著色並使其變為斜體,這在步驟 1 中指定並在下面定義。

svg.append("g")
   .attr("transform", "translate(" + (width / 2 - 120) + "," + 20 + ")")
   .append("text")
   .text("Top population states in india")
   .attr("class", "title")

步驟 12 - 工作示例 - 要繪製餅圖,我們可以獲取印度人口的資料集。此資料集顯示虛擬網站中的人口,其定義如下。

population.csv

states,percent
UP,80.00
Maharastra,70.00
Bihar,65.0
MP,60.00
Gujarat,50.0
WB,49.0
TN,35.0

讓我們為上面的資料集建立一個餅圖視覺化。建立一個網頁 piechart.html 並在其中新增以下程式碼。

<!DOCTYPE html>
<html>
   <head>
      <style>
         .arc text {
            font: 12px arial;
            text-anchor: middle;
         }
         
         .arc path {
            stroke: #fff;
         }
        
        .title {
            fill: green;
            font-weight: italic;
         }
      </style>
      
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
   </head>

   <body>
      <svg width = "400" height = "400"></svg>
      <script>
         var svg = d3.select("svg"),
            width = svg.attr("width"),
            height = svg.attr("height"),
            radius = Math.min(width, height) / 2;
        
         var g = svg.append("g")
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

         var color = d3.scaleOrdinal([
            'gray', 'green', 'brown', 'orange', 'yellow', 'red', 'purple'
         ]);
         
         var pie = d3.pie().value(function(d) { 
            return d.percent; 
         });
         
         var path = d3.arc()
            .outerRadius(radius - 10).innerRadius(0);
        
         var label = d3.arc()
            .outerRadius(radius).innerRadius(radius - 80);
         
         d3.csv("populations.csv", function(error, data) {
            if (error) {
               throw error;
            }
            
            var arc = g.selectAll(".arc")
               .data(pie(data))
               .enter()
               .append("g")
               .attr("class", "arc");
            
            arc.append("path")
               .attr("d", path)
               .attr("fill", function(d) { return color(d.data.states); });
        
            console.log(arc)
        
            arc.append("text").attr("transform", function(d) { 
               return "translate(" + label.centroid(d) + ")"; 
            })
            
            .text(function(d) { return d.data.states; });
         });
         
         svg.append("g")
            .attr("transform", "translate(" + (width / 2 - 120) + "," + 20 + ")")
            .append("text").text("Top population states in india")
            .attr("class", "title")
      </script>
   </body>
</html>

餅形圖

圓環圖

甜甜圈或圓環圖只是一個內部有洞的簡單餅圖。我們可以將孔半徑定義為你需要的任何尺寸,包括百分比或畫素。我們可以建立圓環圖而不是餅圖。更改弧的內半徑以使用大於零的值。它的定義如下。

var arc = d3.arc()
   .outerRadius(radius)
   .innerRadius(100);

與餅圖編碼相同,內半徑略有變化,我們可以生成圓環圖。建立一個網頁 dounutchart.html 並在其中新增以下更改。

Donutchart.html

<!DOCTYPE html>
<html>
   <head>
      <style>
         .arc text {
            font: 12px arial;
            text-anchor: middle;
         }
        
         .arc path {
            stroke: #fff;
         }
        
         .title {
            fill: green;
            font-weight: italic;
         }
      </style>
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
   </head>

   <body>
      <svg width = "400" height = "400"></svg>
      <script>
         var svg = d3.select("svg"),
            width = svg.attr("width"),
            height = svg.attr("height"),
            radius = Math.min(width, height) / 2;
        
         var g = svg.append("g")
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
        
         var color = d3.scaleOrdinal([
            'gray', 'green', 'brown', 'orange', 'yellow', 'red', 'purple'
         ]);
        
         var pie = d3.pie().value(function(d) { 
            return d.percent; 
         });
        
         var path = d3.arc()
            .outerRadius(radius)
            .innerRadius(100);
        
         var label = d3.arc()
            .outerRadius(radius)
            .innerRadius(radius - 80);
        
         d3.csv("populations.csv", function(error, data) {
            if (error) {
               throw error;
            }
            
            var arc = g.selectAll(".arc")
               .data(pie(data))
               .enter()
               .append("g")
               .attr("class", "arc");
               arc.append("path")
                  .attr("d", path)
                  .attr("fill", function(d) { return color(d.data.states); });
           
               console.log(arc)
           
               arc.append("text")
                  .attr("transform", function(d) { 
                     return "translate(" + label.centroid(d) + ")"; 
                   })
                  .text(function(d) { return d.data.states; });
         });
         
         svg.append("g")
            .attr("transform", "translate(" + (width / 2 - 120) + "," + 20 + ")")
            .append("text")
            .attr("class", "title")
      </script>
   </body>
</html>

在這裡,我們將路徑變數更改為 -

var path = d3.arc()
   .outerRadius(radius)
   .innerRadius(100);

我們將 innerRadius 值設定為 0 以生成圓環圖。現在,請求瀏覽器,我們可以看到以下響應。

圓環圖