Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.2 #156

Merged
merged 37 commits into from
Jan 26, 2019
Merged

2.2 #156

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9fe496e
Arbitrary transforms for continuous scales.
mbostock Jan 6, 2019
e3da4b7
Optimize log transform.
mbostock Jan 6, 2019
baeade5
Expose continuous.transform.
mbostock Jan 6, 2019
e342617
Add transformSymlog; fixes #105.
mbostock Jan 6, 2019
a432a51
Fix whitespace.
mbostock Jan 6, 2019
3239e91
Fix coercion.
mbostock Jan 6, 2019
aa6137d
Remove default argument.
mbostock Jan 25, 2019
84834a3
Don’t expose transforms.
mbostock Jan 25, 2019
0fa1462
Separate functions.
mbostock Jan 25, 2019
71c8336
Remove superfluous coercion.
mbostock Jan 25, 2019
fdd2b15
Update README.
mbostock Jan 25, 2019
2f70fdf
Add d3.scaleSequential{Log,Pow,Sqrt}.
mbostock Jan 25, 2019
0ac9be5
Diverging transforms.
mbostock Jan 25, 2019
93f62cc
Add scaleSequentialQuantile.
mbostock Jan 25, 2019
0724fdd
Fix default divergingLog domain.
mbostock Jan 25, 2019
a1183dc
Remove exponent and base constructor arguments.
mbostock Jan 25, 2019
1de765b
Restore test.
mbostock Jan 25, 2019
0a6350c
Revert changes to README.
mbostock Jan 25, 2019
a7671ef
Revert formatting changes.
mbostock Jan 25, 2019
2427450
Fix #159 default constructors.
mbostock Jan 25, 2019
c091e7d
Update README.
mbostock Jan 25, 2019
a51ea80
Add symlog scales.
mbostock Jan 25, 2019
23f32d5
Adopt Webber’s symlog definition.
mbostock Jan 25, 2019
749e22e
Simplify.
mbostock Jan 25, 2019
28b4b4a
Convenience constructors for ordinal scales.
mbostock Jan 26, 2019
f87eeda
Convenience constructors for identity scales.
mbostock Jan 26, 2019
bf1adbc
Convenience constructors for all!
mbostock Jan 26, 2019
9dad02a
Shorten.
mbostock Jan 26, 2019
b3d8ce3
Update README.
mbostock Jan 26, 2019
5bfe135
Update README.
mbostock Jan 26, 2019
ac37960
Expose d3.tickFormat. Fixes #148.
mbostock Jan 26, 2019
19a03ec
Add tests for tickFormat.
mbostock Jan 26, 2019
4d89464
Fix #97 - add scale.unknown.
mbostock Jan 26, 2019
5d767cb
Fix #123 - document that quantize.domain must be ascending.
mbostock Jan 26, 2019
fb5f0b3
Allow unlimited outer padding.
mbostock Jan 26, 2019
3a62189
Update README.
mbostock Jan 26, 2019
30876a5
Fix export.
mbostock Jan 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 103 additions & 36 deletions README.md

Large diffs are not rendered by default.

15 changes: 7 additions & 8 deletions src/band.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {range as sequence} from "d3-array";
import {initRange} from "./init";
import ordinal from "./ordinal";

export default function band() {
Expand Down Expand Up @@ -54,32 +55,30 @@ export default function band() {
};

scale.padding = function(_) {
return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner;
};

scale.paddingInner = function(_) {
return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner;
};

scale.paddingOuter = function(_) {
return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter;
};

scale.align = function(_) {
return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
};

scale.copy = function() {
return band()
.domain(domain())
.range(range)
return band(domain(), range)
.round(round)
.paddingInner(paddingInner)
.paddingOuter(paddingOuter)
.align(align);
};

return rescale();
return initRange.apply(rescale(), arguments);
}

