@@ -177,17 +177,20 @@ function handleCartesian(gd, ev) {
177
177
astr = button . getAttribute ( 'data-attr' ) ,
178
178
val = button . getAttribute ( 'data-val' ) || true ,
179
179
fullLayout = gd . _fullLayout ,
180
- aobj = { } ;
180
+ aobj = { } ,
181
+ axList = Axes . list ( gd , null , true ) ,
182
+ ax ,
183
+ allEnabled = 'on' ,
184
+ i ;
181
185
182
186
if ( astr === 'zoom' ) {
183
187
var mag = ( val === 'in' ) ? 0.5 : 2 ,
184
188
r0 = ( 1 + mag ) / 2 ,
185
- r1 = ( 1 - mag ) / 2 ,
186
- axList = Axes . list ( gd , null , true ) ;
189
+ r1 = ( 1 - mag ) / 2 ;
187
190
188
- var ax , axName ;
191
+ var axName ;
189
192
190
- for ( var i = 0 ; i < axList . length ; i ++ ) {
193
+ for ( i = 0 ; i < axList . length ; i ++ ) {
191
194
ax = axList [ i ] ;
192
195
193
196
if ( ! ax . fixedrange ) {
@@ -202,6 +205,12 @@ function handleCartesian(gd, ev) {
202
205
aobj [ axName + '.range[0]' ] = rangeInitial [ 0 ] ;
203
206
aobj [ axName + '.range[1]' ] = rangeInitial [ 1 ] ;
204
207
}
208
+ if ( ax . _showSpikeInitial !== undefined ) {
209
+ aobj [ axName + '.showspikes' ] = ax . _showSpikeInitial ;
210
+ if ( allEnabled === 'on' && ! ax . _showSpikeInitial ) {
211
+ allEnabled = 'off' ;
212
+ }
213
+ }
205
214
}
206
215
else {
207
216
var rangeNow = [
@@ -219,12 +228,24 @@ function handleCartesian(gd, ev) {
219
228
}
220
229
}
221
230
}
231
+ fullLayout . _cartesianSpikesEnabled = allEnabled ;
222
232
}
223
233
else {
224
234
// if ALL traces have orientation 'h', 'hovermode': 'x' otherwise: 'y'
225
235
if ( astr === 'hovermode' && ( val === 'x' || val === 'y' ) ) {
226
236
val = fullLayout . _isHoriz ? 'y' : 'x' ;
227
237
button . setAttribute ( 'data-val' , val ) ;
238
+ if ( val !== 'closest' ) {
239
+ fullLayout . _cartesianSpikesEnabled = 'off' ;
240
+ }
241
+ } else if ( astr === 'hovermode' && val === 'closest' ) {
242
+ for ( i = 0 ; i < axList . length ; i ++ ) {
243
+ ax = axList [ i ] ;
244
+ if ( allEnabled === 'on' && ! ax . showspikes ) {
245
+ allEnabled = 'off' ;
246
+ }
247
+ }
248
+ fullLayout . _cartesianSpikesEnabled = allEnabled ;
228
249
}
229
250
230
251
aobj [ astr ] = val ;
@@ -518,3 +539,38 @@ modeBarButtons.resetViews = {
518
539
// geo subplots.
519
540
}
520
541
} ;
542
+
543
+ modeBarButtons . toggleSpikelines = {
544
+ name : 'toggleSpikelines' ,
545
+ title : 'Toggle Spike Lines' ,
546
+ icon : Icons . spikeline ,
547
+ attr : '_cartesianSpikesEnabled' ,
548
+ val : 'on' ,
549
+ click : function ( gd ) {
550
+ var fullLayout = gd . _fullLayout ;
551
+
552
+ fullLayout . _cartesianSpikesEnabled = fullLayout . hovermode === 'closest' ?
553
+ ( fullLayout . _cartesianSpikesEnabled === 'on' ? 'off' : 'on' ) : 'on' ;
554
+
555
+ var aobj = setSpikelineVisibility ( gd ) ;
556
+
557
+ aobj . hovermode = 'closest' ;
558
+ Plotly . relayout ( gd , aobj ) ;
559
+ }
560
+ } ;
561
+
562
+ function setSpikelineVisibility ( gd ) {
563
+ var fullLayout = gd . _fullLayout ,
564
+ axList = Axes . list ( gd , null , true ) ,
565
+ ax ,
566
+ axName ,
567
+ aobj = { } ;
568
+
569
+ for ( var i = 0 ; i < axList . length ; i ++ ) {
570
+ ax = axList [ i ] ;
571
+ axName = ax . _name ;
572
+ aobj [ axName + '.showspikes' ] = fullLayout . _cartesianSpikesEnabled === 'on' ? true : false ;
573
+ }
574
+
575
+ return aobj ;
576
+ }
0 commit comments