Skip to content

Commit

Permalink
Add band/point invert.
Browse files Browse the repository at this point in the history
  • Loading branch information
jheer committed May 27, 2016
1 parent e81238b commit b78edc3
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/band.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {range as sequence} from "d3-array";
import {range as sequence, bisectRight} from "d3-array";
import ordinal from "./ordinal";

export default function band() {
Expand Down Expand Up @@ -69,6 +69,28 @@ export default function band() {
return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
};

scale.invert = function(x, y) {
var lo = +x,
hi = arguments.length > 1 ? +y : lo,
reverse = range[1] < range[0],
values = reverse ? ordinalRange().reverse() : ordinalRange(),
n = values.length - 1, a, b, t;

// order range inputs, bail if outside of scale range
if (hi < lo) t = lo, lo = hi, hi = t;
if (hi < values[0] || lo > range[1-reverse]) return undefined;

// binary search to index into scale range
a = Math.max(0, bisectRight(values, lo) - 1);
b = lo===hi ? a : bisectRight(values, hi) - 1;

// increment index a if lo is within padding gap
if (lo - values[a] > bandwidth + 1e-10) ++a;

if (reverse) t = a, a = n - b, b = n - t; // map + swap
return (a > b) ? undefined : domain().slice(a, b+1);
};

scale.copy = function() {
return band()
.domain(domain())
Expand Down
92 changes: 92 additions & 0 deletions test/band-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,96 @@ tape("band.copy() isolates changes to the range", function(test) {
test.end();
});

tape("band.invert(x) inverts single value", function(test) {
var s = scale.scaleBand().domain(["foo", "bar"]);

// ascending range
s.range([0,2]);
test.deepEqual(s.invert(-1), undefined);
test.deepEqual(s.invert(0.0), ["foo"]);
test.deepEqual(s.invert(0.5), ["foo"]);
test.deepEqual(s.invert(1.0), ["bar"]);
test.deepEqual(s.invert(1.5), ["bar"]);
test.deepEqual(s.invert(2.0), ["bar"]);
test.deepEqual(s.invert(2.1), undefined);

// ascending range with padding
s.padding(0.3);
test.deepEqual(s.invert(-1), undefined);
test.deepEqual(s.invert(0.0), undefined);
test.deepEqual(s.invert(0.5), ["foo"]);
test.deepEqual(s.invert(1.0), undefined);
test.deepEqual(s.invert(1.5), ["bar"]);
test.deepEqual(s.invert(2.0), undefined);
test.deepEqual(s.invert(2.1), undefined);

// descending range
s.padding(0).range([2, 0]);
test.deepEqual(s.invert(-1), undefined);
test.deepEqual(s.invert(0.0), ["bar"]);
test.deepEqual(s.invert(0.5), ["bar"]);
test.deepEqual(s.invert(1.0), ["foo"]);
test.deepEqual(s.invert(1.5), ["foo"]);
test.deepEqual(s.invert(2.0), ["foo"]);
test.deepEqual(s.invert(2.1), undefined);

// descending range with padding
s.padding(0.3);
test.deepEqual(s.invert(-1), undefined);
test.deepEqual(s.invert(0.0), undefined);
test.deepEqual(s.invert(0.5), ["bar"]);
test.deepEqual(s.invert(1.0), undefined);
test.deepEqual(s.invert(1.5), ["foo"]);
test.deepEqual(s.invert(2.0), undefined);
test.deepEqual(s.invert(2.1), undefined);

test.end();
});

tape("band.invert(x) inverts value range", function(test) {
var s = scale.scaleBand().domain(["foo", "bar"]);

// ascending range
s.range([0, 2]);
test.deepEqual(s.invert(-2, -1), undefined);
test.deepEqual(s.invert(-1, 0), ["foo"]);
test.deepEqual(s.invert(0, 0.5), ["foo"]);
test.deepEqual(s.invert(0, 1), ["foo", "bar"]);
test.deepEqual(s.invert(0, 2), ["foo", "bar"]);
test.deepEqual(s.invert(2, 3), ["bar"]);
test.deepEqual(s.invert(3, 4), undefined);

// ascending range with padding
s.padding(0.3);
test.deepEqual(s.invert( -1, 0), undefined);
test.deepEqual(s.invert(0.0, 0.1), undefined);
test.deepEqual(s.invert(0.0, 0.5), ["foo"]);
test.deepEqual(s.invert(0.5, 1.5), ["foo", "bar"]);
test.deepEqual(s.invert(0.9, 1.1), undefined);
test.deepEqual(s.invert(1.0, 1.5), ["bar"]);
test.deepEqual(s.invert(1.9, 2.0), undefined);

// descending range
s.padding(0).range([2, 0]);
test.deepEqual(s.invert(-2, -1), undefined);
test.deepEqual(s.invert(-1, 0), ["bar"]);
test.deepEqual(s.invert(0, 0.5), ["bar"]);
test.deepEqual(s.invert(0, 1), ["foo", "bar"]);
test.deepEqual(s.invert(0, 2), ["foo", "bar"]);
test.deepEqual(s.invert(2, 3), ["foo"]);
test.deepEqual(s.invert(3, 4), undefined);

// descending range with padding
s.padding(0.3);
test.deepEqual(s.invert( -1, 0.0), undefined);
test.deepEqual(s.invert(0.0, 0.1), undefined);
test.deepEqual(s.invert(0.0, 0.5), ["bar"]);
test.deepEqual(s.invert(0.5, 1.5), ["foo", "bar"]);
test.deepEqual(s.invert(0.9, 1.1), undefined);
test.deepEqual(s.invert(1.0, 1.5), ["foo"]);
test.deepEqual(s.invert(1.9, 2.0), undefined);

test.end();
});

// TODO align tests for padding & round

0 comments on commit b78edc3

Please sign in to comment.