function pointish(scale) {
Expand All @@ -97,5 +96,5 @@ function pointish(scale) {
}

export function point() {
return pointish(band().paddingInner(1));
return pointish(band.apply(null, arguments).paddingInner(1));
}
71 changes: 41 additions & 30 deletions src/continuous.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,37 @@
import {bisect} from "d3-array";
import {interpolate as interpolateValue, interpolateRound} from "d3-interpolate";
import {interpolate as interpolateValue, interpolateNumber, interpolateRound} from "d3-interpolate";
import {map, slice} from "./array";
import constant from "./constant";
import number from "./number";

var unit = [0, 1];

export function deinterpolateLinear(a, b) {
export function identity(x) {
return x;
}

function normalize(a, b) {
return (b -= (a = +a))
? function(x) { return (x - a) / b; }
: constant(b);
}

function deinterpolateClamp(deinterpolate) {
return function(a, b) {
var d = deinterpolate(a = +a, b = +b);
return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
};
}

function reinterpolateClamp(reinterpolate) {
return function(a, b) {
var r = reinterpolate(a = +a, b = +b);
return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
};
function clamper(domain) {
var a = domain[0], b = domain[domain.length - 1], t;
if (a > b) t = a, a = b, b = t;
return function(x) { return Math.max(a, Math.min(b, x)); };
}

function bimap(domain, range, deinterpolate, reinterpolate) {
// 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) {
var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);
else d0 = normalize(d0, d1), r0 = interpolate(r0, r1);
return function(x) { return r0(d0(x)); };
}

function polymap(domain, range, deinterpolate, reinterpolate) {
function polymap(domain, range, interpolate) {
var j = Math.min(domain.length, range.length) - 1,
d = new Array(j),
r = new Array(j),
Expand All @@ -46,8 +44,8 @@ function polymap(domain, range, deinterpolate, reinterpolate) {
}

while (++i < j) {
d[i] = deinterpolate(domain[i], domain[i + 1]);
r[i] = reinterpolate(range[i], range[i + 1]);
d[i] = normalize(domain[i], domain[i + 1]);
r[i] = interpolate(range[i], range[i + 1]);
}

return function(x) {
Expand All @@ -61,16 +59,18 @@ export function copy(source, target) {
.domain(source.domain())
.range(source.range())
.interpolate(source.interpolate())
.clamp(source.clamp());
.clamp(source.clamp())
.unknown(source.unknown());
}

// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
export default function continuous(deinterpolate, reinterpolate) {
export function transformer() {
var domain = unit,
range = unit,
interpolate = interpolateValue,
clamp = false,
transform,
untransform,
unknown,
clamp = identity,
piecewise,
output,
input;
Expand All @@ -82,15 +82,15 @@ export default function continuous(deinterpolate, reinterpolate) {
}

function scale(x) {
return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate)))(+x);
return isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));
}

scale.invert = function(y) {
return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)));
};

scale.domain = function(_) {
return arguments.length ? (domain = map.call(_, number), rescale()) : domain.slice();
return arguments.length ? (domain = map.call(_, number), clamp === identity || (clamp = clamper(domain)), rescale()) : domain.slice();
};

scale.range = function(_) {
Expand All @@ -102,12 +102,23 @@ export default function continuous(deinterpolate, reinterpolate) {
};

scale.clamp = function(_) {
return arguments.length ? (clamp = !!_, rescale()) : clamp;
return arguments.length ? (clamp = _ ? clamper(domain) : identity, scale) : clamp !== identity;
};

scale.interpolate = function(_) {
return arguments.length ? (interpolate = _, rescale()) : interpolate;
};

return rescale();
scale.unknown = function(_) {
return arguments.length ? (unknown = _, scale) : unknown;
};

return function(t, u) {
transform = t, untransform = u;
return rescale();
};
}

export default function continuous(transform, untransform) {
return transformer()(transform, untransform);
}
76 changes: 67 additions & 9 deletions src/diverging.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
import {identity} from "./continuous";
import {initInterpolator} from "./init";
import {linearish} from "./linear";
import {loggish} from "./log";
import {copy} from "./sequential";
import {symlogish} from "./symlog";
import {powish} from "./pow";

