d3-scale

对于可视化来说,比例尺是一个很方便的工具:将抽象的维度数据映射为可视化表示。虽然经常使用位置编码定量数据,比如将测量单位米使用像素映射。但是比例尺可以对任何视觉编码进行映射,比如颜色,描边的宽度或者符号的大小。比例尺也可以用来对任意类型的数据进行映射,比如分类数据或离散的数据。

对于 continuous(连续的) 定量数据,通常会使用 linear scale(线性比例尺). (对于时间序列则使用 time scale(时间比例尺).) 如果需要也可以使用 power(幂)log(对数) 比例尺。quantize scale(量化比例尺) 可以将连续数据四舍五入到一组固定的离散值中,可以用来生成离散数据。类似的 quantile scale(分位数比例尺) 从样本总体计算分位数,而 threshold scale(阈值比例尺) 可以为一组连续数据指定分割阈值。

对于离散的顺序(有序)或者分类(无序)数据,ordinal scale(序数比例尺) 指定从一组数据值到一组相应视觉属性的显式映射(比如颜色)。相关的 bandpoint 在对分类数据进行位置编码时很有用,如条形图以及分类散点图。

这个模块不会提供颜色方案,可以参考 d3-scale-chromatic 来获取需要的颜色方案。

比例尺没有具体的视觉表现。但是大多数的比例尺可以在显示比例尺的参考轴时候 generate(生成)format(格式化) 刻度。

更多比例尺的介绍可以参考以下推荐的教程:

Installing

NPM 安装:npm install d3-scale. 此外还可以下载 latest release. 可以直接从 d3js.orgstandalone library 或作为 D3 的一部分直接引入。支持 AMD, CommonJS 以及基本的标签引入形式。如果使用标签引入则会暴露全局 d3 变量:

<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-format.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-time.v1.min.js"></script>
<script src="https://d3js.org/d3-time-format.v2.min.js"></script>
<script src="https://d3js.org/d3-scale.v2.min.js"></script>
<script>

var x = d3.scaleLinear();

</script>

(如果不使用 d3.scaleTime or d3.scaleUtc 则可以忽略d3-timed3-time-format.)

API Reference

Continuous Scales

连续比例尺可以将连续的、定量的输入 domain 映射到连续的输入 range。如果输出范围也是数值则这种映射关系可以被 inverted(反转)。连续比例尺是一类比例尺,不能直接使用,可以使用 linear, power, log, identity, timesequential color.

# continuous(value) <>

根据给定的位于 domain 中的 value 返回对应的位于 range 中的值。如果给定的 value 不在 domain 中,并且 clamping 没有启用,则返回的对应的值也会位于 range 之外,这种映射值推算出来的。例如:

var x = d3.scaleLinear()
    .domain([10, 130])
    .range([0, 960]);

x(20); // 80
x(50); // 320

或者将数值映射为颜色:

var color = d3.scaleLinear()
    .domain([10, 100])
    .range(["brown", "steelblue"]);

color(20); // "#9a3439"
color(50); // "#7b5167"

# continuous.invert(value) <>

根据给定的位于 range 中的 value 返回对应的位于 domain 的值。反向映射在交互中通常很有用,根据鼠标的位置计算对应的数据范围。例如:

var x = d3.scaleLinear()
    .domain([10, 130])
    .range([0, 960]);

x.invert(80); // 20
x.invert(320); // 50

如果给定的 value 位于 range 外面,并且没有启用 clamping 则会推算出对应的位于 domain 之外的值。这个方法仅仅在 range 为数值时有用。如果 range 不是数值类型则返回 NaN.

对于有效的处于 range 中的 y 值,continuous(continuous.invert(y)) 近似等于 y;同理对于有效的 x 值,continuous.invert(continuous(x)) 近似等于 x。因为浮点数精度问题,比例尺和它的反推可能不精确。

# continuous.domain([domain]) <>

如果指定了 domain 则将比例尺的 domain 设置为指定的数值数组。数组比例包含两个或者两个以上元素。如果给定的数组中的元素不是数值类型,则会被强制转为数值类型。如果没有指定 domain 则会返回当前比例尺的 domain 的拷贝。

尽管对于连续比例尺来说,doamin 通常包含两个值就可以,但是指定多个值的话会生成一个分段的比例尺。比如创建一个 diverging color scale(分段的颜色比例尺),当值为负时在白色和红色之间插值,当值为正时在白色和绿色之间插值:

var color = d3.scaleLinear()
    .domain([-1, 0, 1])
    .range(["red", "white", "green"]);

color(-0.5); // "rgb(255, 128, 128)"
color(+0.5); // "rgb(128, 192, 128)"

在内部,分段比例尺根据给定的 domain 的值 range 插值器进行 binary search。因此 domain 必须是有序的。如果 domainrange 的长度不一样分别为 NM 则只有 min(N,M) 个元素会被使用。

# continuous.range([range]) <>

