跳至內容

值內插

這些是最通用的內插器,適用於大多數值。

interpolate(a, b)

範例 · 原始碼 · 傳回兩個任意值 ab 之間的內插器。

js
d3.interpolate("red", "blue")(0.5) // "rgb(128, 0, 128)"

內插器的實作基於結束值 b 的類型,使用下列演算法

  1. 如果 b 為 null、未定義或布林值,使用常數 b
  2. 如果 b 為數字,使用 interpolateNumber
  3. 如果 b顏色 或可轉換為顏色的字串,使用 interpolateRgb
  4. 如果 b日期,使用 interpolateDate
  5. 如果 b 是字串,請使用 interpolateString
  6. 如果 b 是數字的 型化陣列,請使用 interpolateNumberArray
  7. 如果 b 是通用 陣列,請使用 interpolateArray
  8. 如果 b 可轉換為數字,請使用 interpolateNumber
  9. 使用 interpolateObject

根據所選的內插器,a 會轉換為適當的對應類型。

interpolateNumber(a, b)

範例 · 來源 · 傳回兩個數字 ab 之間的內插器。

js
d3.interpolateNumber(20, 620)(0.8) // 500

傳回的內插器等於

js
function interpolator(t) {
  return a * (1 - t) + b * t;
}

注意

當內插器用於產生字串時,請避免內插到或從數字零。當非常小的值被轉換成字串時,它們可能會轉換成科學記號,這在較舊的瀏覽器中是不合法的屬性或樣式屬性值。例如,數字 0.0000001 會轉換成字串 "1e-7"。這在內插不透明度時特別明顯。若要避免科學記號,請在 1e-6 開始或結束轉換:不會在科學記號中轉換成字串的最小值。

interpolateRound(a, b)

範例 · 來源 · 傳回兩個數字 ab 之間的內插器。

js
d3.interpolateRound(20, 620)(0.821) // 513

內插器類似於 interpolateNumber,只不過它會將結果值四捨五入到最接近的整數。

interpolateString(a, b)

範例 · 來源 · 傳回兩個字串 ab 之間的內插器。

js
d3.interpolateString("20px", "32px")(0.5) // "26px"

字串內插器會尋找嵌入在 ab 中的數字,其中每個數字都是 JavaScript 所理解的格式。以下是一些會在字串中偵測到的數字範例:-1423.141596.0221413e+23

對於嵌入在 b 中的每個數字,內插器會嘗試在 a 中找到對應的數字。如果找到對應的數字,則會使用 interpolateNumber 建立數字內插器。字串 b 的其餘部分用作範本:字串 b 的靜態部分在內插期間保持不變,內插的數字值會嵌入在範本中。

例如,如果 a"300 12px sans-serif",而 b"500 36px Comic-Sans",則會找到兩個嵌入的數字。其餘的靜態部分(字串 b)是兩個數字之間的空格(" ")和字尾("px Comic-Sans")。內插器在 t = 0.5 時的結果是 "400 24px Comic-Sans"

interpolateDate(a, b)

範例 · 原始碼 · 傳回兩個 日期 ab 之間的內插器。

js
d3.interpolateDate(new Date("2014-01-01"), new Date("2024-01-01"))(0.5) // 2019-01-01

注意

不會建立傳回日期的防禦性拷貝;每次評估內插器時,都會傳回同一個 Date 實例。為了效能考量,不會建立拷貝,因為內插器通常是 動畫過場 內部迴圈的一部分。

interpolateArray(a, b)

範例 · 原始碼 · 傳回兩個陣列 ab 之間的內插器。

js
d3.interpolateArray([0, 0, 0], [1, 2, 3])(0.5) // [0.5, 1, 1.5]

如果 b 是類型化陣列(例如 Float64Array),則會呼叫 interpolateNumberArray

在內部,會建立一個與 b 長度相同的陣列範本。對於 b 中的每個元素,如果 a 中有對應的元素,則會使用 interpolate 為這兩個元素建立一個通用內插器。如果沒有這樣的元素,則範本中會使用 b 中的靜態值。然後,對於給定的參數 t,會評估範本中嵌入的內插器。接著會傳回已更新的陣列範本。

例如,如果 a 是陣列 [0, 1],而 b 是陣列 [1, 10, 100],則內插器在 t = 0.5 時的結果是陣列 [0.5, 5.5, 100]

注意

不會建立範本陣列的防禦性拷貝;修改傳回的陣列可能會對內插器的後續評估造成不良影響。為了效能考量,不會建立拷貝;內插器通常是 動畫過場 內部迴圈的一部分。

interpolateNumberArray(a, b)

範例 · 原始碼 · 傳回兩個數字陣列 ab 之間的內插器。

