@@ -574,54 +574,73 @@ axes.calcTicks = function calcTicks(ax) {
574574 if ( ( ax . _tmin < startTick ) !== axrev ) return [ ] ;
575575
576576 // return the full set of tick vals
577- var tickVals = [ ] ;
578577 if ( ax . type === 'category' || ax . type === 'multicategory' ) {
579578 endTick = ( axrev ) ? Math . max ( - 0.5 , endTick ) :
580579 Math . min ( ax . _categories . length - 0.5 , endTick ) ;
581580 }
582581
583582 var isDLog = ( ax . type === 'log' ) && ! ( isNumeric ( ax . dtick ) || ax . dtick . charAt ( 0 ) === 'L' ) ;
584583
585- var xPrevious = null ;
586- var maxTicks = Math . max ( 1000 , ax . _length || 0 ) ;
587- for ( var x = ax . _tmin ;
588- ( axrev ) ? ( x >= endTick ) : ( x <= endTick ) ;
589- x = axes . tickIncrement ( x , ax . dtick , axrev , ax . calendar ) ) {
590- // prevent infinite loops - no more than one tick per pixel,
591- // and make sure each value is different from the previous
592- if ( tickVals . length > maxTicks || x === xPrevious ) break ;
593- xPrevious = x ;
584+ var tickVals ;
585+ function generateTicks ( ) {
586+ var xPrevious = null ;
587+ var maxTicks = Math . max ( 1000 , ax . _length || 0 ) ;
588+ tickVals = [ ] ;
589+ for ( var x = ax . _tmin ;
590+ ( axrev ) ? ( x >= endTick ) : ( x <= endTick ) ;
591+ x = axes . tickIncrement ( x , ax . dtick , axrev , ax . calendar ) ) {
592+ // prevent infinite loops - no more than one tick per pixel,
593+ // and make sure each value is different from the previous
594+ if ( tickVals . length > maxTicks || x === xPrevious ) break ;
595+ xPrevious = x ;
596+
597+ var minor = false ;
598+ if ( isDLog && ( x !== ( x | 0 ) ) ) {
599+ minor = true ;
600+ }
594601
595- var minor = false ;
596- if ( isDLog && ( x !== ( x | 0 ) ) ) {
597- minor = true ;
602+ tickVals . push ( {
603+ minor : minor ,
604+ value : x
605+ } ) ;
598606 }
599-
600- tickVals . push ( {
601- minor : minor ,
602- value : x
603- } ) ;
604607 }
605608
606- // If same angle over a full circle, the last tick vals is a duplicate.
607- // TODO must do something similar for angular date axes.
608- if ( isAngular ( ax ) && Math . abs ( rng [ 1 ] - rng [ 0 ] ) === 360 ) {
609- tickVals . pop ( ) ;
610- }
609+ generateTicks ( ) ;
611610
612611 if ( ax . breaks ) {
612+ var nTicksBefore = tickVals . length ;
613+
613614 // remove ticks falling inside breaks
614615 tickVals = tickVals . filter ( function ( d ) {
615616 return ax . maskBreaks ( d . value ) !== BADNUM ;
616617 } ) ;
617618
618- // TODO what to do with "overlapping" ticks?
619+ // if 'numerous' ticks get placed into breaks,
620+ // increase dtick to generate more ticks,
621+ // so that some hopefully fall between breaks
622+ if ( ax . tickmode === 'auto' && tickVals . length < nTicksBefore / 6 ) {
623+ ax . dtick /= 2 ;
624+ ax . _tmin = axes . tickFirst ( ax ) ;
625+ generateTicks ( ) ;
626+ tickVals = tickVals . filter ( function ( d ) {
627+ return ax . maskBreaks ( d . value ) !== BADNUM ;
628+ } ) ;
629+ }
630+
631+ // remove "overlapping" ticks (e.g. on either side of a break)
619632 var tf2 = ax . tickfont ? 1.5 * ax . tickfont . size : 0 ;
620633 tickVals = tickVals . filter ( function ( d , i , self ) {
621634 return ! ( i && Math . abs ( ax . c2p ( d . value ) - ax . c2p ( self [ i - 1 ] . value ) ) < tf2 ) ;
622635 } ) ;
623636 }
624637
638+ // If same angle over a full circle, the last tick vals is a duplicate.
639+ // TODO must do something similar for angular date axes.
640+ if ( isAngular ( ax ) && Math . abs ( rng [ 1 ] - rng [ 0 ] ) === 360 ) {
641+ tickVals . pop ( ) ;
642+ }
643+
625644 // save the last tick as well as first, so we can
626645 // show the exponent only on the last one
627646 ax . _tmax = ( tickVals [ tickVals . length - 1 ] || { } ) . value ;
@@ -739,8 +758,6 @@ axes.autoTicks = function(ax, roughDTick) {
739758 // being > half of the final unit - so precalculate twice the rough val
740759 var roughX2 = 2 * roughDTick ;
741760
742- // TODO find way to have 'better' first tick on axes with breaks
743-
744761 if ( roughX2 > ONEAVGYEAR ) {
745762 roughDTick /= ONEAVGYEAR ;
746763 base = getBase ( 10 ) ;
@@ -799,9 +816,6 @@ axes.autoTicks = function(ax, roughDTick) {
799816 ax . tick0 = 0 ;
800817 base = getBase ( 10 ) ;
801818 ax . dtick = roundDTick ( roughDTick , base , roundBase10 ) ;
802-
803- // TODO having tick0 = 0 being insider a breaks does not seem
804- // to matter ...
805819 }
806820
807821 // prevent infinite loops
0 commit comments