D3.js - SVG 轉換

SVG 提供了轉換單個 SVG 形狀元素或 SVG 元素組的選項。SVG 變換支援轉移,縮放,旋轉傾斜。 讓我們在本章學習轉型。

SVG 轉換簡介

SVG 引入了一個新屬性,transform 為支援轉換。可能的值是以下一項或多項,

  • translate - 它有兩個選項,tx 表示沿 x 軸平移,ty 表示沿 y 軸平移。比如 - translate(30,30)

  • rotate - 它有三個選項,angle 指旋轉角度,cxcy 指的是 x 和 y 軸旋轉的中心。如果未指定 cxcy,則預設為座標系的當前原點。比如 - rotate(60)

  • scale - 它有兩個選項,sx 表示沿 x 軸的比例因子,sy 表示沿 y 軸的比例因子。這裡,sy 是可選的,如果沒有指定,則它取 sx 的值。 比如 - scale(10)

  • skew(skewX 和 skewY) - 只需一個選項; skew-angle 指的是沿著 x 軸為 skewX 和沿 y 軸為 SkewY 的角度的角度。比如 - skewX(20)

帶有 translate 的 SVG 矩形示例,如下所述 -

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

   <body>
      <svg width = "300" height = "300">
         <rect x = "20" 
            y = "20"
            width = "60"
            height = "60"
            fill = "green"
            transform = "translate(30 30)">
         </rect>
      </svg>
   </body>
</html>

上面的程式碼將產生以下結果。

可以使用空格作為分隔為單個 SVG 元素指定多個轉換。如果指定了多個值,則將按指定的順序逐個應用轉換。

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

   <body>
      <svg width = "300" height = "300">
         <rect x = "20" 
            y = "20" 
            width = "60" 
            height = "60" 
            fill = "green" 
            transform = "translate(60 60) rotate(45)">
         </rect>
      </svg>
   </body>
</html>

上面的程式碼將產生以下結果。

轉換也可以應用於 SVG 組元素。這使得能夠轉換 SVG 中定義的複雜圖形,如下所述。

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

   <body>
      <svg width = "300" height = "300">
         <g transform = "translate(60,60) rotate(30)">
            <rect x = "20" 
               y = "20" 
               width = "60" 
               height = "30" 
               fill = "green">
            </rect>
            <circle cx = "0" 
               cy = "0" 
               r = "30" 
               fill = "red"/>
         </g>
      </svg>
   </body>
</html>

上面的程式碼將產生以下結果。

一個最小例項

要建立 SVG 影象,嘗試縮放,並使用變換旋轉它,讓我們按照下面給出的步驟。

步驟 1 - 建立 SVG 影象並將寬度設定為 300 畫素,將高度設定為 300 畫素。

<svg width = "300" height = "300">

</svg>

步驟 2 - 建立一個 SVG 組。

<svg width = "300" height = "300">
   <g>
   </g>
</svg>

步驟 3 - 建立一個長度為 60,高度為 30 的矩形,並用綠色填充。

<svg width = "300" height = "300">
   <g>
      <rect x = "20" 
         y = "20" 
         width = "60" 
         height = "30" 
         fill = "green">
      </rect>
   </g>
</svg>

步驟 4 - 建立一個半徑為 30 的圓,並用紅色填充。

<svg width = "300" height = "300">
   <g>
      <rect x = "20" 
         y = "20" 
         width = "60" 
         height = "30" 
         fill = "green">
      </rect>
      <circle cx = "0" 
         cy = "0" 
         r = "30" 
         fill = "red"/>
   </g>
</svg>

步驟 5 - 新增轉換屬性並新增平移和旋轉,如下所示。

<svg width = "300" height = "300">
   <g transform = "translate(60,60) rotate(30)">
      <rect x = "20" 
         y = "20" 
         width = "60" 
         height = "60" 
         fill = "green">
      </rect>
      <circle cx = "0" 
         cy = "0" 
         r = "30" 
         fill = "red"/>
   </g>
</svg>

步驟 6 - 建立 HTML 文件“svg_transform_rotate_group.html”並整合上述 SVG,如下所述。

<!DOCTYPE html>
<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
      <style>
         body { font-family: Arial; }
      </style>
   </head>

   <body>
      <div id = "svgcontainer">
         <svg width = "300" height = "300">
            <g transform = "translate(60,60) rotate(30)">
               <rect x = "20" 
                  y = "20" 
                  width = "60" 
                  height = "60" 
                  fill = "green">
               </rect>
               <circle cx = "0" 
                  cy = "0" 
                  r = "30" 
                  fill = "red"/>
            </g>
         </svg>
      </div>
   </body>
</html>

上面的程式碼將產生以下結果。

使用 D3.js 進行轉換

要使用 D3.js 建立 SVG,請按照下面給出的步驟操作。

步驟 1 - 建立一個容器來儲存 SVG 影象,如下所述。

<div id = "svgcontainer"></div>

步驟 2 - 建立 SVG 影象,如下所述。

var width = 300;
var height = 300;
var svg = d3.select("#svgcontainer")
   .append("svg")
   .attr("width", width)
   .attr("height", height);

步驟 3 - 建立 SVG 組元素並設定轉換和旋轉屬性。

var group = svg.append("g").attr("transform", "translate(60, 60) rotate(30)");

步驟 4 - 建立一個 SVG 矩形並將其附加到組中。

var rect = group
   .append("rect")
   .attr("x", 20)
   .attr("y", 20)
   .attr("width", 60)
   .attr("height", 30)
   .attr("fill", "green")

步驟 5 - 建立一個 SVG 圈並將其附加到組內。

var circle = group
   .append("circle")
   .attr("cx", 0)
   .attr("cy", 0)
   .attr("r", 30)
   .attr("fill", "red")

完整的程式碼如下 -

<!DOCTYPE html>
<html lang = "en">
   <head>
      <title>SVG rectangle</title>
      <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
      <style>
         body { font-family: Arial; }
      </style>
   </head>

   <body>
      <div id = "svgcontainer"></div>
         <script language = "javascript">
            var width = 300;
            var height = 300;
            var svg = d3.select("#svgcontainer")
               .append("svg")
               .attr("width", width)
               .attr("height", height);

            var group = svg.append("g")
               .attr("transform", "translate(60, 60) rotate(30)");
            
            var rect = group.append("rect")
               .attr("x", 20)
               .attr("y", 20)
               .attr("width", 60)
               .attr("height", 30)
               .attr("fill", "green")
            
            var circle = group
               .append("circle")
               .attr("cx", 0)
               .attr("cy", 0)
               .attr("r", 30)
               .attr("fill", "red")
         </script>
      </div>
   </body>
</html>

上面的程式碼將產生以下結果。

變換庫

D3.js 提供了一個單獨的庫來管理轉換,而無需手動建立轉換屬性。它提供了處理所有型別轉換的方法如 transform()translate()scale()rotate() 等。你可以使用以下指令碼在網頁中包含 d3-transform

<script src = "http://d3js.org/d3.v4.min.js"></script>
<script src = "d3-transform.js"></script>

在上面的例子中,轉換程式碼可以寫成如下所示 -

var my_transform = d3Transform()
   .translate([60, 60])
   .rotate(30);

var group = svg
   .append("g")
   .attr("transform", my_transform);