D3.js 核心概念——形狀(四)連線生成器 Links

語言: CN / TW / HK

這是我參與11月更文挑戰的第12天,活動詳情查看:2021最後一次更文挑戰


系列文章可以查看《數據可視化》專欄


參考:


連線生成器 Links 基於兩個座標點,繪製出平滑的三次貝塞爾曲線作為兩點之間(從起源點 source point 到目標點 target point)的連線,一般用於樹形圖 tree diagram 中。

所繪製的連線在起點和終點的處的切線可以有三種形式,分別通過三種不同的方法創建三種不同的連線生成器(以下稱為 link),適用於不同方向的樹形圖中

  • 使用方法 d3.linkVertical() 創建(生成垂直切線的)連線生成器(以下稱為 linkVertical,一般用於父節點和子節點是上下相對位置的樹形圖中
  • 使用方法 d3.linkHorizontal() 創建(生成水平切線的)連線生成器(以下稱為 linkHorizontal,一般用於父節點和子節點是水平左右相對位置的樹形圖中
  • 使用方法 d3.linkRadial() 創建(生成徑向切線的)連線生成器(以下稱為 linkRadial,一般用於根節點在內部,後代節點在外部的環形樹形圖中

它既是一個方法,可以直接調用,傳遞需要可視化的數據,連線生成器會根據數據構建出連線。一般是以一個對象作為入參,它最基本的形式是包含 sourcetarget 這兩個屬性,分別表示連線的起點和終點,這兩個屬性的屬性值最基本的形式就是一個數組,分別表示起點或終點的 xy

js // D3 默認支持的連線生成器入參數據形式 link({  source: [100, 100],  target: [300, 300] });

💡 調用連線生成器時返回的結果,也會基於生成器是否設置了父容器 context 而不同。如果設置了父容器,則生成 <path> 元素,並添加到父容器中;如果沒有設置父容器,則生成字符串。

它也是一個對象,具有多種方法設置不同的參數,一般通過鏈式調用的方式來使用:

對於 linkVerticallinkHorizontal 連線生成器有以下方法

  • link.source(sourceFunc) 設置起始點讀取函數。該函數的入參是調用連線生成器時傳遞的數據 d,D3 默認該數據是一個對象,且具有 source 屬性表示起始點,因此默認讀取函數如下

    js function source(d) {  return d.source; }

    💡 如果入參的數據形式和 D3 的默認形式不同,需要手動設置起始點讀取函數,返回起始點

  • link.target(targetFunc) 設置起始點讀取函數。默認讀取函數如下

    js function target(d) {  return d.target; }

  • link.x(xFunc) 設置橫座標讀取函數。D3 默認起點和終點都是一個含有兩個元素的數組,第一個元素表示這些點的橫座標,第二個元素表示這些點的縱座標,因此默認讀取函數如下

    js function x(d) {  return d[0]; }

    💡 如果入參的數據形式和 D3 的默認形式不同,需要手動設置點讀取函數,返回橫座標

  • link.y(yFunc) 設置縱座標讀取函數。默認讀取函數如下

    js function y(d) {  return d[1]; }

  • link.context(parentDOM) 用於設置父容器

對於 linkRadial 連線生成器有類似的方法,不過它的橫座標變成角度(單位是弧度),縱座標變成了徑向距離

  • linkRadial.angle(angleFunc) 類似於 link.x(xFunc),設置角度讀取函數,返回的角度單位是弧度

  • linkRadial.radius(radiusFunc) 類似於 link.y(yFunc),設置徑向距離讀取函數

    💡 調用徑向連線生成器時,它生成的連線的中心座標默認是 (0, 0),可以為其父容器(一般是元素 <g>)設置 transform 屬性,移動到目標位置

💡 如果希望從抽象的數據開始以構建樹形圖,可以使用 d3-hierarchy 模塊。該模塊基於抽象的數據和頁面大小自動計算佈局,即將抽象的數據映射到頁面的可視化圖形元素,生成各連線的起點 source 和終點 target 座標數據。再將這些數據分別傳遞給相應的連線生成器即可分別生成連線。