From 19a71227cce67f40d863da54f7f4038b61f946c3 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sat, 19 Dec 2015 10:16:05 -0800 Subject: [PATCH] Optional parameters to interpolators. Related d3/d3-scale#39. --- README.md | 29 +++++++++++++++-------------- index.js | 9 +++------ package.json | 5 +++-- src/bind.js | 16 ++++++++++++++++ src/cubehelix.js | 20 ++++++++++++++++++++ src/cubehelixGamma.js | 21 --------------------- src/cubehelixGammaLong.js | 20 -------------------- src/cubehelixLong.js | 19 +++++++++++++++++++ test/bind-test.js | 15 +++++++++++++++ 9 files changed, 91 insertions(+), 63 deletions(-) create mode 100644 src/bind.js create mode 100644 src/cubehelix.js delete mode 100644 src/cubehelixGamma.js delete mode 100644 src/cubehelixGammaLong.js create mode 100644 src/cubehelixLong.js create mode 100644 test/bind-test.js diff --git a/README.md b/README.md index 6b4b4cf..4b536f6 100644 --- a/README.md +++ b/README.md @@ -163,30 +163,31 @@ Returns an HCL color space interpolator between the two colors *a* and *b*. The Like [hcl](#hcl), but does not use the shortest path between hues. -# d3_interpolate.cubehelix(a, b) +# d3_interpolate.cubehelix(a, b[, gamma]) cubehelix -Returns a Cubehelix color space interpolator between the two colors *a* and *b* using the default *gamma* of 1.0. The colors *a* and *b* need not be in Cubehelix; they will be converted to Cubehelix using [color.cubehelix](https://github.com/d3/d3-color#cubehelix). If either color’s hue or saturation is NaN, the opposing color’s channel value is used. The shortest path between hues is used. The return value of the interpolator is a hexadecimal RGB string. +Or, with a gamma of 3.0 to emphasize high-intensity values: -# d3_interpolate.cubehelixLong(a, b) +cubehelixGamma -cubehelixLong +Returns a Cubehelix color space interpolator between the two colors *a* and *b* using the specified *gamma*. If *gamma* is not specified, it defaults to 1.0. The colors *a* and *b* need not be in Cubehelix; they will be converted to Cubehelix using [color.cubehelix](https://github.com/d3/d3-color#cubehelix). If either color’s hue or saturation is NaN, the opposing color’s channel value is used. The shortest path between hues is used. The return value of the interpolator is a hexadecimal RGB string. -Like [cubehelix](#cubehelix), but does not use the shortest path between hues. +# d3_interpolate.cubehelixLong(a, b[, gamma]) -# d3_interpolate.cubehelixGamma(gamma) +cubehelixLong -cubehelixGamma +Or, with a gamma of 3.0 to emphasize high-intensity values: -Returns a Cubehelix color space interpolator factory using the specified *gamma*. A gamma value less than one emphasizes low intensity values, while a gamma value greater than one emphasizes high intensity values. For example: +cubehelixGammaLong -```js -var i = d3_interpolate.cubehelixGamma(3)("purple", "orange"); -``` +Like [cubehelix](#cubehelix), but does not use the shortest path between hues. -# d3_interpolate.cubehelixGammaLong(gamma) +# d3_interpolate.bind(type[, parameters…]) -cubehelixGammaLong +A convenience function for binding zero or more *parameters* to the specified interpolation function *type*. If no *parameters* are specified, this function simply returns *type*. The returned function takes two arguments *a* and *b* and passes any optional *parameters* to the underlying function *type*. For example, the following statements are equivalent: -Like [cubehelixGamma](#cubehelixGamma), but does not use the shortest path between hues. +```js +d3_interpolate.bind(d3_interpolate.cubehelix, 3)("purple", "orange"); +d3_interpolate.cubehelix("purple", "orange", 3); +``` diff --git a/index.js b/index.js index 0e1dbb4..db3a858 100644 --- a/index.js +++ b/index.js @@ -13,9 +13,6 @@ export {default as hslLong} from "./src/hslLong"; export {default as lab} from "./src/lab"; export {default as hcl} from "./src/hcl"; export {default as hclLong} from "./src/hclLong"; - -import cubehelixGamma from "./src/cubehelixGamma"; -import cubehelixGammaLong from "./src/cubehelixGammaLong"; -export var cubehelix = cubehelixGamma(1); -export var cubehelixLong = cubehelixGammaLong(1); -export {cubehelixGamma, cubehelixGammaLong}; +export {default as cubehelix} from "./src/cubehelix"; +export {default as cubehelixLong} from "./src/cubehelixLong"; +export {default as bind} from "./src/bind"; diff --git a/package.json b/package.json index 7402bbe..1e8473c 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,12 @@ { "name": "d3-interpolate", - "version": "0.2.1", + "version": "0.3.0", "description": "Interpolate numbers, colors, strings, arrays, objects, whatever!", "keywords": [ "d3", "interpolate", - "interpolation" + "interpolation", + "color" ], "homepage": "https://github.com/d3/d3-interpolate", "license": "BSD-3-Clause", diff --git a/src/bind.js b/src/bind.js new file mode 100644 index 0000000..aa95f3f --- /dev/null +++ b/src/bind.js @@ -0,0 +1,16 @@ +var slice = Array.prototype.slice; + +function bindN(type, args) { + args = slice.call(args); + args[0] = null; + args.unshift(null); + return function(a, b) { + args[0] = a; + args[1] = b; + return type.apply(null, args); + }; +} + +export default function(type) { + return arguments.length === 1 ? type : bindN(type, arguments); +}; diff --git a/src/cubehelix.js b/src/cubehelix.js new file mode 100644 index 0000000..316f123 --- /dev/null +++ b/src/cubehelix.js @@ -0,0 +1,20 @@ +import {cubehelix} from "d3-color"; +import deltaHue from "./deltaHue"; + +export default function(a, b, gamma) { + if (arguments.length < 3) gamma = 1; + a = cubehelix(a); + b = cubehelix(b); + var ah = isNaN(a.h) ? b.h : a.h, + as = isNaN(a.s) ? b.s : a.s, + al = a.l, + bh = isNaN(b.h) ? 0 : deltaHue(b.h, ah), + bs = isNaN(b.s) ? 0 : b.s - as, + bl = b.l - al; + return function(t) { + a.h = ah + bh * t; + a.s = as + bs * t; + a.l = al + bl * Math.pow(t, gamma); + return a + ""; + }; +}; diff --git a/src/cubehelixGamma.js b/src/cubehelixGamma.js deleted file mode 100644 index e0205af..0000000 --- a/src/cubehelixGamma.js +++ /dev/null @@ -1,21 +0,0 @@ -import {cubehelix} from "d3-color"; -import deltaHue from "./deltaHue"; - -export default function(gamma) { - return function(a, b) { - a = cubehelix(a); - b = cubehelix(b); - var ah = isNaN(a.h) ? b.h : a.h, - as = isNaN(a.s) ? b.s : a.s, - al = a.l, - bh = isNaN(b.h) ? 0 : deltaHue(b.h, ah), - bs = isNaN(b.s) ? 0 : b.s - as, - bl = b.l - al; - return function(t) { - a.h = ah + bh * t; - a.s = as + bs * t; - a.l = al + bl * Math.pow(t, gamma); - return a + ""; - }; - }; -}; diff --git a/src/cubehelixGammaLong.js b/src/cubehelixGammaLong.js deleted file mode 100644 index 08ee216..0000000 --- a/src/cubehelixGammaLong.js +++ /dev/null @@ -1,20 +0,0 @@ -import {cubehelix} from "d3-color"; - -export default function(gamma) { - return function(a, b) { - a = cubehelix(a); - b = cubehelix(b); - var ah = isNaN(a.h) ? b.h : a.h, - as = isNaN(a.s) ? b.s : a.s, - al = a.l, - bh = isNaN(b.h) ? 0 : b.h - ah, - bs = isNaN(b.s) ? 0 : b.s - as, - bl = b.l - al; - return function(t) { - a.h = ah + bh * t; - a.s = as + bs * t; - a.l = al + bl * Math.pow(t, gamma); - return a + ""; - }; - }; -}; diff --git a/src/cubehelixLong.js b/src/cubehelixLong.js new file mode 100644 index 0000000..b4c3e91 --- /dev/null +++ b/src/cubehelixLong.js @@ -0,0 +1,19 @@ +import {cubehelix} from "d3-color"; + +export default function(a, b, gamma) { + if (arguments.length < 3) gamma = 1; + a = cubehelix(a); + b = cubehelix(b); + var ah = isNaN(a.h) ? b.h : a.h, + as = isNaN(a.s) ? b.s : a.s, + al = a.l, + bh = isNaN(b.h) ? 0 : b.h - ah, + bs = isNaN(b.s) ? 0 : b.s - as, + bl = b.l - al; + return function(t) { + a.h = ah + bh * t; + a.s = as + bs * t; + a.l = al + bl * Math.pow(t, gamma); + return a + ""; + }; +}; diff --git a/test/bind-test.js b/test/bind-test.js new file mode 100644 index 0000000..022ade5 --- /dev/null +++ b/test/bind-test.js @@ -0,0 +1,15 @@ +var tape = require("tape"), + interpolate = require("../"); + +tape("bind(type) returns type", function(test) { + test.equal(interpolate.bind(interpolate.cubehelix), interpolate.cubehelix); + test.equal(interpolate.bind(interpolate.rgb), interpolate.rgb); + test.end(); +}); + +tape("bind(type, parameter) binds the specified parameter to the given type", function(test) { + test.equal(interpolate.bind(interpolate.cubehelix, 3)("purple", "orange")(0.5), interpolate.cubehelix("purple", "orange", 3)(0.5)); + test.equal(interpolate.bind(interpolate.cubehelixLong, 3)("purple", "orange")(0.5), interpolate.cubehelixLong("purple", "orange", 3)(0.5)); + test.equal(interpolate.bind(interpolate.rgb, 3)("purple", "orange")(0.5), interpolate.rgb("purple", "orange", 3)(0.5)); // ignored + test.end(); +});