Skip to content

Commit

Permalink
fix #263; don’t mutate user thresholds
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Dec 3, 2022
1 parent 147e2bf commit bec0354
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
10 changes: 6 additions & 4 deletions src/bin.js
Expand Up @@ -66,9 +66,11 @@ export default function bin() {
}

// Remove any thresholds outside the domain.
var m = tz.length;
while (tz[0] <= x0) tz.shift(), --m;
while (tz[m - 1] > x1) tz.pop(), --m;
// Be careful not to mutate an array owned by the user!
var m = tz.length, a = 0, b = m;
while (tz[a] <= x0) ++a;
while (tz[b - 1] > x1) --b;
if (a || (b < m)) tz = tz.slice(a, b), m = b - a;

var bins = new Array(m + 1),
bin;
Expand Down Expand Up @@ -116,7 +118,7 @@ export default function bin() {
};

histogram.thresholds = function(_) {
return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;
return arguments.length ? (threshold = typeof _ === "function" ? _ : constant(Array.isArray(_) ? slice.call(_) : _), histogram) : threshold;
};

return histogram;
Expand Down
16 changes: 16 additions & 0 deletions test/bin-test.js
Expand Up @@ -241,6 +241,22 @@ it("bin(data) assigns integer values to the correct bins", () => {
assert.deepStrictEqual(bin().domain([3, 8])(eights), [box([], 3, 4), box([], 4, 5), box([], 5, 6), box([], 6, 7), box(eights, 7, 8)]);
});

it("bin(data) does not mutate user-supplied thresholds as an array", () => {
const thresholds = [3, 4, 5, 6];
const b = bin().domain([4, 5]).thresholds(thresholds);
assert.deepStrictEqual(b([5]), [box([], 4, 5), box([5], 5, 5)]);
assert.deepStrictEqual(thresholds, [3, 4, 5, 6]);
assert.deepStrictEqual(b.thresholds()(), [3, 4, 5, 6]);
});

it("bin(data) does not mutate user-supplied thresholds as a function", () => {
const thresholds = [3, 4, 5, 6];
const b = bin().domain([4, 5]).thresholds(() => thresholds);
assert.deepStrictEqual(b([5]), [box([], 4, 5), box([5], 5, 5)]);
assert.deepStrictEqual(thresholds, [3, 4, 5, 6]);
assert.deepStrictEqual(b.thresholds()(), [3, 4, 5, 6]);
});

function box(bin, x0, x1) {
bin.x0 = x0;
bin.x1 = x1;
Expand Down

0 comments on commit bec0354

Please sign in to comment.