Skip to content

Commit

Permalink
In band scales, avoid collapsing with round=true when the range is to…
Browse files Browse the repository at this point in the history
…o narrow to accommodate the domain.

fixes #242
  • Loading branch information
Fil committed Mar 31, 2021
1 parent 8afe6bd commit d50549d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/band.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ export default function band() {
start = reverse ? r1 : r0,
stop = reverse ? r0 : r1;
step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
if (round) step = Math.floor(step);
var r = round && step >= 1;
if (r) step = Math.floor(step);
start += (stop - start - step * (n - paddingInner)) * align;
bandwidth = step * (1 - paddingInner);
if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
if (round) start = Math.round(start);
if (r) bandwidth = Math.round(bandwidth);
var values = sequence(n).map(function(i) { return start + step * i; });
return ordinalRange(reverse ? values.reverse() : values);
}
Expand Down
17 changes: 17 additions & 0 deletions test/band-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,23 @@ tape("band.rangeRound(values) coerces values to numbers", function(test) {
test.end();
});

tape("band.round is ignored when the range is too small and the scale would collapse", function(test) {
var domain = ["A", "B", "C", "D", "E", "F"];
var s1 = scale.scaleBand().domain(domain).rangeRound([0, 3]);
test.deepEqual(domain.map(s1), [ 0, 0.5, 1, 1.5, 2, 2.5 ]);
test.equal(s1.bandwidth(), 0.5);
var s2 = scale.scaleBand().domain(domain).rangeRound([0, 30]);
test.deepEqual(domain.map(s2), [ 0, 5, 10, 15, 20, 25 ]);
var s3 = scale.scaleBand().domain(domain).rangeRound([0, 10]);
test.deepEqual(domain.map(s3), [ 2, 3, 4, 5, 6, 7 ]);
var s4 = scale.scaleBand().domain(domain).range([0, 3]).round(true);
test.deepEqual(domain.map(s4), [ 0, 0.5, 1, 1.5, 2, 2.5 ]);
var s5 = scale.scaleBand().domain(domain).range([0, 1.5]).round(true);
test.deepEqual(domain.map(s5), [ 0, 0.25, 0.5, 0.75, 1, 1.25 ]);
test.equal(s5.bandwidth(), 0.25);
test.end();
});

tape("band.paddingInner(p) specifies the inner padding p", function(test) {
var s = scale.scaleBand().domain(["a", "b", "c"]).range([120, 0]).paddingInner(0.1).round(true);
test.deepEqual(s.domain().map(s), [83, 42, 1]);
Expand Down

0 comments on commit d50549d

Please sign in to comment.