如果指定了 range 则将比例尺的 range 设置为指定的数组。数组必须包含两个或两个以上元素。与 domain 不同的是,range 中的元素不一定非要为数值类型。任何支持 interpolator 的类型都可以被设置。但是要注意的是如果要使用 invertrange 必须指定为数值类型. 如果 range 没有指定则返回比例尺当前 range 的拷贝。参考 continuous.interpolate 获取更多例子。

# continuous.rangeRound([range]) <>

设置比例尺的 range 为指定的数组同时设置比例尺的 interpolatorinterpolateRound. 这是一个便捷方法等价于:

continuous
    .range(range)
    .interpolate(d3.interpolateRound);

启用插值器的四舍五入有时对避免反锯齿有用,当然也可以使用 shape-rendering 的“crispEdges” 样式. 注意这种只针对数值类型的 range 有效。

# continuous.clamp(clamp) <>

如果指定了 clamp 则启用或者关闭比例尺的钳位功能。如果没有启用钳位功能,则当传入位于 domain 之外的值时会推算出对应的、处于 range 之外的值。如果启用了钳位功能,则能保证返回的值总是处于 range。钳位功能对于 continuous.invert 也是同样的效果。例如:

var x = d3.scaleLinear()
    .domain([10, 130])
    .range([0, 960]);

x(-10); // -160, outside range
x.invert(-160); // -10, outside domain

x.clamp(true);
x(-10); // 0, clamped to range
x.invert(-160); // 10, clamped to domain

如果没有指定 clamp 则返回当前比例尺是否启用了钳位功能。

# continuous.interpolate(interpolate) <>

如果指定了 interpolate 则设置比例尺的 range 插值器。插值器函数被用来在两个相邻的来自 range 值之间进行插值;这些插值器将输入值 t 归一化到 [0, 1] 之间。如果 factory 没有指定则返回比例尺的当前插值函数。默认为 interpolate. 参考 d3-interpolate 获取更多关于插值器的介绍。

If interpolate is specified, sets the scale’s range interpolator factory. This interpolator factory is used to create interpolators for each adjacent pair of values from the range; these interpolators then map a normalized domain parameter t in [0, 1] to the corresponding value in the range. If factory is not specified, returns the scale’s current interpolator factory, which defaults to interpolate. See d3-interpolate for more interpolators.

例如,考虑输出范围为三个颜色值:

var color = d3.scaleLinear()
    .domain([-100, 0, +100])
    .range(["red", "white", "green"]);

内部会创建两个插值器,等价于:

var i0 = d3.interpolate("red", "white"),
    i1 = d3.interpolate("white", "green");

自定义插值器的一个直接的原因是可以修改插值器的颜色空间,比如使用 HCL 颜色空间:

var color = d3.scaleLinear()
    .domain([10, 100])
    .range(["brown", "steelblue"])
    .interpolate(d3.interpolateHcl);

或者自定义 Cubehelixgamma 值:

var color = d3.scaleLinear()
    .domain([10, 100])
    .range(["brown", "steelblue"])
    .interpolate(d3.interpolateCubehelix.gamma(3));

注意:default interpolator 可能复用返回值。例如,如果 range 为对象,则 range 插值器总是返回同一个修改后的对象。如果比例尺用来设置样式或者属性,则可以使用这种方式,但是如果你想存储比例尺的返回值,则必须指定自己的插值器或者适当的复制。

# continuous.ticks([count])

返回近似的用来表示比例尺 domaincount。如果没有指定 count 则默认为 10. 返回的 tick 值的个数是均匀的并且对人类友好的(比如都为 10 的整数倍),切在 domain 的范围内。ticks 经常被用来显示刻度线或者刻度标记。指定的 count 仅仅是一个参考,比例尺会根据 domain 计算具体的 ticks。可以参考 d3-arrayticks.

# continuous.tickFormat([count[, specifier]]) <>

返回一个调整小时刻度值的 number format 函数。count 应该与通过 tick values 指定的 count 相同。

Returns a number format function suitable for displaying a tick value, automatically computing the appropriate precision based on the fixed interval between tick values. The specified count should have the same value as the count that is used to generate the tick values.

可选的 specifier 允许 custom format(自定义格式),格式的精度会自动设置。比如将数字格式化为百分比:

var x = d3.scaleLinear()
    .domain([-1, 1])
    .range([0, 960]);

var ticks = x.ticks(5),
    tickFormat = x.tickFormat(5, "+%");

ticks.map(tickFormat); // ["-100%", "-50%", "+0%", "+50%", "+100%"]

如果 specifier 使用格式类型 s 则比例尺会根据 domain 的最大值返回 SI-prefix format。如果 specifier 已经指定了精度则这个方法等价于 locale.format.

# continuous.nice([count]) <>

扩展 domain 使其为整。这个方法通常会修改 domain 将其扩展为最接近的整数值。可选的 count 参数可以用来控制扩展的步长。对 domain 的取整在根据数据计算 domain 时候很有用。比如计算后的 domain 为 [0.201479…, 0.996679…] 时,在经过取整之后会被扩展为 [0.2, 1.0]。如果 domain 包含两个以上的元素,则取整操作仅仅影响第一个和最后一个值。参考 d3-arraytickStep 操作。

