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, 传入一个范围在 [0, 1] 之间的参数 t 会返回一个对应的在 a 和 b 之间的值。插值器通常在 t = 0 时候返回 a, 并且在 t = 1 时返回 b.
你可以对数值之外的其他值进行插值。比如返回 steelblue
和 brown
之间感知上处于中点的颜色:
d3.interpolateLab("steelblue", "brown")(0.5); // "rgb(142, 92, 109)"
下面是一个更详细的例子说明 interpolate 的类型推断:
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
. 此外还可以下载 latest release. 你可以直接从 d3js.org 作为 standalone library 或作为 D3 4.0 的一部分直接引入. 支持 AMD
, CommonJS
以及基本的标签引入形式。如果使用标签引入则会暴露全局 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
或者boolean
, 则使用常量 b. - 如果 b 为
number
, 使用 interpolateNumber. - 如果 b 为 color 或可以转为颜色的字符串, 使用 interpolateRgb.
- 如果 b 为 date, 使用 interpolateDate.
- 如果 b 为
string
, 使用 interpolateString. - 如果 b 为 array, 使用 interpolateArray.
- 如果 b 可以转为
number
, 使用 interpolateNumber. - 使用 interpolateObject.
基于选中的插值器,a 会被强制转为对应的类型.
d3.interpolateNumber(a, b) <>
返回一个在两个数值 a 和 b 之间插值的插值器。返回的插值器等价于:
function interpolator(t) {
return a * (1 - t) + b * t;
}
警告: 避免以 0
作为插值的起点或终点因为可能会生成字符串。当数字非常小的时候会使用科学计数法表示,这种标记可能会被解析为错误的属性或样式值。比如,数值 0.0000001
会被转为字符串 "1e-7"
。这种现象在对不透明度插值时会尤其明显。为避免科学计数法,可以起于或结束于 1e-6
:科学计数法中没有被字符串化的最小值。
d3.interpolateRound(a, b) <>
返回一个在两个数值 a 和 b 之间插值的插值器; 这个插值器与 Sampling
d3.quantize(interpolator, n) <>
根据指定的 interpolator 返回 n 个等间隔的均匀采样, 其中 n 是一个大于 1
的整数。第一个采样点总是取 t = 0 时的值而最后一个值总是取 t = 1 处的值。这个方法可以从给定的插值器中取固定数量的等间隔的值, 比如从 continuous interpolator 中推导 quantize scale。
警告: 这种方法不适用于不返回副本的插值器, 比如 Color Spaces
d3.interpolateRgb(a, b) <>
或者, 使用 2.2
修正的 gamma:
返回一个在两个颜色 a 和 b 之间插值的 RGB
颜色空间插值器, 其中包含可配置参数 gamma。如果没有指定 gamma
则默认为 1.0
。颜色 a 和 b 不需要非要是 RGB
空间;可以使用 d3.rgb 转为 RGB
颜色即可。插值器返回的结果使用 RGB
字符串表示.
Returns an RGB color space interpolator between the two colors a and b with a configurable gamma. If the gamma is not specified, it defaults to 1.0. The colors a and b need not be in RGB; they will be converted to RGB using d3.rgb. The return value of the interpolator is an RGB string.
"https://github.com/d3/d3-interpolate/blob/master/src/rgb.js" title="Source" target="_blank" rel="noopener noreferrer"><>
根据指定的颜色数组返回一个 uniform nonrational
B-样条插值器, 这些颜色都会被转为 RGB color space。隐式控制点的生成会使得 t = 0 时返回 colors[0] 并且在 t = 1 时返回 [colors.length - 1]。目前支持不透明度的插值.参考 d3.interpolateBasis 和 d3-scale-chromatic 获取更多例子。
"https://github.com/d3/d3-interpolate/blob/master/src/rgb.js" title="Source" target="_blank" rel="noopener noreferrer"><>
根据指定的颜色数组返回一个 uniform nonrational
B-样条插值器, 这些颜色都会被转为 RGB color space。隐式的控制点是重复的,这样在 t 处于 [0, 1] 时返回的结果是循环重复的。创建一个循环颜色比例尺时是有用的。目前支持不透明度的插值.参考 d3.interpolateBasis 和 d3-scale-chromatic 获取更多例子。
d3.interpolateHsl(a, b) <>
在两个颜色 a 和 b 之间创建一个 HSL
颜色空间的插值器。a 和 b 不一定使用 HSL
表示,它们将会适用 d3.hsl 转为 HSL
表示. 如果其中一个颜色的 hue
或 saturation
为 NaN
则使用相反的颜色通道值。最短路径的 hues
将会被使用。返回的值使用 RGB
字符串表示.
d3.interpolateHslLong(a, b) <>
与 interpolateHsl 类似, 但是不使用 hues
之间的最短路径.
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
表示. 如果其中一个颜色的 hue
或 chroma
为 NaN
则使用相反的颜色通道值。最短路径的 hues
将会被使用。返回的值使用 RGB
字符串表示.
d3.interpolateHclLong(a, b) <>
与 interpolateHcl 类似, 但是不使用 hues
之间的最短路径.
d3.interpolateCubehelix(a, b) <>
或者使用 gamma = 3.0 来强调高亮度的值:
返回一个在两个颜色 a 和 b 之间可配置 gamma 的 Cubehelix
颜色空间插值器。如果没有指定 gamma
则默认为 1.0. 颜色值 a 和b 不一定必须为 Cubehelix
;在内部会使用 d3.cubehelix 将其转换为 Cubehelix
表示。如果其中一个颜色值得 hue
或 saturation
为 NaN
, 则相反的颜色通道值会使用。会在两个颜色值之间最短的 hue
路径之间插值,返回值是一个 RGB
字符串。
d3.interpolateCubehelixLong(a, b) <>
或者使用 gamma = 3.0 来强调高亮度的值:
与 interpolateCubehelix 类似, 但是不是使用两个 hues
值之间的最短路径.
interpolate.gamma(gamma)
给定的 interpolate 为 interpolateRgb, interpolateCubehelix 或 interpolateCubehelixLong 中的一种, 使用指定的 gamma 值返回一个新的同类型的插值器. 例如使用 gamma 为 2.2 且在 purple
和 orange
之间进行 RGB
颜色插值的插值器:
var interpolator = d3.interpolateRgb.gamma(2.2)("purple", "orange");
参考 Eric Brasseur
的文章 Gamma error in picture scaling 获取更多关于 gamma 修正的资料.
Splines
标准的插值器会在起始值 t = 0 时的 a 和 t = 1 时的 b 之间计算得出一个适当的值。而样条曲线插值器可以使用分段多项式函数为多个介于 [0,1] 之间的输入值进行光滑插值。目前只支持三次无理 B-splines,也就是基本样条曲线。
Piecewise
d3.piecewise(interpolate, values) <>
根据指定的 values 数组返回一个分段的插值器, 其中数组中每两个相邻的值之间会创建一个单独的插值器。返回的插值器在 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,以此类推。从结果来看,这是一个轻量级的 linear scale。例如创建一个在 red
, green
和 blue
之间创建一个插值器:
var interpolate = d3.piecewise(d3.interpolateRgb.gamma(2.2), ["red", "green", "blue"]);