@@ -72,10 +72,18 @@ module.exports = function draw(gd) {
7272 computeLabelSteps ( sliderOpts ) ;
7373
7474 Plots . manageCommandObserver ( gd , sliderOpts , sliderOpts . steps , function ( data ) {
75- if ( sliderOpts . active === data . index ) return ;
76- if ( sliderOpts . _dragging ) return ;
77-
78- setActive ( gd , gSlider , sliderOpts , data . index , false , true ) ;
75+ // NB: Same as below. This is *not* always the same as sliderOpts since
76+ // if a new set of steps comes in, the reference in this callback would
77+ // be invalid. We need to refetch it from the slider group, which is
78+ // the join data that creates this slider. So if this slider still exists,
79+ // the group should be valid, *to the best of my knowledge.* If not,
80+ // we'd have to look it up by d3 data join index/key.
81+ var opts = gSlider . data ( ) [ 0 ] ;
82+
83+ if ( opts . active === data . index ) return ;
84+ if ( opts . _dragging ) return ;
85+
86+ setActive ( gd , gSlider , opts , data . index , false , true ) ;
7987 } ) ;
8088
8189 drawSlider ( gd , d3 . select ( this ) , sliderOpts ) ;
@@ -225,6 +233,15 @@ function findDimensions(gd, sliderOpts) {
225233}
226234
227235function drawSlider ( gd , sliderGroup , sliderOpts ) {
236+ // This is related to the other long notes in this file regarding what happens
237+ // when slider steps disappear. This particular fix handles what happens when
238+ // the *current* slider step is removed. The drawing functions will error out
239+ // when they fail to find it, so the fix for now is that it will just draw the
240+ // slider in the first position but will not execute the command.
241+ if ( sliderOpts . active >= sliderOpts . steps . length ) {
242+ sliderOpts . active = 0 ;
243+ }
244+
228245 // These are carefully ordered for proper z-ordering:
229246 sliderGroup
230247 . call ( drawCurrentValue , sliderOpts )
@@ -251,9 +268,9 @@ function drawCurrentValue(sliderGroup, sliderOpts, valueOverride) {
251268
252269 switch ( sliderOpts . currentvalue . xanchor ) {
253270 case 'right' :
254- // This is anchored left and adjusted by the width of the longest label
255- // so that the prefix doesn't move. The goal of this is to emphasize
256- // what's actually changing and make the update less distracting.
271+ // This is anchored left and adjusted by the width of the longest label
272+ // so that the prefix doesn't move. The goal of this is to emphasize
273+ // what's actually changing and make the update less distracting.
257274 x0 = sliderOpts . inputAreaLength - constants . currentValueInset - sliderOpts . currentValueMaxWidth ;
258275 textAnchor = 'left' ;
259276 break ;
@@ -402,11 +419,21 @@ function setActive(gd, sliderGroup, sliderOpts, index, doCallback, doTransition)
402419 }
403420}
404421
405- function attachGripEvents ( item , gd , sliderGroup , sliderOpts ) {
422+ function attachGripEvents ( item , gd , sliderGroup ) {
406423 var node = sliderGroup . node ( ) ;
407424 var $gd = d3 . select ( gd ) ;
408425
426+ // NB: This is *not* the same as sliderOpts itself! These callbacks
427+ // are in a closure so this array won't actually be correct if the
428+ // steps have changed since this was initialized. The sliderGroup,
429+ // however, has not changed since that *is* the slider, so it must
430+ // be present to receive mouse events.
431+ function getSliderOpts ( ) {
432+ return sliderGroup . data ( ) [ 0 ] ;
433+ }
434+
409435 item . on ( 'mousedown' , function ( ) {
436+ var sliderOpts = getSliderOpts ( ) ;
410437 gd . emit ( 'plotly_sliderstart' , { slider : sliderOpts } ) ;
411438
412439 var grip = sliderGroup . select ( '.' + constants . gripRectClass ) ;
@@ -420,11 +447,13 @@ function attachGripEvents(item, gd, sliderGroup, sliderOpts) {
420447 sliderOpts . _dragging = true ;
421448
422449 $gd . on ( 'mousemove' , function ( ) {
450+ var sliderOpts = getSliderOpts ( ) ;
423451 var normalizedPosition = positionToNormalizedValue ( sliderOpts , d3 . mouse ( node ) [ 0 ] ) ;
424452 handleInput ( gd , sliderGroup , sliderOpts , normalizedPosition , false ) ;
425453 } ) ;
426454
427455 $gd . on ( 'mouseup' , function ( ) {
456+ var sliderOpts = getSliderOpts ( ) ;
428457 sliderOpts . _dragging = false ;
429458 grip . call ( Color . fill , sliderOpts . bgcolor ) ;
430459 $gd . on ( 'mouseup' , null ) ;
0 commit comments