取整操作仅仅影响当前 domain, 不会对之后通过 continuous.domain 设置的 domain 产生影响,如果需要在重置 domain 之后重新取整,则必须在重置之后再次取整。

# continuous.copy() <>

返回一个当前比例尺的拷贝。返回的拷贝和当前比例尺之间不会相互影响。

Linear Scales

# d3.scaleLinear() <>

使用单位 domain [0, 1], 单位 range [0, 1], 以及 default interpolator 和关闭的 clamping 构造一个新的 continuous scale。线性插值器是一个很好的适用于连续定量数据的比例尺,因为它很好的保留了比例差异。每一个 range 中的值 y 都可以被表示为一个函数:y = mx + b,其中 x 为对应的 domain 中的值。

Power Scales

幂比例尺与 linear scales 类似,只不过在计算输出 range 值之前对 domain 值应用了指数变换。每一个输出值 y 可以表示为 x 的一个函数:y = mx^k + b,其中 kexponent 值。幂比例尺也支持值为负的输入值,这种情况下输入值和输出值都会被乘以 -1.

# d3.scalePow() <>

使用单位 domain [0, 1], 单位 range [0, 1], 指数 exponent 为 1, 以及 default(默认的) interpolator 并关闭 clamping 构造一个新的 continuous scale。(在设置指数之前,与线性比例尺功效一样)。

# pow(value) <>

参考 continuous.

# pow.invert(value) <>

参考 continuous.invert.

# pow.exponent([exponent]) <>

如果指定了 exponent 则将当前幂比例尺的指数设置为指定的值。如果没有指定 exponent 则返回当前的指数,默认为 1。(指数为 1 时候,与线性比例尺功效一样)。

# pow.domain([domain]) <>

参考 continuous.domain.

# pow.range([range]) <>

参考 continuous.range.

# pow.rangeRound([range]) <>

参考 continuous.rangeRound.

# pow.clamp(clamp) <>

参考 continuous.clamp.

# pow.interpolate(interpolate) <>

参考 continuous.interpolate.

# pow.ticks([count]) <>

参考 continuous.ticks.

# pow.tickFormat([count[, specifier]]) <>

参考 continuous.tickFormat.

# pow.nice([count]) <>

参考 continuous.nice.

# pow.copy() <>

参考 continuous.copy.

# d3.scaleSqrt() <>

使用单位 domain [0, 1], 单位 range [0, 1], exponent0.5, default interpolator 并关闭 clamping 构造一个新的连续的 power scale。这是 d3.scalePow().exponent(0.5) 的一个便捷方式。

Log Scales

对数比例尺与 linear scales 类似。只不过在计算输出值之前对输入值进行了对数转换。对应的 y 值可以表示为 x 的函数:y = m log(x) + b.

因为 log(0) = -∞,所以对数比例尺的输入值必须严格为负或者严格为正;输入范围必须不能包含或跨过 0. 如果将负值传递给输入范围为正的对数比例尺,则返回未定义,反之亦然。

# d3.scaleLog() <>

使用单位 domain [1, 10], 单位 range [0, 1], base(基) 为 10, default interpolator 并关闭 [clamping] 构造一个新的 continuous scale

# log(value) <>

参考 continuous.

# log.invert(value) <>

参考 continuous.invert.

# log.base([base]) <>

If base is specified, sets the base for this logarithmic scale to the specified value. If base is not specified, returns the current base, which defaults to 10.

# log.domain([domain]) <>

参考 continuous.domain.

# log.range([range]) <>

参考 continuous.range.

# log.rangeRound([range]) <>

参考 continuous.rangeRound.

# log.clamp(clamp) <>

参考 continuous.clamp.

# log.interpolate(interpolate) <>

参考 continuous.interpolate.

# log.ticks([count]) <>

continuous.ticks 类似,但是是对数比例尺特定的。如果 base 为整数,则返回的 ticks 在基的每个整数幂内间隔均匀。否则,基的每个整数次幂一个 tick。如果没有指定 count 则默认为 10.

# log.tickFormat([count[, specifier]]) <>

continuous.tickFormat 类似,但是为对数比例尺定特定的。指定的 count 通常与生成 tick values 的个数一致。如果个数太多的话,则 formatter 可能会对某些刻度返回空字符串,但是注意刻度仍然会显示。若要禁用筛选,请指定 count 为无穷大。可能还需要一个格式化 specifier 或者格式化函数。例如显示格式为货币并且刻度个数为 20 则可以定义为:log.tickFormat(20, "$,f")。如果格式化说明符没有指定精度则会自动计算。

# log.nice() <>

continuous.nice 类似,但是其实现是将 domain 扩展为 base 的整数次幂。例如对于输入域为 [0.201479…, 0.996679…], 基为 10 的比例尺,则 domain 会被扩展为 [0.1, 1]。如果 domain 有两个以上元素,则只对第一个和最后一个元素有效。

