跳至内容

线性刻度

线性刻度使用线性变换(平移和缩放)将连续的定量输入映射到连续的输出范围。如果范围也是数值型的,则映射可以被反转。线性刻度是连续定量数据的良好默认选择,因为它们保留了比例差异。每个范围值 *y* 可以表示为域值 *x* 的函数:*y* = *mx* + *b*。

scaleLinear(domain, range)

示例 · 源代码 · 构建一个新的线性刻度,具有指定的范围默认插值器,并且钳制禁用。

js
d3.scaleLinear([0, 100], ["red", "blue"])

如果只指定一个参数,则将其解释为范围。如果范围未指定,则每个都默认为 [0, 1]。

js
d3.scaleLinear(["red", "blue"]) // default domain of [0, 1]

linear(value)

示例 · 源代码 · 给定来自,返回来自范围的相应值。例如,要应用位置编码

js
const x = d3.scaleLinear([10, 130], [0, 960]);
x(20); // 80
x(50); // 320

要应用颜色编码

js
const color = d3.scaleLinear([10, 100], ["brown", "steelblue"]);
color(20); // "rgb(154, 52, 57)"
color(50); // "rgb(123, 81, 103)"

如果给定的在域之外,并且钳制未启用,则映射将被外推,使得返回值在范围之外。

linear.invert(value)

示例 · 源代码 · 给定来自范围,返回来自的相应值。反转对于交互很有用,例如确定对应于鼠标位置的数据值。例如,要反转位置编码

js
const x = d3.scaleLinear([10, 130], [0, 960]);
x.invert(80); // 20
x.invert(320); // 50

如果给定的在范围之外,并且钳制未启用,则映射可能被外推,使得返回值在域之外。此方法仅在范围为数值型时受支持。如果范围不是数值型的,则返回 NaN。

对于范围中的有效值 *y*,linear(linear.invert(y)) 大致等于 *y*;类似地,对于域中的有效值 *x*,linear.invert(linear(x)) 大致等于 *x*。由于浮点精度的限制,刻度及其反转可能不精确。

linear.domain(domain)

示例 · 源代码 · 如果指定了domain,则将刻度的域设置为指定数字数组,并返回此刻度。

js
const x = d3.scaleLinear().domain([10, 130]);

数组必须包含两个或更多元素。如果给定数组中的元素不是数字,则它们将被强制转换为数字。

虽然连续刻度通常在它们的域和范围内各有两个值,但指定超过两个值会生成分段刻度。例如,要创建一个分歧颜色刻度,它在负值的情况下在白色和红色之间插值,在正值的情况下在白色和绿色之间插值,例如

js
const color = d3.scaleLinear([-1, 0, 1], ["red", "white", "green"]);
color(-0.5); // "rgb(255, 128, 128)"
color(+0.5); // "rgb(128, 192, 128)"

在内部,分段刻度对对应于给定域值的范围插值器执行二分搜索。因此,域必须按升序或降序排列。如果域和范围具有不同的长度 *N* 和 *M*,则仅观察每个中的前 *min(N,M)* 个元素。

如果未指定domain,则返回刻度当前域的副本。

js
color.domain() // [-1, 0, 1]

linear.range(range)

示例 · 源代码 · 如果指定了range,则将刻度的范围设置为指定的值数组,并返回此刻度。

js
const x = d3.scaleLinear().range([0, 960]);

数组必须包含两个或更多元素。与不同,给定数组中的元素不必是数字;任何被底层插值器支持的值都可以,但请注意,invert需要数值范围。

如果未指定range,则返回刻度当前范围的副本。

js
x.range() // [0, 960]

有关更多示例,请参见linear.interpolate

linear.rangeRound(range)

示例 · 源代码 · 将刻度的范围设置为指定的值数组,同时还将刻度的插值器设置为interpolateRound;返回此刻度。

js
const x = d3.scaleLinear().rangeRound([0, 960]);

这是一个与以下等效的便捷方法

js
linear.range(range).interpolate(d3.interpolateRound)

舍入插值器有时用于避免抗锯齿伪像,但也考虑shape-rendering “crispEdges” 样式。请注意,此插值器只能与数值范围一起使用。

linear.clamp(clamp)

示例 · 源代码 · 如果指定了clamp,则相应地启用或禁用钳制;返回此刻度。

js
const x = d3.scaleLinear([0, 960]).clamp(true);

如果钳制被禁用并且刻度传递了一个超出的值,则刻度可能会通过外推返回范围之外的值。如果钳制被启用,则刻度的返回值始终在刻度的范围内。钳制类似地应用于linear.invert。例如

js
const x = d3.scaleLinear([10, 130], [0, 960]); // clamping disabled by default
x(-10); // -160, outside range
x.invert(-160); // -10, outside domain
x.clamp(true); // enable clamping
x(-10); // 0, clamped to range
x.invert(-160); // 10, clamped to domain

如果未指定clamp,则返回刻度当前是否将值钳制在范围内。

js
x.clamp() // true, perhaps

linear.unknown(value)

示例 · 源代码 · 如果指定了value,则将刻度的输出值设置为未定义或 NaN 输入值,并返回此刻度。这对于指定如何显示丢失或无效数据很有用。

js
const color = d3.scaleLinear([0, 100], ["red", "blue"]).unknown("#ccc");
color(NaN); // "#ccc"

如果未指定value,则返回当前未知值,该值默认为未定义。

js
color.unknown() // "#ccc"

linear.interpolate(interpolate)

示例 · 源代码 · 如果指定了interpolate,则将刻度的范围插值器工厂设置为该值。

