|
- import {bisect} from "d3-array";
- import {interpolate as interpolateValue, 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) {
- 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 bimap(domain, range, deinterpolate, reinterpolate) {
- 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);
- return function(x) { return r0(d0(x)); };
- }
-
- function polymap(domain, range, deinterpolate, reinterpolate) {
- var j = Math.min(domain.length, range.length) - 1,
- d = new Array(j),
- r = new Array(j),
- i = -1;
-
- // Reverse descending domains.
- if (domain[j] < domain[0]) {
- domain = domain.slice().reverse();
- range = range.slice().reverse();
- }
-
- while (++i < j) {
- d[i] = deinterpolate(domain[i], domain[i + 1]);
- r[i] = reinterpolate(range[i], range[i + 1]);
- }
-
- return function(x) {
- var i = bisect(domain, x, 1, j) - 1;
- return r[i](d[i](x));
- };
- }
-
- export function copy(source, target) {
- return target
- .domain(source.domain())
- .range(source.range())
- .interpolate(source.interpolate())
- .clamp(source.clamp());
- }
-
- // 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) {
- var domain = unit,
- range = unit,
- interpolate = interpolateValue,
- clamp = false,
- piecewise,
- output,
- input;
-
- function rescale() {
- piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;
- output = input = null;
- return scale;
- }
-
- function scale(x) {
- return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate)))(+x);
- }
-
- scale.invert = function(y) {
- return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
- };
-
- scale.domain = function(_) {
- return arguments.length ? (domain = map.call(_, number), rescale()) : domain.slice();
- };
-
- scale.range = function(_) {
- return arguments.length ? (range = slice.call(_), rescale()) : range.slice();
- };
-
- scale.rangeRound = function(_) {
- return range = slice.call(_), interpolate = interpolateRound, rescale();
- };
-
- scale.clamp = function(_) {
- return arguments.length ? (clamp = !!_, rescale()) : clamp;
- };
-
- scale.interpolate = function(_) {
- return arguments.length ? (interpolate = _, rescale()) : interpolate;
- };
-
- return rescale();
- }
|