值插值
🌐 Value interpolation
这些是最通用的插值器,适用于大多数值。
🌐 These are the most general interpolators, suitable for most values.
插值(a, b)
🌐 interpolate(a, b)
示例 · 来源 · 返回一个在两个任意值 a 和 b 之间的插值器。
d3.interpolate("red", "blue")(0.5) // "rgb(128, 0, 128)"插值器的实现基于终值 b 的类型,使用以下算法:
🌐 The interpolator implementation is based on the type of the end value b, using the following algorithm:
- 如果 b 为 null、undefined 或布尔值,请使用常量 b。
- 如果 b 是一个数字,使用 interpolateNumber。
- 如果 b 是一个 颜色 或者可以转换为颜色的字符串,请使用 interpolateRgb。
- 如果 b 是一个 日期,使用 interpolateDate。
- 如果 b 是一个字符串,使用 interpolateString。
- 如果 b 是一个数字的类型化数组,请使用 interpolateNumberArray。
- 如果 b 是一个通用 数组,请使用 interpolateArray。
- 如果b可以被强制转换为数字,请使用interpolateNumber。
- 使用 interpolateObject。
根据所选的插值器,a 会被强制转换为相应的适当类型。
🌐 Based on the chosen interpolator, a is coerced to the suitable corresponding type.
插值数字(a, b)
🌐 interpolateNumber(a, b)
示例 · 来源 · 返回两个数字 a 和 b 之间的插值器。
d3.interpolateNumber(20, 620)(0.8) // 500返回的插值器等同于:
🌐 The returned interpolator is equivalent to:
function interpolator(t) {
return a * (1 - t) + b * t;
}小心
在使用插值器生成字符串时,避免插值到零或从零开始。当非常小的值被转换为字符串时,它们可能会被转换为科学计数法,在旧版浏览器中这是无效的属性或样式属性值。例如,数字 0.0000001 被转换为字符串 "1e-7"。在插值透明度时,这种情况尤其明显。为避免科学计数法,请从或结束过渡值为 1e-6:这是不会以科学计数法字符串化的最小值。
interpolateRound(a, b)
示例 · 来源 · 返回一个在两个数字 a 和 b 之间的插值器。
d3.interpolateRound(20, 620)(0.821) // 513插值器类似于 interpolateNumber,只不过它会将结果值四舍五入到最接近的整数。
🌐 The interpolator is similar to interpolateNumber except it will round the resulting value to the nearest integer.
interpolateString(a, b)
示例 · 来源 · 返回一个在两个字符串 a 和 b 之间的插值器。
d3.interpolateString("20px", "32px")(0.5) // "26px"字符串插值器会在 a 和 b 中找到嵌入的数字,每个数字的形式都为 JavaScript 可理解的形式。在字符串中可以检测到的一些数字示例包括:-1、42、3.14159 和 6.0221413e+23。
🌐 The string interpolator finds numbers embedded in a and b, where each number is of the form understood by JavaScript. A few examples of numbers that will be detected within a string: -1, 42, 3.14159, and 6.0221413e+23.
对于嵌入在 b 中的每个数字,插值器将尝试在 a 中找到对应的数字。如果找到对应的数字,则使用 interpolateNumber 创建一个数字插值器。字符串 b 的其余部分用作模板:字符串 b 的静态部分在插值过程中保持不变,插入的数字值嵌入到模板中。
🌐 For each number embedded in b, the interpolator will attempt to find a corresponding number in a. If a corresponding number is found, a numeric interpolator is created using interpolateNumber. The remaining parts of the string b are used as a template: the static parts of the string b remain constant for the interpolation, with the interpolated numeric values embedded in the template.
例如,如果 a 为 "300 12px sans-serif",b 为 "500 36px Comic-Sans",则会发现两个嵌入的数字。剩余的静态部分(字符串 b 的)是两个数字之间的空格(" ")和后缀("px Comic-Sans")。在 t = 0.5 时插值器的结果是 "400 24px Comic-Sans"。
🌐 For example, if a is "300 12px sans-serif", and b is "500 36px Comic-Sans", two embedded numbers are found. The remaining static parts (of string b) are a space between the two numbers (" "), and the suffix ("px Comic-Sans"). The result of the interpolator at t = 0.5 is "400 24px Comic-Sans".
interpolateDate(a, b)
示例 · 来源 · 返回两个 日期 a 和 b 之间的插值器。
d3.interpolateDate(new Date("2014-01-01"), new Date("2024-01-01"))(0.5) // 2019-01-01小心
返回的日期没有创建防御性副本;每次评估插值器时返回的都是同一个 Date 实例。未进行副本复制是出于性能考虑,因为插值器通常是动画过渡内部循环的一部分。
interpolateArray(a, b)
d3.interpolateArray([0, 0, 0], [1, 2, 3])(0.5) // [0.5, 1, 1.5]如果 b 是一个类型化数组(例如,Float64Array),则会调用 interpolateNumberArray 。
🌐 If b is a typed array (e.g., Float64Array), interpolateNumberArray is called instead.
在内部,会创建一个数组模板,其长度与 b 相同。对于 b 中的每个元素,如果在 a 中存在对应的元素,则使用 interpolate 为这两个元素创建一个通用插值器。如果不存在这样的元素,则模板中使用 b 中的静态值。然后,对于给定的参数 t,对模板中嵌入的插值器进行评估。随后返回更新后的数组模板。
🌐 Internally, an array template is created that is the same length as b. For each element in b, if there exists a corresponding element in a, a generic interpolator is created for the two elements using interpolate. If there is no such element, the static value from b is used in the template. Then, for the given parameter t, the template’s embedded interpolators are evaluated. The updated array template is then returned.
例如,如果 a 是数组 [0, 1],b 是数组 [1, 10, 100],那么插值器在 t = 0.5 时的结果是数组 [0.5, 5.5, 100]。
🌐 For example, if a is the array [0, 1] and b is the array [1, 10, 100], then the result of the interpolator for t = 0.5 is the array [0.5, 5.5, 100].
小心
没有创建模板数组的防御性副本;返回的数组修改可能会对插值器的后续评估产生不利影响。出于性能原因,不会创建副本;插值器通常是动画过渡内部循环的一部分。
interpolateNumberArray(a, b)
d3.interpolateNumberArray([0, 1], Float64Array.of(1, 3))(0.5) // [0.5, 2]在内部,会创建一个数组模板,其类型和长度与 b 相同。对于 b 中的每个元素,如果在 a 中存在对应的元素,则将值直接插入数组模板中。如果没有这样的元素,则复制 b 中的静态值。然后返回更新后的数组模板。
🌐 Internally, an array template is created that is the same type and length as b. For each element in b, if there exists a corresponding element in a, the values are directly interpolated in the array template. If there is no such element, the static value from b is copied. The updated array template is then returned.
小心
不会对模板数组和参数 a 与 b 制作防御性副本;对这些数组的修改可能会影响后续对插值器的评估。
interpolateObject(a, b)
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,评估模板中嵌入的插值器,并返回更新后的对象模板。
🌐 Internally, an object template is created that has the same properties as b. For each property in b, if there exists a corresponding property in a, a generic interpolator is created for the two elements using interpolate. If there is no such property, the static value from b is used in the template. Then, for the given parameter t, the template's embedded interpolators are evaluated and the updated object template is then returned.
例如,如果 a 是对象 {x: 0, y: 1},b 是对象 {x: 1, y: 10, z: 100},则插值器在 t = 0.5 时的结果是对象 {x: 0.5, y: 5.5, z: 100}。
🌐 For example, if a is the object {x: 0, y: 1} and b is the object {x: 1, y: 10, z: 100}, the result of the interpolator for t = 0.5 is the object {x: 0.5, y: 5.5, z: 100}.
对象插值对于数据空间插值特别有用,在这种情况下插值的是数据而不是属性值。例如,你可以插值一个描述饼图中弧的对象,然后使用 arc 来计算新的 SVG 路径数据。
🌐 Object interpolation is particularly useful for dataspace interpolation, where data is interpolated rather than attribute values. For example, you can interpolate an object which describes an arc in a pie chart, and then use arc to compute the new SVG path data.
小心
没有创建模板对象的防御性副本;返回对象的修改可能会对插值器的后续评估产生不利影响。出于性能原因,不会创建副本;插值器通常是动画过渡内部循环的一部分。
interpolateBasis(values)
示例 · 来源 · 返回一个一致的非有理B样条插值器,通过指定的 values 数组,该数组必须是数字。
d3.interpolateBasis([0, 0.1, 0.4, 1])(0.5) // 0.2604166666666667隐式控制点是生成的,以便插值器在 t = 0 时返回 values[0],在 t = 1 时返回 values[values.length - 1]。另请参见 curveBasis 和 interpolateRgbBasis。
🌐 Implicit control points are generated such that the interpolator returns values[0] at t = 0 and values[values.length - 1] at t = 1. See also curveBasis and interpolateRgbBasis.
interpolateBasisClosed(values)
示例 · 来源 · 返回一个一致的非有理B样条插值器,通过指定的 values 数组,该数组必须是数字。
d3.interpolateBasisClosed([0, 0.1, 0.4, 1])(0.5) // 0.45控制点被隐式重复,使得当在 [0,1] 中绕 t 重复时,得到的一维样条具有循环的 C² 连续性。另请参见 curveBasisClosed 和 interpolateRgbBasisClosed。
🌐 The control points are implicitly repeated such that the resulting one-dimensional spline has cyclical C² continuity when repeated around t in [0,1]. See also curveBasisClosed and interpolateRgbBasisClosed.
interpolateDiscrete(values)
示例 · 来源 · 返回给定 values 数组的离散插值器。
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] 的轻量级 量化比例。
🌐 The returned interpolator maps t in [0, 1 / n) to values[0], t in [1 / n, 2 / n) to values[1], and so on, where n = values.length. In effect, this is a lightweight quantize scale with a fixed domain of [0, 1].
quantize(interpolator, n)
示例 · 来源 · 从指定的 插值器 返回 n 个均匀间隔的样本,其中 n 是大于一的整数。
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。这在从给定的插值器生成固定数量的样本时非常有用,例如从 连续插值器 推导出 量化比例 的范围。
🌐 The first sample is always at t = 0, and the last sample is always at t = 1. This can be useful in generating a fixed number of samples from a given interpolator, such as to derive the range of a quantize scale from a continuous interpolator.
小心
此方法不适用于不返回其输出防御性副本的插值器,例如 interpolateArray、interpolateDate 和 interpolateObject。对于这些插值器,你必须封装插值器并为每个返回的值创建一个副本。
分段(interpolate, values)
🌐 piecewise(interpolate, values)
示例 · 来源 · 返回一个分段插值器,组合每对相邻值的插值器。
d3.piecewise(d3.interpolateRgb.gamma(2.2), ["red", "green", "blue"])如果未指定 interpolate,则默认为 interpolate。
🌐 If interpolate is not specified, defaults to interpolate.
d3.piecewise(["red", "green", "blue"])返回的插值器将 t 在 [0, 1 / (n - 1)] 映射到 interpolate(values[0], values[1]),t 在 [1 / (n - 1), 2 / (n - 1)] 映射到 interpolate(values[1], values[2]),依此类推,其中 n = values.length。实际上,这是一种轻量级的线性比例。
🌐 The returned interpolator maps t in [0, 1 / (n - 1)] to interpolate(values[0], values[1]), t in [1 / (n - 1), 2 / (n - 1)] to interpolate(values[1], values[2]), and so on, where n = values.length. In effect, this is a lightweight linear scale.