Skip to content

Commit 8fe1842

Browse files
committed
Tweak slider behavior to avoid event -> method loops
1 parent e13e0ee commit 8fe1842

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

src/components/sliders/draw.js

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ function attachListeners(gd, sliderGroup, sliderOpts) {
230230
value = Lib.nestedProperty(data, updatevalue).get();
231231
}
232232

233+
// If it's *currently* invoking a command an event is received,
234+
// then we'll ignore the event in order to avoid complicated
235+
// invinite loops.
236+
if(sliderOpts._invokingCommand) return;
237+
233238
setActiveByLabel(gd, sliderGroup, sliderOpts, value, false, true);
234239
};
235240
}
@@ -338,17 +343,38 @@ function setActiveByLabel(gd, sliderGroup, sliderOpts, label, doCallback, doTran
338343
function setActive(gd, sliderGroup, sliderOpts, index, doCallback, doTransition) {
339344
sliderOpts._input.active = sliderOpts.active = index;
340345

341-
sliderGroup.call(setGripPosition, sliderOpts, sliderOpts.active / (sliderOpts.steps.length - 1), doTransition);
342-
343346
var step = sliderOpts.steps[sliderOpts.active];
344347

348+
sliderGroup.call(setGripPosition, sliderOpts, sliderOpts.active / (sliderOpts.steps.length - 1), doTransition);
349+
345350
if(step && step.method && doCallback) {
346-
var args = step.args;
347-
Plotly[step.method](gd, args[0], args[1], args[2]).catch(function() {
348-
// This is not a disaster. Some methods like `animate` reject if interrupted
349-
// and *should* nicely log a warning.
350-
Lib.warn('Warning: Plotly.' + step.method + ' was called and rejected.');
351-
});
351+
if(sliderGroup._nextMethod) {
352+
// If we've already queued up an update, just overwrite it with the most recent:
353+
sliderGroup._nextMethod.step = step;
354+
sliderGroup._nextMethod.doCallback = doCallback;
355+
sliderGroup._nextMethod.doTransition = doTransition;
356+
} else {
357+
sliderGroup._nextMethod = {step: step, doCallback: doCallback, doTransition: doTransition};
358+
sliderGroup._nextMethodRaf = window.requestAnimationFrame(function() {
359+
var _step = sliderGroup._nextMethod.step;
360+
var args = _step.args;
361+
if(!_step.method) return;
362+
363+
sliderOpts._invokingCommand = true;
364+
Plotly[_step.method](gd, args[0], args[1], args[2]).then(function() {
365+
sliderOpts._invokingCommand = false;
366+
}, function() {
367+
sliderOpts._invokingCommand = false;
368+
369+
// This is not a disaster. Some methods like `animate` reject if interrupted
370+
// and *should* nicely log a warning.
371+
Lib.warn('Warning: Plotly.' + _step.method + ' was called and rejected.');
372+
});
373+
374+
sliderGroup._nextMethod = null;
375+
sliderGroup._nextMethodRaf = null;
376+
});
377+
}
352378
}
353379
}
354380

@@ -428,7 +454,7 @@ function setGripPosition(sliderGroup, sliderOpts, position, doTransition) {
428454
var x = normalizedValueToPosition(sliderOpts, position);
429455

430456
var el = grip;
431-
if(doTransition && sliderOpts.transition.duration > 0) {
457+
if(doTransition && sliderOpts.transition.duration > 0 && !sliderOpts._invokingCommand) {
432458
el = el.transition()
433459
.duration(sliderOpts.transition.duration)
434460
.ease(sliderOpts.transition.easing);

test/image/baselines/sliders.png

21.7 KB
Loading

test/image/mocks/slider.json renamed to test/image/mocks/sliders.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@
4545
"easing": "cubic-in-out"
4646
},
4747

48-
"xpad": 20,
49-
"ypad": 30,
48+
"pad": {
49+
"r": 20,
50+
"t": 20
51+
},
5052

5153
"font": {}
5254
}, {
@@ -88,8 +90,10 @@
8890
"easing": "cubic-in-out"
8991
},
9092

91-
"xpad": 20,
92-
"ypad": 30,
93+
"pad": {
94+
"l": 20,
95+
"t": 20
96+
},
9397

9498
"font": {}
9599
}],

0 commit comments

Comments
 (0)