@@ -183,7 +183,8 @@ function handleCartesian(gd, ev) {
183183 var mag = ( val === 'in' ) ? 0.5 : 2 ,
184184 r0 = ( 1 + mag ) / 2 ,
185185 r1 = ( 1 - mag ) / 2 ,
186- axList = Axes . list ( gd , null , true ) ;
186+ axList = Axes . list ( gd , null , true ) ,
187+ allEnabled = 'on' ;
187188
188189 var ax , axName ;
189190
@@ -202,6 +203,12 @@ function handleCartesian(gd, ev) {
202203 aobj [ axName + '.range[0]' ] = rangeInitial [ 0 ] ;
203204 aobj [ axName + '.range[1]' ] = rangeInitial [ 1 ] ;
204205 }
206+ if ( ax . _showSpikeInitial !== undefined ) {
207+ aobj [ axName + '.showspike' ] = ax . _showSpikeInitial ;
208+ if ( allEnabled === 'on' && ! ax . _showSpikeInitial ) {
209+ allEnabled = 'off' ;
210+ }
211+ }
205212 }
206213 else {
207214 var rangeNow = [
@@ -219,12 +226,17 @@ function handleCartesian(gd, ev) {
219226 }
220227 }
221228 }
229+ fullLayout . _cartesianSpikesEnabled = allEnabled ;
222230 }
223231 else {
224232 // if ALL traces have orientation 'h', 'hovermode': 'x' otherwise: 'y'
225233 if ( astr === 'hovermode' && ( val === 'x' || val === 'y' ) ) {
226234 val = fullLayout . _isHoriz ? 'y' : 'x' ;
227235 button . setAttribute ( 'data-val' , val ) ;
236+ if ( val !== 'closest' ) {
237+ fullLayout . _cartesianSpikesEnabled = 'off' ;
238+ aobj = setSpikelineVisibility ( gd ) ;
239+ }
228240 }
229241
230242 aobj [ astr ] = val ;
@@ -518,3 +530,38 @@ modeBarButtons.resetViews = {
518530 // geo subplots.
519531 }
520532} ;
533+
534+ modeBarButtons . toggleSpikelines = {
535+ name : 'toggleSpikelines' ,
536+ title : 'Toggle Spike Lines' ,
537+ icon : Icons . home ,
538+ attr : '_cartesianSpikesEnabled' ,
539+ val : 'on' ,
540+ click : function ( gd ) {
541+ var fullLayout = gd . _fullLayout ;
542+
543+ fullLayout . _cartesianSpikesEnabled = fullLayout . hovermode === 'closest' ?
544+ ( fullLayout . _cartesianSpikesEnabled === 'on' ? 'off' : 'on' ) : 'on' ;
545+
546+ var aobj = setSpikelineVisibility ( gd ) ;
547+
548+ aobj . hovermode = 'closest' ;
549+ Plotly . relayout ( gd , aobj ) ;
550+ }
551+ } ;
552+
553+ function setSpikelineVisibility ( gd ) {
554+ var fullLayout = gd . _fullLayout ,
555+ axList = Axes . list ( gd , null , true ) ,
556+ ax ,
557+ axName ,
558+ aobj = { } ;
559+
560+ for ( var i = 0 ; i < axList . length ; i ++ ) {
561+ ax = axList [ i ] ;
562+ axName = ax . _name ;
563+ aobj [ axName + '.showspike' ] = fullLayout . _cartesianSpikesEnabled === 'on' ? true : false ;
564+ }
565+
566+ return aobj ;
567+ }
0 commit comments