@@ -34,6 +34,11 @@ var ONESEC = constants.ONESEC;
3434var MINUS_SIGN = constants . MINUS_SIGN ;
3535var BADNUM = constants . BADNUM ;
3636
37+ var ZERO_PATH = { K : 'zeroline' } ;
38+ var GRID_PATH = { K : 'gridline' , L : 'path' } ;
39+ var TICK_PATH = { K : 'tick' , L : 'path' } ;
40+ var TICK_TEXT = { K : 'tick' , L : 'text' } ;
41+
3742var alignmentConstants = require ( '../../constants/alignment' ) ;
3843var MID_SHIFT = alignmentConstants . MID_SHIFT ;
3944var CAP_SHIFT = alignmentConstants . CAP_SHIFT ;
@@ -1449,7 +1454,7 @@ function formatDate(ax, out, hover, extraPrecision) {
14491454 ax . _prevDateHead = headStr ;
14501455 dateStr += '<br>' + headStr ;
14511456 } else {
1452- var isInside = ( ax . ticklabelposition || '' ) . indexOf ( 'inside' ) !== - 1 ;
1457+ var isInside = insideTicklabelposition ( ax ) ;
14531458 var side = ax . _realSide || ax . side ; // polar mocks the side of the radial axis
14541459 if (
14551460 ( ! isInside && side === 'top' ) ||
@@ -2180,6 +2185,7 @@ axes.drawOne = function(gd, ax, opts) {
21802185 return axes . drawLabels ( gd , ax , {
21812186 vals : vals ,
21822187 layer : mainAxLayer ,
2188+ plotinfo : plotinfo ,
21832189 transFn : transTickLabelFn ,
21842190 labelFns : axes . makeLabelFns ( ax , mainLinePosition )
21852191 } ) ;
@@ -2798,7 +2804,10 @@ axes.drawTicks = function(gd, ax, opts) {
27982804 . classed ( 'crisp' , opts . crisp !== false )
27992805 . call ( Color . stroke , ax . tickcolor )
28002806 . style ( 'stroke-width' , Drawing . crispRound ( gd , ax . tickwidth , 1 ) + 'px' )
2801- . attr ( 'd' , opts . path ) ;
2807+ . attr ( 'd' , opts . path )
2808+ . style ( 'display' , null ) ; // visible
2809+
2810+ hideCounterAxisInsideTickLabels ( ax , [ TICK_PATH ] ) ;
28022811
28032812 ticks . attr ( 'transform' , opts . transFn ) ;
28042813} ;
@@ -2861,7 +2870,10 @@ axes.drawGrid = function(gd, ax, opts) {
28612870 grid . attr ( 'transform' , opts . transFn )
28622871 . attr ( 'd' , opts . path )
28632872 . call ( Color . stroke , ax . gridcolor || '#ddd' )
2864- . style ( 'stroke-width' , ax . _gw + 'px' ) ;
2873+ . style ( 'stroke-width' , ax . _gw + 'px' )
2874+ . style ( 'display' , null ) ; // visible
2875+
2876+ hideCounterAxisInsideTickLabels ( ax , [ GRID_PATH ] ) ;
28652877
28662878 if ( typeof opts . path === 'function' ) grid . attr ( 'd' , opts . path ) ;
28672879} ;
@@ -2910,7 +2922,10 @@ axes.drawZeroLine = function(gd, ax, opts) {
29102922 zl . attr ( 'transform' , opts . transFn )
29112923 . attr ( 'd' , opts . path )
29122924 . call ( Color . stroke , ax . zerolinecolor || Color . defaultLine )
2913- . style ( 'stroke-width' , Drawing . crispRound ( gd , ax . zerolinewidth , ax . _gw || 1 ) + 'px' ) ;
2925+ . style ( 'stroke-width' , Drawing . crispRound ( gd , ax . zerolinewidth , ax . _gw || 1 ) + 'px' )
2926+ . style ( 'display' , null ) ; // visible
2927+
2928+ hideCounterAxisInsideTickLabels ( ax , [ ZERO_PATH ] ) ;
29142929} ;
29152930
29162931/**
@@ -2983,7 +2998,10 @@ axes.drawLabels = function(gd, ax, opts) {
29832998 // sync label: just position it now.
29842999 positionLabels ( thisLabel , tickAngle ) ;
29853000 }
2986- } ) ;
3001+ } )
3002+ . style ( 'display' , null ) ; // visible
3003+
3004+ hideCounterAxisInsideTickLabels ( ax , [ TICK_TEXT ] ) ;
29873005
29883006 tickLabels . exit ( ) . remove ( ) ;
29893007
@@ -2995,7 +3013,7 @@ axes.drawLabels = function(gd, ax, opts) {
29953013 }
29963014
29973015 function positionLabels ( s , angle ) {
2998- var isInside = ( ax . ticklabelposition || '' ) . indexOf ( 'inside' ) !== - 1 ;
3016+ var isInside = insideTicklabelposition ( ax ) ;
29993017
30003018 s . each ( function ( d ) {
30013019 var thisLabel = d3 . select ( this ) ;
@@ -3025,8 +3043,7 @@ axes.drawLabels = function(gd, ax, opts) {
30253043 } ) ;
30263044
30273045 if ( isInside ) {
3028- // ensure visible
3029- thisText . style ( { opacity : 100 } ) ;
3046+ thisText . style ( 'opacity' , 0 ) ; // visible
30303047
30313048 if ( ax . _hideOutOfRangeInsideTickLabels ) {
30323049 ax . _hideOutOfRangeInsideTickLabels ( ) ;
@@ -3040,9 +3057,8 @@ axes.drawLabels = function(gd, ax, opts) {
30403057 } ) ;
30413058 }
30423059
3043- ax . _hideOutOfRangeInsideTickLabels = undefined ;
3044- if ( ( ax . ticklabelposition || '' ) . indexOf ( 'inside' ) !== - 1 ) {
3045- ax . _hideOutOfRangeInsideTickLabels = function ( ) {
3060+ ax . _hideOutOfRangeInsideTickLabels = function ( ) {
3061+ if ( insideTicklabelposition ( ax ) ) {
30463062 var rl = Lib . simpleMap ( ax . range , ax . r2l ) ;
30473063
30483064 // hide inside tick labels that go outside axis end points
@@ -3052,8 +3068,12 @@ axes.drawLabels = function(gd, ax, opts) {
30523068 var min = Math . min ( p0 , p1 ) + ax . _offset ;
30533069 var max = Math . max ( p0 , p1 ) + ax . _offset ;
30543070
3071+ var side = ax . side ;
30553072 var isX = ax . _id . charAt ( 0 ) === 'x' ;
30563073
3074+ var visibleLabelMin = Infinity ;
3075+ var visibleLabelMax = - Infinity ;
3076+
30573077 tickLabels . each ( function ( d ) {
30583078 var thisLabel = d3 . select ( this ) ;
30593079 var mathjaxGroup = thisLabel . select ( '.text-math-group' ) ;
@@ -3068,11 +3088,69 @@ axes.drawLabels = function(gd, ax, opts) {
30683088 if ( bb . bottom > max ) hide = true ;
30693089 else if ( bb . top + ( ax . tickangle ? 0 : d . fontSize / 4 ) < min ) hide = true ;
30703090 }
3071- if ( hide ) thisLabel . select ( 'text' ) . style ( { opacity : 0 } ) ;
3091+
3092+ var t = thisLabel . select ( 'text' ) ;
3093+ if ( hide ) {
3094+ t . style ( 'opacity' , 0 ) ; // hidden
3095+ } else {
3096+ t . style ( 'opacity' , 1 ) ; // visible
3097+
3098+ if ( side === 'bottom' || side === 'right' ) {
3099+ visibleLabelMin = Math . min ( visibleLabelMin , isX ? bb . top : bb . left ) ;
3100+ } else {
3101+ visibleLabelMin = - Infinity ;
3102+ }
3103+
3104+ if ( side === 'top' || side === 'left' ) {
3105+ visibleLabelMax = Math . max ( visibleLabelMax , isX ? bb . bottom : bb . right ) ;
3106+ } else {
3107+ visibleLabelMax = Infinity ;
3108+ }
3109+ }
30723110 } // TODO: hide mathjax?
30733111 } ) ;
3074- } ;
3075- }
3112+
3113+ if ( ax . _anchorAxis ) {
3114+ ax . _anchorAxis . _visibleLabelMin = visibleLabelMin ;
3115+ ax . _anchorAxis . _visibleLabelMax = visibleLabelMax ;
3116+ }
3117+ }
3118+ } ;
3119+
3120+ ax . _hideCounterAxisInsideTickLabels = function ( partialOpts ) {
3121+ if ( insideTicklabelposition ( ax . _anchorAxis || { } ) ) {
3122+ ( partialOpts || [
3123+ ZERO_PATH ,
3124+ GRID_PATH ,
3125+ TICK_PATH ,
3126+ TICK_TEXT
3127+ ] ) . forEach ( function ( e ) {
3128+ var isTickText = e . K === 'tick' && e . L === 'text' ;
3129+ if ( isTickText && ax . ticklabelmode === 'period' ) return ;
3130+
3131+ var sel ;
3132+ if ( e . K === ZERO_PATH . K ) sel = opts . plotinfo . zerolinelayer . selectAll ( '.' + ax . _id + 'zl' ) ;
3133+ else if ( e . K === GRID_PATH . K ) sel = opts . plotinfo . gridlayer . selectAll ( '.' + ax . _id ) ;
3134+ else sel = opts . plotinfo [ ax . _id . charAt ( 0 ) + 'axislayer' ] ;
3135+
3136+ sel . each ( function ( ) {
3137+ var w = d3 . select ( this ) ;
3138+ if ( e . L ) w = w . selectAll ( e . L ) ;
3139+
3140+ w . each ( function ( d ) {
3141+ var q = ax . l2p ( d . x ) + ax . _offset ;
3142+
3143+ var t = d3 . select ( this ) ;
3144+ if ( q < ax . _visibleLabelMax && q > ax . _visibleLabelMin ) {
3145+ t . style ( 'display' , 'none' ) ; // hidden
3146+ } else if ( e . K === 'tick' ) {
3147+ t . style ( 'display' , null ) ; // visible
3148+ }
3149+ } ) ;
3150+ } ) ;
3151+ } ) ;
3152+ }
3153+ } ;
30763154
30773155 // make sure all labels are correctly positioned at their base angle
30783156 // the positionLabels call above is only for newly drawn labels.
@@ -3201,7 +3279,7 @@ axes.drawLabels = function(gd, ax, opts) {
32013279 var anchorAx = ax . _anchorAxis ;
32023280 if (
32033281 anchorAx && anchorAx . autorange &&
3204- ( ax . ticklabelposition || '' ) . indexOf ( 'inside' ) !== - 1 &&
3282+ insideTicklabelposition ( ax ) &&
32053283 ! isLinked ( fullLayout , ax . _id )
32063284 ) {
32073285 if ( ! fullLayout . _insideTickLabelsAutorange ) {
@@ -3350,7 +3428,7 @@ function drawTitle(gd, ax) {
33503428 if ( ax . title . hasOwnProperty ( 'standoff' ) ) {
33513429 titleStandoff = ax . _depth + ax . title . standoff + approxTitleDepth ( ax ) ;
33523430 } else {
3353- var isInside = ( ax . ticklabelposition || '' ) . indexOf ( 'inside' ) !== - 1 ;
3431+ var isInside = insideTicklabelposition ( ax ) ;
33543432
33553433 if ( ax . type === 'multicategory' ) {
33563434 titleStandoff = ax . _depth ;
@@ -3708,3 +3786,15 @@ function moveOutsideBreak(v, ax) {
37083786 }
37093787 return v ;
37103788}
3789+
3790+ function insideTicklabelposition ( ax ) {
3791+ return ( ( ax . ticklabelposition || '' ) . indexOf ( 'inside' ) !== - 1 ) ;
3792+ }
3793+
3794+ function hideCounterAxisInsideTickLabels ( ax , opts ) {
3795+ if ( insideTicklabelposition ( ax . _anchorAxis || { } ) ) {
3796+ if ( ax . _hideCounterAxisInsideTickLabels ) {
3797+ ax . _hideCounterAxisInsideTickLabels ( opts ) ;
3798+ }
3799+ }
3800+ }
0 commit comments