# log.copy() <>

参考 continuous.copy.

Identity Scales

恒等比例尺是 linear scales 的一种特殊情况。其输入域和值域是完全一致的;这种比例尺的映射以及反映射是完全恒等的。在处理像素坐标时,这些比例尺有时是有用的,例如与轴或画笔一起使用。恒等比例尺不支持 rangeRound, clampinterpolate.

# d3.scaleIdentity() <>

使用单元 domain [0, 1]和单元 range [0, 1] 构造一个恒等比例尺。

Time Scales

时间比例尺是 linear scales 的一种变体。它的输入被强制转为 dates 而不是数值类型,并且 invert 返回的是 date 类型。时间比例尺基于 calendar intervals 实现 ticks

例如创建一个时间-位置映射比例尺:

var x = d3.scaleTime()
    .domain([new Date(2000, 0, 1), new Date(2000, 0, 2)])
    .range([0, 960]);

x(new Date(2000, 0, 1,  5)); // 200
x(new Date(2000, 0, 1, 16)); // 640
x.invert(200); // Sat Jan 01 2000 05:00:00 GMT-0800 (PST)
x.invert(640); // Sat Jan 01 2000 16:00:00 GMT-0800 (PST)

对于合法的输出值 ytime(time.invert(y)) 等于 y; 对于合法的输入值 xtime.invert(time(x)) 等于 x. 反转方法在交互时很有用,可以确定鼠标位置与时间之间的对应关系。

# d3.scaleTime() <>

使用默认的 domain : [2000-01-01, 2000-01-02], 单位 range [0, 1] 以及 default interpolator 并关闭 clamping 构造一个新的时间比例尺。

# time(value) <>

参考 continuous.

# time.invert(value) <>

参考 continuous.invert.

# time.domain([domain]) <>

参考 continuous.domain.

# time.range([range]) <>

参考 continuous.range.

# time.rangeRound([range]) <>

参考 continuous.rangeRound.

# time.clamp(clamp) <>

参考 continuous.clamp.

# time.interpolate(interpolate) <>

参考 continuous.interpolate.

# time.ticks([count]) <>
# time.ticks([interval])

从比例尺的 domain 中返回具有代表性的日期刻度。返回的刻度值是等间距的(大多数情况下),并且是合理的(比如每天的午夜),并且保证在输入域的范围内。刻度通常被用来显示参考刻度线或者刻度标记。

可选的 count 可以用来指定生成多少刻度。如果 count 没有指定则默认为 10。指定的 count 仅仅是一个参考值。最后返回的刻度个数可能或多或少。例如,创建一个默认的刻度值则可以:

var x = d3.scaleTime();

x.ticks(10);
// [Sat Jan 01 2000 00:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 03:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 06:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 09:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 12:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 15:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 18:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 21:00:00 GMT-0800 (PST),
//  Sun Jan 02 2000 00:00:00 GMT-0800 (PST)]

如下的时间间隔在自动计算刻度时会被考虑:

  • 1-, 5-, 15- and 30-second.
  • 1-, 5-, 15- and 30-minute.
  • 1-, 3-, 6- and 12-hour.
  • 1- and 2-day.
  • 1-week.
  • 1- and 3-month.
  • 1-year.

作为 count 的替代物,可以指定一个明确的 time interval。表示根据指定的时间 interval(间隔) 使用 interval.every 生成刻度。例如,每 15-minute 生成一个刻度:

var x = d3.scaleTime()
    .domain([new Date(2000, 0, 1, 0), new Date(2000, 0, 1, 2)]);

x.ticks(d3.timeMinute.every(15));
// [Sat Jan 01 2000 00:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 00:15:00 GMT-0800 (PST),
//  Sat Jan 01 2000 00:30:00 GMT-0800 (PST),
//  Sat Jan 01 2000 00:45:00 GMT-0800 (PST),
//  Sat Jan 01 2000 01:00:00 GMT-0800 (PST),
//  Sat Jan 01 2000 01:15:00 GMT-0800 (PST),
//  Sat Jan 01 2000 01:30:00 GMT-0800 (PST),
//  Sat Jan 01 2000 01:45:00 GMT-0800 (PST),
//  Sat Jan 01 2000 02:00:00 GMT-0800 (PST)]

或者给 interval.filter 传递一个测试函数:

x.ticks(d3.timeMinute.filter(function(d) {
  return d.getMinutes() % 15 === 0;
}));

注意:在某些情况下,比如使用日期为间隔时,可能会导致刻度间隔不均匀,因为时间间隔对应的输出区间长度可能不均匀。

# time.tickFormat([count[, specifier]]) <>
# time.tickFormat([interval[, specifier]])

