d3-interpolate
此模块提供了用于在两个值之间进行混合的各种插值方法。值可以是数字,颜色,字符串,数组,甚至是深层嵌套的对象。例如:
var i = d3.interpolateNumber(10, 20);
i(0.0); // 10
i(0.2); // 12
i(0.5); // 15
i(1.0); // 20
返回的函数i
称为interpolator(插值器)。给定起始值a和结束值b,它在domain[0,1]中取参数t并返回a和b之间的相应插值。插值器通常返回等效的值,即a对应t = 0、b对应t = 1。
你可以插入的不仅仅是数字。要找到steelblue和brown之间的感知中点:
d3.interpolateLab("steelblue", "brown")(0.5); // "rgb(142, 92, 109)"
下面是一个更详细的示例,演示了插值使用的类型推断:
var i = d3.interpolate({colors: ["red", "blue"]}, {colors: ["white", "black"]});
i(0.0); // {colors: ["rgb(255, 0, 0)", "rgb(0, 0, 255)"]}
i(0.5); // {colors: ["rgb(255, 128, 128)", "rgb(0, 0, 128)"]}
i(1.0); // {colors: ["rgb(255, 255, 255)", "rgb(0, 0, 0)"]}
请注意,通用值插值器不仅检测嵌套对象和数组,还检测嵌入字符串中的颜色字符串和数字!
Installing
如果你使用npm,请键入npm install d3-interpolate
。否则,请下载最新版本。你也可以直接从d3js.org加载,作为standalone library(独立库)或D3 4.0的一部分来使用。支持AMD,CommonJS和vanilla环境。在vanilla环境下,会输出一个全局的d3
:
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script>
var interpolate = d3.interpolateRgb("steelblue", "brown");
</script>
API Reference
d3.interpolate(a, b)
返回两个任意值a和b之间的插值器。插值器基于最终值b的类型实现,使用以下算法:
- 如果b为null、undefined或布尔值,则使用常量b。
- 如果b为数字,则使用interpolateNumber。
- 如果b为颜色或可强制转换为颜色的字符串,则使用interpolateRgb。
- 如果b为日期,则使用interpolateDate。
- 如果b为字符串,则使用interpolateString。
- 如果b为数组,则使用interpolateArray。
- 如果b可以强制转换为数字,则使用interpolateNumber。
- 使用interpolateObject。
基于选择的内插器,a被强制转换为合适的对应类型。
d3.interpolateNumber(a, b)
返回两个数字a和b之间的插值器。返回的插值器相当于:
function interpolator(t) {
return a * (1 - t) + b * t;
}
注意:使用插值器生成字符串时,应避免插入数字0或从数字0插入。当非常小的值被字符串化时,可能会将其转换为科学记数法,这在旧版浏览器中是无效属性或样式属性值。例如,数字0.0000001
会被转换为字符串"1e-7"
。这在插入不透明度时尤其明显。为避免科学记数法,在1e-6处开始或结束过渡:未用科学记数法字符串化的最小值。
d3.interpolateRound(a, b)
返回两个数字a和b之间的插值器;此插值器类似于interpolateNumber,除了它会将结果值四舍五入为最接近的整数。
d3.interpolateString(a, b)
返回两个字符串a和b之间的插值器。字符串插值器会查找嵌入在a和b中的数字,其中每个数字都是JavaScript可以理解的形式。在字符串内会被检测的几个数字例子:-1
,42
,3.14159
,和6.0221413e+23
。
对于嵌入在b中的每个数字,插值器将尝试在a中找到相应的数字。如果找到相应的数字,则使用interpolateNumber创建数字插值器。字符串b的其余部分将被用作模板:当插值数值嵌入模板中时,字符串b的静态部分对于插值保持常量。
例如,如果a是"300 12px sans-serif"
,而b是"500 36px Comic-Sans"
,则找到两个嵌入的数字。字符串的其余静态部分是两个数字(" "
)和后缀("px Comic-Sans"
)之间的空格。插值器在t = 0.5时的结果是"400 24px Comic-Sans"
。
d3.interpolateDate(a, b)
返回两个日期 a和b之间的插值器。
注意:没有创建返回日期的防御副本 ;针对插值器的每次求值返回相同的Date实例。由于性能原因没有复制;插值器通常是动画过渡的内部循环的一部分。
d3.interpolateArray(a, b)
返回两个数组a和b之间的插值器。在内部,创建一个与b的长度相同的数组模板。对于每个元素b,如果在a中存在一个相应元素,则使用interpolate为两个元素创建一个通用插值器。如果不存在这样的元素,则在模板中使用来自b的静态值。然后,对于给定的参数t,对模板嵌入的插值器求值。然后返回更新的数组模板。
例如,如果a是数组[0, 1]
而b是数组[1, 10, 100]
,则t = 0.5 的插值器的结果就是数组[0.5, 5.5, 100]
。
注意:没有创建模板数组的防御副本 ;对返回数组的修改可能会对插值器的后续求值产生不利影响。由于性能原因没有复制;插值器器通常是动画过渡的内部循环的一部分。
d3.interpolateObject(a, b)
返回两个对象a和b之间的插值器。在内部,创建一个与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}
。
对象插值对于dataspace interpolation(数据空间)插值特别有用,插值的是数据而不是属性值。例如,可以在饼图中插入一个描述圆弧的对象,然后使用d3.svg.arc计算新的SVG路径数据。
注意:没有创建模板对象的防御副本 ;对返回对象的修改可能会对插值器的后续求值产生不利影响。由于性能原因没有复制; 插值器通常是动画过渡的内部循环的一部分。
d3.interpolateTransformCss(a, b)
返回由a和b表示的两个2D CSS转换之间的插值器。每个转换都被分解为一个标准的表示形式,即translate,rotate,x- skew和scale;然后插入这些分量转换。此行为由CSS标准化:请参阅动画的矩阵分解。
d3.interpolateTransformSvg(a, b)
返回由a和b表示的两个2D SVG转换之间的插值器。每个转换都被分解为一个标准的表示形式,即translate,rotate,x- skew和scale;然后插入这些分量转换。此行为由CSS标准化:请参阅动画的矩阵分解。
d3.interpolateZoom(a, b)
基于Jarke J. van Wijk和Wim AA Nuij的“Smooth and efficient zooming and panning”,返回二维平面的两个视图a和b之间的插值器。每个视图被定义为三个数字的数组:cx,cy和width。前两个坐标cx,cy代表视口的中心;最后一个坐标width表示视口的大小。
返回的插值器公开了一个duration属性,它以毫秒为单位对推荐的转换持续时间进行编码。该持续时间基于产国x,y空间的弯曲轨迹的路径长度。如果你想要更慢或更快的转换,请将其乘以任意比例因子(V,如原稿中所述)。
Sampling
d3.quantize(interpolator, n)
从指定的interpolator返回n个均匀间隔样本,其中n是大于1的整数。第一个样本总是在t = 0处,而最后一个样本总是在t = 1 处。这对于从给定插值器生成固定数量的样本是有用的,例如从连续插值器中导出量化比例尺的range。
警告:此方法不适用于不返回其输出的防御副本的插值器,如d3.interpolateArray,d3.interpolateDate和d3.interpolateObject。对于这些插值器,你必须包装插值器并为每个返回的值创建一个副本。
Color Spaces
d3.interpolateRgb(a, b)
或者,使用修正后的gamma 2.2:
使用可配置的gamma返回两种颜色a和b之间的RGB颜色空间插值器。如果不指定gamma,则默认为1.0。颜色a和b不需要在RGB中;他们将使用d3.rgb转换为RGB 。插值器的返回值是一个RGB字符串。
d3.interpolateRgbBasis(colors)
通过指定的colors数组返回一个统一的非理性B样条插值器,并将其转换为RGB颜色空间。隐式地生成控制点,使得插值器在t = 0时返回colors[0],在t = 1时返回colors[colors.length - 1]。不透明度插值目前不支持。有关示例,另请参阅d3.interpolateBasis,并参见d3-scale-chromatic的示例。
d3.interpolateRgbBasisClosed(colors)
通过指定的colors数组返回一个统一的非理性B样条插值器,并将其转换为RGB颜色空间。隐式地重复控制点,使得在[0,1]中围绕t周围重复时,结果样条具有周期性的C²连续性;这是有用的,例如,创建周期性颜色比例尺。目前不支持不透明度插值。另请参阅d3.interpolateBasisClosed,并参见d3-scale-chromatic的示例。
d3.interpolateHsl(a, b)
返回两种颜色a和b之间的HSL颜色空间插值器。颜色a和b不需要在HSL中;它们将使用d3.hsl转换为HSL 。如果任一颜色的色相或饱和度是NaN,则使用相对颜色的通道值。使用色相之间的最短路径。插值器的返回值是一个RGB字符串。
d3.interpolateHslLong(a, b)
像interpolateHsl一样,但不使用色相之间的最短路径。
d3.interpolateLab(a, b)
返回两种颜色a和b之间的Lab颜色空间插值器。颜色a和b不需要在Lab中; 他们将使用d3.lab转换为Lab 。插值器的返回值是一个RGB字符串。
d3.interpolateHcl(a, b)
返回两种颜色a和b之间的HCL颜色空间插值器。颜色a和b不需要在HCL中; 他们将使用d3.hcl转换为HCL 。如果任何一种颜色的色相或色度是NaN,则使用相对颜色的通道值。使用色相之间的最短路径。插值器的返回值是一个RGB字符串。
d3.interpolateHclLong(a, b)
像interpolateHcl一样,但不使用色相之间的最短路径。
d3.interpolateCubehelix(a, b)
或者,用3.0 的gamma强调高强度值:
使用可配置的gamma,返回两种颜色a和b之间的Cubehelix颜色空间插值器。如果不指定gamma,则默认为1.0。颜色a和b不一定在Cubehelix中;他们将使用d3.cubehelix转换为Cubehelix。如果任一颜色的色相或饱和度是NaN,则使用相对颜色的通道值。使用色相之间的最短路径。插值器的返回值是一个RGB字符串。
d3.interpolateCubehelixLong(a, b)
或者,用3.0 的gamma强调高强度值:
像interpolateCubehelix一样,但不使用色相之间的最短路径。
interpolate.gamma(gamma)
如果interpolate是interpolateRgb,interpolateCubehelix或interpolateCubehelixLong之一,则使用指定的gamma返回相同类型的新插值器工厂函数。例如,要在RGB空间中以2.2的gamma从紫色插值到橙色:
var interpolator = d3.interpolateRgb.gamma(2.2)("purple", "orange");
有关伽马校正的更多信息,请参阅Eric Brasseur的文章,Gamma error in picture scaling。
Splines
鉴于标准插值器从起始值a在t = 0到结束值b在t = 1进行混合,样条插值器为平滑混合多个在[0,1]中的输入值t而使用分段多项式函数。目前仅支持三次均匀非理性B样条,也称为basis splines(基函数样条)。
d3.interpolateBasis(values)
通过指定的values数组返回一个统一的非理性B样条插值器,它必须是数字。生成隐式控制点,使得插值器在t = 0时返回values[0],在t = 1时返回values[values.length - 1]。另请参阅d3.curveBasis。
d3.interpolateBasisClosed(values)
通过指定的values数组返回一个统一的非理性B样条插值器,它必须是数字。隐式地重复控制点,使得在[0,1] 中围绕t重复时,产生的一维样条具有周期性的C²连续性。另请参阅d3.curveBasisClosed。