@@ -581,7 +581,8 @@ axes.calcTicks = function calcTicks(ax) {
581
581
var maxTicks = Math . max ( 1000 , ax . _length || 0 ) ;
582
582
for ( var x = ax . _tmin ;
583
583
( axrev ) ? ( x >= endTick ) : ( x <= endTick ) ;
584
- x = axes . tickIncrement ( x , ax . dtick , axrev , ax . calendar ) ) {
584
+ x = axes . tickIncrement ( x , ax . dtick , axrev , ax . calendar )
585
+ ) {
585
586
// prevent infinite loops - no more than one tick per pixel,
586
587
// and make sure each value is different from the previous
587
588
if ( vals . length > maxTicks || x === xPrevious ) break ;
@@ -846,7 +847,27 @@ axes.tickIncrement = function(x, dtick, axrev, calendar) {
846
847
var axSign = axrev ? - 1 : 1 ;
847
848
848
849
// includes linear, all dates smaller than month, and pure 10^n in log
849
- if ( isNumeric ( dtick ) ) return x + axSign * dtick ;
850
+ if ( isNumeric ( dtick ) ) {
851
+ // Note 1:
852
+ // 0.3 != 0.1 + 0.2 but 0.3 == ((10 * 0.1) + (10 * 0.2)) / 10
853
+ // Attempt to use integer steps to increment
854
+ var magic = 1 / dtick ;
855
+ var newX = (
856
+ magic * x +
857
+ magic * axSign * dtick
858
+ ) / magic ;
859
+
860
+ // Note 2: now we may also consider rounding to cover few more edge cases
861
+ var lenDt = ( '' + dtick ) . length ;
862
+ var lenX0 = ( '' + x ) . length ;
863
+ var lenX1 = ( '' + newX ) . length ;
864
+
865
+ if ( lenX1 > lenX0 + lenDt ) { // this is likey a rounding error!
866
+ newX = + parseFloat ( newX ) . toPrecision ( 12 ) ;
867
+ }
868
+
869
+ return newX ;
870
+ }
850
871
851
872
// everything else is a string, one character plus a number
852
873
var tType = dtick . charAt ( 0 ) ;
0 commit comments