From 970b0658b20b7a8f12540695ff2b3927fd83f38c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 5 Jan 2022 11:28:54 +0100 Subject: [PATCH 1/3] low, high --- src/continuous.js | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/continuous.js b/src/continuous.js index d932095..da9a1e3 100644 --- a/src/continuous.js +++ b/src/continuous.js @@ -15,12 +15,6 @@ function normalize(a, b) { : constant(isNaN(b) ? NaN : 0.5); } -function clamper(a, b) { - var t; - if (a > b) t = a, a = b, b = t; - return function(x) { return Math.max(a, Math.min(b, x)); }; -} - // normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. // interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b]. function bimap(domain, range, interpolate) { @@ -69,6 +63,10 @@ export function transformer() { transform, untransform, unknown, + low, + high, + min, + max, clamp = identity, piecewise, output, @@ -76,14 +74,21 @@ export function transformer() { function rescale() { var n = Math.min(domain.length, range.length); - if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]); + min = domain[0]; + max = domain[n - 1]; + if (max < min) ([min, max] = [max, min]); + if (clamp !== identity) clamp = x => x < min ? min : x > max ? max : x; piecewise = n > 2 ? polymap : bimap; output = input = null; return scale; } function scale(x) { - return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x))); + const tr = clamp !== identity ? x => transform(clamp(x)) : transform; + return x == null || isNaN(x = +x) ? unknown + : low !== undefined && x < min ? low + : high !== undefined && x > max ? high + : (output || (output = piecewise(domain.map(transform), range, interpolate)))(tr(x)); } scale.invert = function(y) { @@ -114,6 +119,14 @@ export function transformer() { return arguments.length ? (unknown = _, scale) : unknown; }; + scale.low = function(_) { + return arguments.length ? (low = _, scale) : low; + }; + + scale.high = function(_) { + return arguments.length ? (high = _, scale) : high; + }; + return function(t, u) { transform = t, untransform = u; return rescale(); From 8558e51afb963d22df79a536ff14f9f79ed8e0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 5 Jan 2022 11:31:48 +0100 Subject: [PATCH 2/3] simplify clamp --- src/continuous.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/continuous.js b/src/continuous.js index da9a1e3..0149d2e 100644 --- a/src/continuous.js +++ b/src/continuous.js @@ -67,7 +67,7 @@ export function transformer() { high, min, max, - clamp = identity, + clamp, piecewise, output, input; @@ -77,14 +77,14 @@ export function transformer() { min = domain[0]; max = domain[n - 1]; if (max < min) ([min, max] = [max, min]); - if (clamp !== identity) clamp = x => x < min ? min : x > max ? max : x; + if (clamp) clamp = x => x < min ? min : x > max ? max : x; piecewise = n > 2 ? polymap : bimap; output = input = null; return scale; } function scale(x) { - const tr = clamp !== identity ? x => transform(clamp(x)) : transform; + const tr = clamp ? x => transform(clamp(x)) : transform; return x == null || isNaN(x = +x) ? unknown : low !== undefined && x < min ? low : high !== undefined && x > max ? high @@ -92,7 +92,8 @@ export function transformer() { } scale.invert = function(y) { - return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y))); + const x = untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)); + return clamp ? clamp(x) : x; }; scale.domain = function(_) { @@ -108,7 +109,7 @@ export function transformer() { }; scale.clamp = function(_) { - return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity; + return arguments.length ? (clamp = !!_, rescale()) : !!clamp; }; scale.interpolate = function(_) { From b46009ac26a33e31cd2767d61cf2fd1a6b9113f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 5 Jan 2022 11:58:22 +0100 Subject: [PATCH 3/3] document low, high --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 9024eaf..ed9aef3 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,14 @@ x.invert(-160); // 10, clamped to domain If *clamp* is not specified, returns whether or not the scale currently clamps values to within the range. +# continuous.low([value]) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales) + +If *value* is specified, sets the output value for values lower than the lower bound of the domain and returns this scale. If *value* is undefined, interpolation or clamping may happen. If *value* is not specified, returns the current low value, which defaults to undefined. + +# continuous.high([value]) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales) + +If *value* is specified, sets the output value for values higher than the upper bound of the domain and returns this scale. If *value* is undefined, interpolation or clamping may happen. If *value* is not specified, returns the current high value, which defaults to undefined. + # continuous.unknown([value]) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales) If *value* is specified, sets the output value of the scale for undefined (or NaN) input values and returns this scale. If *value* is not specified, returns the current unknown value, which defaults to undefined.