返回一个适用于显示日期类 tick 的格式化函数。指定的 countinterval 目前是被忽略,但是为了保持与 continuous.tickFormat 的一致性,可以这么使用。如果指定了格式化 specifier 则等价于 format。如果 specifier 没有指定则返回默认的日期格式。默认的日期格式化会从以下人类友好的格式化说明符中选择合适的:

  • %Y - 年份,比如 2011.
  • %B - 月份,比如 February.
  • %b %d - 周, 比如 Feb 06.
  • %a %d - 天, 比如 Mon 07.
  • %I %p - 时, 比如 01 AM.
  • %I:%M - 分钟, 比如 01:23.
  • :%S - 秒, 比如 :45.
  • .%L - 毫秒, 比如 .012.

虽然有些不同寻常,但这种默认的格式具有同时提供本地和全局上下文的优点: 将时间序列格式化为 [11 PM, Mon 07, 01 AM],与 [11 PM, 12 AM, 01 AM] 相比可以同时显示有关小时、日期和日期的信息,如果想自定义自己的时间格式,请参考 d3-time-format

# time.nice([count]) <>
# time.nice([interval[, step]])

扩展比例尺的 domain 使其开始和结束值更规整。这个方法会修改比例尺的 domain,并且只将其扩展到最近的整值。参考 continuous.nice

可选的刻度 count 允许对扩展步骤大小进行更精确的控制,确保返回的刻度数正好覆盖整个 domain。或者可以显示的指定一个 time interval 来设置刻度。如果指定了 interval 则还可以指定一个可选步长来跳过一些刻度。例如 time.nice(d3.timeSecond, 10) 在扩展 domain 时会根据步长 10秒 来扩展(0s, 10s, 20a 等)。参考 time.ticksinterval.every 获取详细介绍。

当输入范围根据数据计算时,取整操作很有用。例如对于时间范围 [2009-07-13T00:02, 2009-07-13T23:48] 取整后为 [2009-07-13, 2009-07-14]。如果输入域有两个以上元素,则取整只对第一个和最后一个元素生效。

# d3.scaleUtc() <>

等价于 time,但是返回的时间格式是 Coordinated Universal Time(协调世界时) 而不是当地时间。

Sequential Scales

序列比例尺,与 diverging scalescontinuous scales 类似,将连续的数字输入域映射到连续的输出域。但是与连续比例尺不一样的是,它的输出域是根据指定的插值器内置且不可配置,其次它的插值方式也不可配置。不暴露 invert, range, rangeRoundinterpolate 方法。

# d3.scaleSequential(interpolator) <>

使用跟定的 interpolator 函数构造一个新的序列比例尺。在应用比例尺时,可以传入的值 [0, 1]。其中 0 表示最小值,1 表示最大值。例如实现一个 HSL 具有周期性的颜色插值器:

var rainbow = d3.scaleSequential(function(t) {
  return d3.hsl(t * 360, 1, 0.5) + "";
});

使用 d3.interpolateRainbow 实现一种更优雅并且更高效的周期性颜色插值器:

var rainbow = d3.scaleSequential(d3.interpolateRainbow);

# sequential(value) <>

参考 continuous.

# sequential.domain([domain]) <>

参考 continuous.domain. 注意序列比例尺的输入必须是数值, 并且只包含两个值.

# sequential.clamp([clamp]) <>

参考 continuous.clamp.

# sequential.interpolator([interpolator]) <>

如果指定了 interpolate 则将比例尺的插值器设置为指定的函数。如果没有指定 interpolate 则返回当前比例尺的插值器。

# sequential.copy() <>

参考 continuous.copy.

Diverging Scales

发散比例尺,与 sequential scalescontinuous scales 类似,讲一个连续的数值类型输入映射到连续的输出域。但是与连续比例尺不同的是,发散比例尺的输出是根据插值器计算不可配置。不暴露 invert, range, rangeRoundinterpolate 方法.

# d3.scaleDiverging(interpolator) <>

根据跟定的 interpolator 函数构建一个新的发散比例尺。当比例尺被 applied 时,插值器将会根据范围为 [0,1] 的输入值计算对应的输出值,其中 0 表示负向极小值,0.5 表示中位值,1 表示正向极大值。例如使用 d3.interpolateSpectral

var spectral = d3.scaleDiverging(d3.interpolateSpectral);

# diverging(value) <>

参考 continuous.

# diverging.domain([domain]) <>

参考 continuous.domain. 发散比例尺的输入必须是数值并且包含三个元素,默认的输入域是 [0, 0.5, 1].

# diverging.clamp([clamp]) <>

参考 continuous.clamp.

# diverging.interpolator([interpolator]) <>

如果指定了 interpolate 则将比例尺的插值器设置为指定的函数,如果没有指定 interpolate 则返回当前比例尺的插值器。

# diverging.copy() <>

参考 continuous.copy.

Quantize Scales

量化比例尺与 linear scales 类似,但是其输出区间是离散的而不是连续的。连续的输入域根据输出域被分割为均匀的片段。每一个输出域中的值 y 都可以定义为输入域中 x 值的一个线性函数:x: y = m round(x) + b. 参考 bl.ocks.org/4060606 获取示例。