export default function diverging(interpolator) {
function transformer() {
var x0 = 0,
x1 = 0.5,
x2 = 1,
k10 = 1,
k21 = 1,
clamp = false;
t0,
t1,
t2,
k10,
k21,
interpolator = identity,
transform,
clamp = false,
unknown;

function scale(x) {
var t = 0.5 + ((x = +x) - x1) * (x < x1 ? k10 : k21);
return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
return isNaN(x = +x) ? unknown : (x = 0.5 + ((x = +transform(x)) - t1) * (x < t1 ? k10 : k21), interpolator(clamp ? Math.max(0, Math.min(1, x)) : x));
}

scale.domain = function(_) {
return arguments.length ? (x0 = +_[0], x1 = +_[1], x2 = +_[2], k10 = x0 === x1 ? 0 : 0.5 / (x1 - x0), k21 = x1 === x2 ? 0 : 0.5 / (x2 - x1), scale) : [x0, x1, x2];
return arguments.length ? (t0 = transform(x0 = +_[0]), t1 = transform(x1 = +_[1]), t2 = transform(x2 = +_[2]), k10 = t0 === t1 ? 0 : 0.5 / (t1 - t0), k21 = t1 === t2 ? 0 : 0.5 / (t2 - t1), scale) : [x0, x1, x2];
};

scale.clamp = function(_) {
Expand All @@ -25,9 +36,56 @@ export default function diverging(interpolator) {
return arguments.length ? (interpolator = _, scale) : interpolator;
};

scale.unknown = function(_) {
return arguments.length ? (unknown = _, scale) : unknown;
};

return function(t) {
transform = t, t0 = t(x0), t1 = t(x1), t2 = t(x2), k10 = t0 === t1 ? 0 : 0.5 / (t1 - t0), k21 = t1 === t2 ? 0 : 0.5 / (t2 - t1);
return scale;
};
}

export default function diverging() {
var scale = linearish(transformer()(identity));

scale.copy = function() {
return copy(scale, diverging());
};

return initInterpolator.apply(scale, arguments);
}

export function divergingLog() {
var scale = loggish(transformer()).domain([0.1, 1, 10]);

scale.copy = function() {
return copy(scale, divergingLog()).base(scale.base());
};

return initInterpolator.apply(scale, arguments);
}

export function divergingSymlog() {
var scale = symlogish(transformer());

scale.copy = function() {
return diverging(interpolator).domain([x0, x1, x2]).clamp(clamp);
return copy(scale, divergingSymlog()).constant(scale.constant());
};

return linearish(scale);
return initInterpolator.apply(scale, arguments);
}

export function divergingPow() {
var scale = powish(transformer());

scale.copy = function() {
return copy(scale, divergingPow()).exponent(scale.exponent());
};

return initInterpolator.apply(scale, arguments);
}

export function divergingSqrt() {
return divergingPow.apply(null, arguments).exponent(0.5);
}
14 changes: 10 additions & 4 deletions src/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import {map} from "./array";
import {linearish} from "./linear";
import number from "./number";

export default function identity() {
var domain = [0, 1];
export default function identity(domain) {
var unknown;

function scale(x) {
return +x;
return isNaN(x = +x) ? unknown : x;
}

scale.invert = scale;
Expand All @@ -15,9 +15,15 @@ export default function identity() {
return arguments.length ? (domain = map.call(_, number), scale) : domain.slice();
};

scale.unknown = function(_) {
return arguments.length ? (unknown = _, scale) : unknown;
};

scale.copy = function() {
return identity().domain(domain);
return identity(domain).unknown(unknown);
};

domain = arguments.length ? map.call(domain, number) : [0, 1];

return linearish(scale);
}
23 changes: 21 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export {
default as scaleLog
} from "./log";

export {
default as scaleSymlog
} from "./symlog";

export {
default as scaleOrdinal,
implicit as scaleImplicit
Expand Down Expand Up @@ -46,9 +50,24 @@ export {
} from "./utcTime";

export {
default as scaleSequential
default as scaleSequential,
sequentialLog as scaleSequentialLog,
sequentialPow as scaleSequentialPow,
sequentialSqrt as scaleSequentialSqrt,
sequentialSymlog as scaleSequentialSymlog
} from "./sequential";

export {
default as scaleDiverging
default as scaleSequentialQuantile
} from "./sequentialQuantile";

export {
default as scaleDiverging,
divergingLog as scaleDivergingLog,
divergingPow as scaleDivergingPow,
divergingSqrt as scaleDivergingSqrt
} from "./diverging";

export {
default as tickFormat
} from "./tickFormat";
17 changes: 17 additions & 0 deletions src/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export function initRange(domain, range) {
switch (arguments.length) {
case 0: break;
case 1: this.range(domain); break;
default: this.range(range).domain(domain); break;
}
return this;
}

export function initInterpolator(domain, interpolator) {
switch (arguments.length) {
case 0: break;
case 1: this.interpolator(domain); break;
default: this.interpolator(interpolator).domain(domain); break;
}
return this;
}
Loading