Skip to content

Commit 3b8c3b3

Browse files
committed
smarter tick count limit for cartesian axes
1 parent e3eba8a commit 3b8c3b3

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

src/plots/cartesian/axes.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -804,13 +804,18 @@ axes.calcTicks = function calcTicks(ax) {
804804
endtick = (axrev) ? Math.max(-0.5, endtick) :
805805
Math.min(ax._categories.length - 0.5, endtick);
806806
}
807+
808+
var xPrevious = null;
809+
var maxTicks = Math.max(1000, ax._length || 0);
807810
for(var x = ax._tmin;
808811
(axrev) ? (x >= endtick) : (x <= endtick);
809812
x = axes.tickIncrement(x, ax.dtick, axrev, ax.calendar)) {
810-
vals.push(x);
813+
// prevent infinite loops - no more than one tick per pixel,
814+
// and make sure each value is different from the previous
815+
if(vals.length > maxTicks || x === xPrevious) break;
816+
xPrevious = x;
811817

812-
// prevent infinite loops
813-
if(vals.length > 1000) break;
818+
vals.push(x);
814819
}
815820

816821
// save the last tick as well as first, so we can

test/jasmine/tests/axes_test.js

+32
Original file line numberDiff line numberDiff line change
@@ -2225,6 +2225,38 @@ describe('Test axes', function() {
22252225
['2000-01-01 11:00:00.0001', 'Jan 1, 2000, 11:00:00.0001']
22262226
]);
22272227
});
2228+
2229+
it('avoids infinite loops due to rounding errors', function() {
2230+
var textOut = mockCalc({
2231+
type: 'linear',
2232+
tickmode: 'linear',
2233+
tick0: 1e200,
2234+
dtick: 1e-200,
2235+
range: [1e200, 2e200]
2236+
});
2237+
2238+
// This actually gives text '-Infinity' because it can't
2239+
// calculate the first tick properly, but since it's not going to
2240+
// be able to do any better with the rest, we don't much care.
2241+
expect(textOut.length).toBe(1);
2242+
});
2243+
2244+
it('truncates at the greater of 1001 ticks or one per pixel', function() {
2245+
var ax = {
2246+
type: 'linear',
2247+
tickmode: 'linear',
2248+
tick0: 0,
2249+
dtick: 1,
2250+
range: [0, 1e6],
2251+
_length: 100
2252+
};
2253+
2254+
expect(mockCalc(ax).length).toBe(1001);
2255+
2256+
ax._length = 10000;
2257+
2258+
expect(mockCalc(ax).length).toBe(10001);
2259+
});
22282260
});
22292261

22302262
describe('autoBin', function() {

0 commit comments

Comments
 (0)