@@ -526,7 +526,10 @@ axes.prepTicks = function(ax) {
526526 // have explicit tickvals without tick text
527527 if ( ax . tickmode === 'array' ) nt *= 100 ;
528528
529- axes . autoTicks ( ax , Math . abs ( rng [ 1 ] - rng [ 0 ] ) / nt ) ;
529+
530+ ax . _roughDTick = ( Math . abs ( rng [ 1 ] - rng [ 0 ] ) - ( ax . _lBreaks || 0 ) ) / nt ;
531+ axes . autoTicks ( ax , ax . _roughDTick ) ;
532+
530533 // check for a forced minimum dtick
531534 if ( ax . _minDtick > 0 && ax . dtick < ax . _minDtick * 2 ) {
532535 ax . dtick = ax . _minDtick ;
@@ -573,32 +576,65 @@ axes.calcTicks = function calcTicks(ax) {
573576 if ( ( ax . _tmin < startTick ) !== axrev ) return [ ] ;
574577
575578 // return the full set of tick vals
576- var tickVals = [ ] ;
577579 if ( ax . type === 'category' || ax . type === 'multicategory' ) {
578580 endTick = ( axrev ) ? Math . max ( - 0.5 , endTick ) :
579581 Math . min ( ax . _categories . length - 0.5 , endTick ) ;
580582 }
581583
582584 var isDLog = ( ax . type === 'log' ) && ! ( isNumeric ( ax . dtick ) || ax . dtick . charAt ( 0 ) === 'L' ) ;
583585
584- var xPrevious = null ;
585- var maxTicks = Math . max ( 1000 , ax . _length || 0 ) ;
586- for ( var x = ax . _tmin ;
587- ( axrev ) ? ( x >= endTick ) : ( x <= endTick ) ;
588- x = axes . tickIncrement ( x , ax . dtick , axrev , ax . calendar ) ) {
589- // prevent infinite loops - no more than one tick per pixel,
590- // and make sure each value is different from the previous
591- if ( tickVals . length > maxTicks || x === xPrevious ) break ;
592- xPrevious = x ;
586+ var tickVals ;
587+ function generateTicks ( ) {
588+ var xPrevious = null ;
589+ var maxTicks = Math . max ( 1000 , ax . _length || 0 ) ;
590+ tickVals = [ ] ;
591+ for ( var x = ax . _tmin ;
592+ ( axrev ) ? ( x >= endTick ) : ( x <= endTick ) ;
593+ x = axes . tickIncrement ( x , ax . dtick , axrev , ax . calendar ) ) {
594+ // prevent infinite loops - no more than one tick per pixel,
595+ // and make sure each value is different from the previous
596+ if ( tickVals . length > maxTicks || x === xPrevious ) break ;
597+ xPrevious = x ;
598+
599+ var minor = false ;
600+ if ( isDLog && ( x !== ( x | 0 ) ) ) {
601+ minor = true ;
602+ }
603+
604+ tickVals . push ( {
605+ minor : minor ,
606+ value : x
607+ } ) ;
608+ }
609+ }
610+
611+ generateTicks ( ) ;
612+
613+ if ( ax . breaks ) {
614+ var nTicksBefore = tickVals . length ;
615+
616+ // remove ticks falling inside breaks
617+ tickVals = tickVals . filter ( function ( d ) {
618+ return ax . maskBreaks ( d . value ) !== BADNUM ;
619+ } ) ;
593620
594- var minor = false ;
595- if ( isDLog && ( x !== ( x | 0 ) ) ) {
596- minor = true ;
621+ // if 'numerous' ticks get placed into breaks,
622+ // increase dtick to generate more ticks,
623+ // so that some hopefully fall between breaks
624+ if ( ax . tickmode === 'auto' && tickVals . length < nTicksBefore / 6 ) {
625+ axes . autoTicks ( ax , ax . _roughDTick / 3 ) ;
626+ autoTickRound ( ax ) ;
627+ ax . _tmin = axes . tickFirst ( ax ) ;
628+ generateTicks ( ) ;
629+ tickVals = tickVals . filter ( function ( d ) {
630+ return ax . maskBreaks ( d . value ) !== BADNUM ;
631+ } ) ;
597632 }
598633
599- tickVals . push ( {
600- minor : minor ,
601- value : x
634+ // remove "overlapping" ticks (e.g. on either side of a break)
635+ var tf2 = ax . tickfont ? 1.5 * ax . tickfont . size : 0 ;
636+ tickVals = tickVals . filter ( function ( d , i , self ) {
637+ return ! ( i && Math . abs ( ax . c2p ( d . value ) - ax . c2p ( self [ i - 1 ] . value ) ) < tf2 ) ;
602638 } ) ;
603639 }
604640
@@ -670,6 +706,13 @@ function arrayTicks(ax) {
670706
671707 if ( j < vals . length ) ticksOut . splice ( j , vals . length - j ) ;
672708
709+ if ( ax . breaks ) {
710+ // remove ticks falling inside breaks
711+ ticksOut = ticksOut . filter ( function ( d ) {
712+ return ax . maskBreaks ( d . x ) !== BADNUM ;
713+ } ) ;
714+ }
715+
673716 return ticksOut ;
674717}
675718
@@ -966,7 +1009,7 @@ axes.tickText = function(ax, x, hover, noSuffixPrefix) {
9661009
9671010 if ( arrayMode && Array . isArray ( ax . ticktext ) ) {
9681011 var rng = Lib . simpleMap ( ax . range , ax . r2l ) ;
969- var minDiff = Math . abs ( rng [ 1 ] - rng [ 0 ] ) / 10000 ;
1012+ var minDiff = ( Math . abs ( rng [ 1 ] - rng [ 0 ] ) - ( ax . _lBreaks || 0 ) ) / 10000 ;
9701013
9711014 for ( i = 0 ; i < ax . ticktext . length ; i ++ ) {
9721015 if ( Math . abs ( x - tickVal2l ( ax . tickvals [ i ] ) ) < minDiff ) break ;
@@ -2828,6 +2871,7 @@ axes.shouldShowZeroLine = function(gd, ax, counterAxis) {
28282871 ( rng [ 0 ] * rng [ 1 ] <= 0 ) &&
28292872 ax . zeroline &&
28302873 ( ax . type === 'linear' || ax . type === '-' ) &&
2874+ ! ( ax . breaks && ax . maskBreaks ( 0 ) === BADNUM ) &&
28312875 (
28322876 clipEnds ( ax , 0 ) ||
28332877 ! anyCounterAxLineAtZero ( gd , ax , counterAxis , rng ) ||
0 commit comments