js
d3.interpolateNumberArray([0, 1], Float64Array.of(1, 3))(0.5) // [0.5, 2]

在內部,會建立一個與 b 相同類型和長度的陣列範本。對於 b 中的每個元素,如果 a 中有對應的元素,則會直接在陣列範本中內插這些值。如果沒有這樣的元素,則會複製 b 中的靜態值。接著會傳回已更新的陣列範本。

注意

不會建立防禦性副本的範本陣列和引數 ab;修改這些陣列可能會影響內插器的後續評估。

interpolateObject(a, b)

範例 · 原始碼 · 傳回兩個物件 ab 之間的內插器。

js
d3.interpolateObject({x: 0, y: 1}, {x: 1, y: 10, z: 100})(0.5) // {x: 0.5, y: 5.5, z: 100}

在內部,會建立一個物件範本,其屬性與 b 相同。對於 b 中的每個屬性,如果 a 中存在對應的屬性,則會使用 interpolate 為這兩個元素建立一個通用內插器。如果沒有這樣的屬性,則會在範本中使用 b 中的靜態值。然後,對於給定的參數 t,會評估範本的內嵌內插器,然後傳回更新的物件範本。

例如,如果 a 是物件 {x: 0, y: 1},而 b 是物件 {x: 1, y: 10, z: 100},則內插器對於 t = 0.5 的結果是物件 {x: 0.5, y: 5.5, z: 100}

物件內插對於資料空間內插特別有用,其中內插的是資料,而不是屬性值。例如,您可以內插一個描述圓餅圖中弧形的物件,然後使用 arc 來計算新的 SVG 路徑資料。

注意

不會建立防禦性副本的範本物件;修改傳回的物件可能會對內插器的後續評估產生負面影響。基於效能考量,不會建立副本;內插器通常是 動畫轉場 內部迴圈的一部分。

interpolateBasis(values)

範例 · 原始碼 · 傳回一個均勻非有理 B 樣條內插器,通過指定的 values 陣列,其中必須是數字。

js
d3.interpolateBasis([0, 0.1, 0.4, 1])(0.5) // 0.2604166666666667

隱含控制點會生成,以便插補器在 t = 0 時傳回 values[0],在 t = 1 時傳回 values[values.length - 1]。另請參閱 curveBasisinterpolateRgbBasis

interpolateBasisClosed(values)

範例 · 原始碼 · 傳回透過指定 values 陣列的均勻非有理 B 樣條插補器,其中必須是數字。

js
d3.interpolateBasisClosed([0, 0.1, 0.4, 1])(0.5) // 0.45

控制點會隱含重複,以便在 [0,1] 中重複 t 時,產生的單一維度樣條具有循環 C² 連續性。另請參閱 curveBasisClosedinterpolateRgbBasisClosed

interpolateDiscrete(values)

範例 · 原始碼 · 傳回給定 values 陣列的離散插補器。

js
d3.interpolateDiscrete(["red", "blue", "green"])(0.5) // "blue"

傳回的插補器會將 [0, 1 / n) 中的 t 對應到 values[0],將 [1 / n, 2 / n) 中的 t 對應到 values[1],依此類推,其中 n = values.length。實際上,這是一個輕量級 量化比例尺,其固定網域為 [0, 1]。

quantize(interpolator, n)

範例 · 原始碼 · 傳回從指定 interpolator 均勻間隔取樣的 n 個樣本,其中 n 是大於 1 的整數。

js
d3.quantize(d3.interpolate("red", "blue"), 4) // ["rgb(255, 0, 0)", "rgb(170, 0, 85)", "rgb(85, 0, 170)", "rgb(0, 0, 255)"]

第一個範例總是位於 t = 0,最後一個範例總是位於 t = 1。這在從給定的內插器產生固定數量的範例時很有用,例如從 量化比例 中衍生 連續內插器 的範圍。

注意

此方法不適用於不會傳回其輸出防禦性副本的內插器,例如 interpolateArrayinterpolateDateinterpolateObject。對於這些內插器,您必須包裝內插器並為每個傳回的值建立一個副本。

piecewise(interpolate, values)

範例 · 來源 · 傳回分段內插器,為每個相鄰的 values 對組成內插器。

js
d3.piecewise(d3.interpolateRgb.gamma(2.2), ["red", "green", "blue"])

如果未指定 interpolate,則預設為 interpolate

js
d3.piecewise(["red", "green", "blue"])

傳回的內插器將 [0, 1 / (n - 1)] 中的 t 對應到 interpolate(values[0], values[1]),將 [1 / (n - 1), 2 / (n - 1)] 中的 t 對應到 interpolate(values[1], values[2]),依此類推,其中 n = values.length。實際上,這是一個輕量級的 線性比例