js
const color = d3.scaleLinear(["red", "blue"]).interpolate(d3.interpolateHcl);

刻度的插值器工厂用于为范围中的每对相邻值创建插值器;然后这些插值器将归一化的域参数 *t* 在 [0, 1] 中映射到范围内相应的 value。如果未指定factory,则返回刻度当前的插值器工厂,该工厂默认为d3.interpolate。有关更多插值器,请参见d3-interpolate

例如,考虑一个具有三个范围颜色的分歧颜色刻度

js
const color = d3.scaleLinear([-100, 0, +100], ["red", "white", "green"]);

刻度在内部创建两个插值器,等效于

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

指定自定义插值器的一个常见原因是更改插值的色域。例如,要使用HCL

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

或者对于具有自定义伽马的Cubehelix

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

注意

默认的插值器**可能会重复使用返回值**。例如,如果范围值是对象,则值插值器始终返回同一个对象,并在原地修改它。如果刻度用于设置属性或样式,这通常是可以接受的(并且对性能有利);但是,如果您需要存储刻度的返回值,则必须指定您自己的插值器或根据需要创建副本。

linear.ticks(count)

示例 · 源代码 · 返回刻度范围内的约count个具有代表性的值。

js
const x = d3.scaleLinear([10, 100], ["red", "blue"]);
x.ticks(); // [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

如果未指定count,则默认值为 10。返回的刻度值均匀分布,具有可读性强的值(例如 10 的幂的倍数),并且保证在域的范围内。刻度通常与可视化数据一起用于显示参考线或刻度标记。指定的count只是一个提示;刻度可能根据域返回更多或更少的。另请参见 d3-array 的 ticks

linear.tickFormat(count, specifier)

示例 · 源代码 · 返回一个用于显示刻度值的数字格式函数,根据刻度值之间固定的间隔自动计算适当的精度。指定的count应该与用于生成刻度值的计数相同。

js
const x = d3.scaleLinear([0.1, 1], ["red", "blue"]);
const f = x.tickFormat();
f(0.1); // "0.1"
f(1); // "1.0"

可选的specifier允许使用自定义格式,其中格式的精度由刻度根据刻度间隔自动设置。例如,要格式化百分比变化,您可以这样说

js
const x = d3.scaleLinear([-1, 1], [0, 960]);
const T = x.ticks(5); // [-1, -0.5, 0, 0.5, 1]
const f = x.tickFormat(5, "+%");
T.map(f); // ["−100%", "−50%", "+0%", "+50%", "+100%"]

如果specifier使用格式类型 s,则刻度将返回一个基于域中最大值的SI 前缀格式。如果specifier已经指定了精度,则此方法等效于locale.format

另请参见 d3.tickFormat

linear.nice(count)

示例 · 源代码 · 扩展,使其以良好的圆形值开始和结束。

js
const x = d3.scaleLinear([0.241079, 0.969679], [0, 960]).nice();
x.domain(); // [0.2, 1]

此方法通常会修改刻度的域,并且可能只将边界扩展到最近的圆形值。如果域是从数据计算出来的,例如使用extent,并且可能是无规律的,则美化非常有用。如果域包含两个以上的,则美化域只会影响第一个和最后一个值。

可选的刻度count参数允许对用于扩展边界的步长进行更大的控制,从而保证返回的刻度将完全覆盖域。

js
const x = d3.scaleLinear([0.241079, 0.969679], [0, 960]).nice(40);
x.domain(); // [0.24, 0.98]

美化刻度只会修改当前域;它不会自动美化随后使用linear.domain设置的域。如果需要,您必须在设置新域后重新美化刻度。

linear.copy()

示例 · 源代码 · 返回此刻度的精确副本。

js
const x1 = d3.scaleLinear([0, 100], ["red", "blue"]);
const x2 = x1.copy();

对这个刻度的更改不会影响返回的刻度,反之亦然。

tickFormat(start, stop, count, specifier)

示例 · 源代码 · 返回一个用于显示刻度值的数字格式函数,根据d3.tickStep确定的刻度值之间固定的间隔自动计算适当的精度。

js
const f = d3.tickFormat(0, 1, 20);
f(1); // "1.00"

可选的specifier允许使用自定义格式,其中格式的精度由刻度根据刻度间隔自动设置。例如,要格式化百分比变化,您可以这样说

js
const f = d3.tickFormat(-1, 1, 5, "+%");
f(-0.5); // "-50%"

如果specifier使用格式类型 s,则刻度将返回一个基于startstop的较大绝对值的SI 前缀格式。如果specifier已经指定了精度,则此方法等效于locale.format

scaleIdentity(range)

示例 · 源代码 · 使用指定的范围(以及扩展的)构建一个新的标识刻度。

js
const x = d3.scaleIdentity([0, 960]);

标识刻度是线性刻度的一种特殊情况,其中域和范围相同;因此,刻度及其反转方法是恒等函数。这些刻度在处理像素坐标时偶尔很有用,例如与轴一起使用。标识刻度不支持rangeRoundclampinterpolate

如果未指定range,则默认值为 [0, 1]。

scaleRadial(domain, range)

示例 · 源代码 · 使用指定的范围构建一个新的径向刻度。

js
const r = d3.scaleRadial([100, 200], [0, 480]);

径向刻度是线性刻度的一种变体,其中范围在内部被平方,以便输入值线性对应于平方输出值。当您希望输入值对应于图形标记的面积,并且该标记由半径指定(如径向条形图)时,这些刻度很有用。径向刻度不支持interpolate

如果未指定domainrange,则每个都默认为 [0, 1]。