# d3.scaleQuantize() <>

使用单位输入域 domain : [0, 1] 和单位输出域 range : [0, 1]构造一个新的量化比例尺。默认的量化比例尺等效于 Math.round 函数。

# quantize(value) <>

根据给定的输入域中的值 value 返回对应的输出域汇总的值。例如对位于 [0,1] 中的值进行两种颜色编码:

var color = d3.scaleQuantize()
    .domain([0, 1])
    .range(["brown", "steelblue"]);

color(0.49); // "brown"
color(0.51); // "steelblue"

或者将输入域划分为三个三个大小相等、范围值不同的片段来计算合适的笔画宽度:

var width = d3.scaleQuantize()
    .domain([10, 100])
    .range([1, 2, 4]);

width(20); // 1
width(50); // 2
width(80); // 4

# quantize.invertExtent(value) <>

根据指定的输出域中的值,计算对应的输入域的范围 [x0, x1]。这个方法在交互时很有用,比如根据与鼠标像素对应值反推输入域的范围。

var width = d3.scaleQuantize()
    .domain([10, 100])
    .range([1, 2, 4]);

width.invertExtent(2); // [40, 70]

# quantize.domain([domain]) <>

如果指定了 domain 则将比例尺的输入域设置为指定的二元数值型数组。如果给定的数组中的元素不是数值类型则将被强制转为数值类型。如果没有指定 domain 则返回当前比例尺的输入域。

# quantize.range([range]) <>

如果指定了 range 则将比例尺的输出域设置为指定的数组。这个数组可以包含任意数量的离散值。跟定的数组元素不一定非要为数值类型,可以是任意类型的。如果没有指定 range 则返回当前比例尺的输出域。

# quantize.ticks([count]) <>

等价于 continuous.ticks.

# quantize.tickFormat([count[, specifier]]) <>

等价于 continuous.tickFormat.

# quantize.nice() <>

等价于 continuous.nice.

# quantize.copy() <>

返回当前比例尺的精准拷贝。原比例尺和副本之间不会相互影响。

Quantile Scales

分位数比例尺将一个离散的输入域映射到一个离散的输出域。输入域被认为是连续的,因此可以接受任何合理的输入值。但是输入域被指定为一组离散的样本值,输出域中的值的数量决定了分位数的数量。为了计算分位数,输入域中的值会被排序。并且作为 population of discrete values(离散值总体). 参考 d3-arrayquantile。参考例子: bl.ocks.org/8ca036b3505121279daf

# d3.scaleQuantile() <>

使用空的 domain 和空的 range 构造一个分位数比例尺。在指定输入和输出域之前,分位数比例尺是无效的。

# quantile(value) <>

根据给定的 domain 中的值 value 返回对应的 range 中的值。

# quantile.invertExtent(value) <>

根据指定的输出域中的值返回输入域中所有值的范围 [<i>x0</i>, <i>x1</i>]: 在交互时候很有用,比如根据鼠标位置计算对应的输入区间。

# quantile.domain([domain]) <>

如果指定了 domain 则将当前分位数比例尺的输入域设置为指定的离散的数值数组。数组必须不能为空,并且必须包含至少一个数值类型的值。NaN, nullundefined 将会被忽略不被作为样本的一部分。如果给定的数组中的元素非数值,则会被强制转为数值类型。比例尺内部会存储输入数组的副本。如果没有指定 domain 则会返回比例尺当前的输入域。

# quantile.range([range]) <>

如果指定了 range 则设置比例尺的输出域。数组必须不能为空,并且可以包含任意类型。输出域中的元素数量决定了分位数的数量。例如,要计算四分位数,范围必须是一个包含四个元素的数组, 比如 [0,1,2,3] 等。如果没有指定 range 则返回比例尺当前的输出域。

# quantile.quantiles() <>

返回分位阈值。如果输出域包含 n 个离散的值,则返回的阈值数组会包含 n - 1 个元素。输入值小于第一个阈值的值对应第一个分位数,大于第一个但是小于第二个阈值的输入值对应第二个分位数,以此类推。在内部,阈值数组通过 bisect 根据输入值查找对应的分位数值。

# quantile.copy() <>

返回当前比例尺的精准拷贝。原比例尺和副本之间不会相互影响。

Threshold Scales

阈值比例尺与 quantize scales 类似,只不过它们允许将输入域的任意子集映射到输入域的离散值。输入域依旧是连续的,并且会根据输出域分片。参考 bl.ocks.org/3306362

# d3.scaleThreshold() <>

使用默认的 domain:[0.5] 以及默认的 range:[0, 1] 构造一个新的阈值比例尺。因此默认的阈值比例尺等价于 Math.round 函数。例如 threshold(0.49) 返回 0, threshold(0.51) 返回 1.

# threshold(value) <>

根据输入域中的值返回对应的输出域中的值。例如:

var color = d3.scaleThreshold()
    .domain([0, 1])
    .range(["red", "white", "green"]);

color(-1);   // "red"
color(0);    // "white"
color(0.5);  // "white"
color(1);    // "green"
color(1000); // "green"

# threshold.invertExtent(value) <>

返回输出域中的值 value 对应的输入范围 [<i>x0</i>, <i>x1</i>], 表示输入和输出之间的反转映射。这个方法在交互时很有用。例如:

var color = d3.scaleThreshold()
    .domain([0, 1])
    .range(["red", "white", "green"]);

color.invertExtent("red"); // [undefined, 0]
color.invertExtent("white"); // [0, 1]
color.invertExtent("green"); // [1, undefined]

# threshold.domain([domain]) <>

如果指定了 domain 则将比例尺的输入范围设置为指定的数组。数组必须是升序排序的。值通常是数值,也可以是能进行排序的其他类型。如果输出域的值个数为 N + 1, 则输入域中值的个数必须为 N. 如果比 N 少则对应的输出域中多余的值会被忽略。如果多于 N 则会出现返回 undefined 的情况。如果没指定 domain 则返回比例尺当前的输入域。

# threshold.range([range]) <>

如果指定了 range 则将当前比例尺的输出域设置为指定的数组。如果输入域中的元素个数为 N 则输出域中的元素个数必须为 N + 1. 如果少于 N + 1 个元素,则比例尺对某些值可能会返回 undefined。如果多于 N + 1 个值,则多余的值会被忽略。输出域中的元素不一定必须为数值类型,如果是其他类型也可以正常工作。如果没有指定 range 则返回比例尺当前的输出域。

# threshold.copy() <>

返回当前比例尺的精准拷贝。原比例尺和副本之间不会相互影响。

Ordinal Scales

continuous scales 不同,序数比例尺的输出域和输入域都是离散的。例如序数比例尺可以将一组命名类别映射到一组颜色。或者确定一组条形图在水平方向的位置等等。

# d3.scaleOrdinal([range]) <>

使用空的输入域和指定的 range 构造一个序数比例尺。如果没有指定 range 则默认为空数组。序数比例尺在定义非空的输入域之前,总是返回 undefined

# ordinal(value) <>

根据输入域中的值 value 返回对应的输入域中的值。如果给定的 value 不在输入域中则返回 unknown;如果 unknownimplicit(隐式的)(默认的),则 value 会被隐式的添加到输入域中。这样的话在后续的调用中会返回对应的默认值。

# ordinal.domain([domain]) <>

如果指定了 domain 则将输入域设置为指定的数组。输入域中的元素次序与输出域中的元素次序一一对应。输入域在内部以字符串到索引的映射形式存储;索引值用来进行进行输出检索。因此,序数比例尺的值必须为字符串或者能被强制转为字符串的类型,并且必须唯一。

如果 unknown valueimplicit(指定默认值)。则设置输入域是可选的(非强制的)。在这种情况下,输入域会根据传给比例尺的值推测出来。要注意的是最好显式的指定输入域,因为这样的话映射关系能确定。

# ordinal.range([range]) <>

如果指定了 range 则将序数比例尺的输出域设置为指定的数组。输入域中的元素与输出域中的元素一一对应。如果没有指定 tange 则返回比例尺当前的输出域。

# ordinal.unknown([value]) <>

如果指定了 value 则将未知输入的输出值设置为指定的值。如果没有指定 value 则返回当前的未知值,默认为 implicit. 隐式值会对输入域进行隐式调整,参考 ordinal.domain.

# ordinal.copy() <>

返回当前比例尺的精准拷贝。原比例尺和副本之间不会相互影响。

# d3.scaleImplicit <>

序数比例尺 ordinal.unknown 的一个特殊的值,支持对输入域的隐式构造:将未知的值到输入域中。

Band Scales

分段比例尺与 ordinal scales 类似,只不过其输出域可以是连续的数值类型。离散的输出值是通过将连续的范围划分为均匀的分段。分段比例尺通常用于包含序数或类别维度的条形图。分段比例尺的 unknown value 是未定义的:它们不允许隐式构造。

band

# d3.scaleBand() <>

使用空的 domain,单位 range:[0, 1],不设置 padding, 不设置 rounding 以及 alignment 构造一个新的分段比例尺。

# band(value) <>

根据输入域中的值 value 返回对应的分段的起点值。如果给定的 value 不在输入域中,则返回 undefined

# band.domain([domain]) <>

如果指定了 domain 则将比例尺的输入域设置为指定的数组。第一个元素对应第一个分段,第二个元素对应第二个分段,以此类推。在内部分段比例尺的输入会存储字符串与索引的映射关系,因此输入域中的值必须是字符串或者能被强制转为字符串的值。并且必须唯一。如果没有指定 domain 则返回比例尺当前的输入域。

# band.range([range]) <>

如果指定了 range 则将比例尺的输出域设置为指定的二元数值数组。如果数组中元素不是数值类型则会被强制转为数值类型。如果没有指定 range 则返回比例尺当前的输出范围,默认为 [0, 1]

# band.rangeRound([range]) <>

将比例尺的 range 设置为指定的二元数值数组。并且启用 rounding,这是如下操作的一个便捷方法:

band
    .range(range)
    .round(true);

取整有时候能避免锯齿,当然也可以使用 shape-rendering 的 “crispEdges” 样式来避免锯齿。

# band.round([round]) <>

如果指定了 round 则表示启用或关闭取整操作。如果开启了取整,则每个分段的起点和终点都是整数。取整有时候能避免锯齿。需要注意的是,如果输入域的宽度不能被输出范围整除,则可能还有剩余的未使用的空间,即使没有填充。可以使用 band.align 来以指定剩余空间的分布方式。

# band.paddingInner([padding]) <>

如果指定了 padding 则将分段的内部间隔设置为指定的值,值的范围必须在 [0, 1] 之间. 如果没有指定 padding 则返回当前的内部间隔,默认为 0. 内部间隔决定了两个分段之间的间隔比例。

# band.paddingOuter([padding]) <>

如果指定了 padding 则将分段的外部间隔设置为指定的值,值的范围必须在 [0, 1] 之间. 如果没有指定 padding 则返回当前的外部,默认为 0. 外部决定了第一个分段之前与最后一个分段之后的间隔比例。

# band.padding([padding]) <>

一个同时设置 innerouter 的便捷方法。如果没有指定 padding 则返回内部间隔。

# band.align([align]) <>

如果指定了 align 则设置分段的对其方式,值处于 [0, 1] 之间。如果没有指定 align 则返回当前的对其方式,默认为 0.5。对其方式决定了输出区间的分布方式。0,5 表示第一个分段前和最后一个分段之后的未使用空间一致。使用 0 或者 1 可以将分段整体向某一侧对齐。

# band.bandwidth() <>

返回每一个分段的宽度。

# band.step() <>

返回相邻的两个分段的起点之间的距离。

# band.copy() <>

返回当前比例尺的精准拷贝。原比例尺和副本之间不会相互影响。

Point Scales

标点比例尺是 band scales 的分段宽度为 0 时的变体。标点比例尺通常用于对具有序数或分类维度的散点图。unknown value 总是 undefined: 它们不能隐式的构造输入域。

point

# d3.scalePoint() <>

使用空的 domain, 单位 range:[0, 1], 不指定 padding, rounding 以及 alignment 构造一个新的标点比例尺.

# point(value) <>

根据输入域中的值 value 返回对应的输出域中的点。如果给定的 value 不在输入域中则返回 undefined

# point.domain([domain]) <>

如果指定了 domain 则将比例尺的输入域设置为指定的数组。第一个元素对应第一个分段,第二个元素对应第二个分段,以此类推。在内部分段比例尺的输入会存储字符串与索引的映射关系,因此输入域中的值必须是字符串或者能被强制转为字符串的值。并且必须唯一。如果没有指定 domain 则返回比例尺当前的输入域。

# point.range([range]) <>

如果指定了 range 则将比例尺的输出域设置为指定的二元数值数组。如果数组中元素不是数值类型则会被强制转为数值类型。如果没有指定 range 则返回比例尺当前的输出范围,默认为 [0, 1]

# point.rangeRound([range]) <>

将比例尺的 range 设置为指定的二元数值数组。并且启用 rounding,这是如下操作的一个便捷方法:

point
    .range(range)
    .round(true);

取整有时候能避免锯齿,当然也可以使用 shape-rendering 的 “crispEdges” 样式来避免锯齿。

# point.round([round]) <>

如果指定了 round 则表示启用或关闭取整操作。如果开启了取整,则每个分段的起点和终点都是整数。取整有时候能避免锯齿。需要注意的是,如果输入域的宽度不能被输出范围整除,则可能还有剩余的未使用的空间,即使没有填充。可以使用 band.align 来以指定剩余空间的分布方式。

# point.padding([padding]) <>

如果指定了 padding 则将分段的内部间隔设置为指定的值,值的范围必须在 [0, 1] 之间. 如果没有指定 padding 则返回当前的内部间隔,默认为 0. 内部间隔决定了两个分段之间的间隔比例。

# point.align([align]) <>

如果指定了 align 则设置分段的对其方式,值处于 [0, 1] 之间。如果没有指定 align 则返回当前的对其方式,默认为 0.5。对其方式决定了输出区间的分布方式。0,5 表示第一个分段前和最后一个分段之后的未使用空间一致。使用 0 或者 1 可以将分段整体向某一侧对齐。

# point.bandwidth() <>

返回 0

# point.step() <>

返回相邻的两个标点之间的距离.

# point.copy() <>

返回当前比例尺的精准拷贝。原比例尺和副本之间不会相互影响。

最后更新: 2019-5-18 18:11:02
本站功能逐步完善中,如果您对本站有好的建议或者意见,欢迎留言。 取 消 确 定