Skip to content

Animate API #802

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Sep 6, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
57892ed
Animate API
rreusser Aug 1, 2016
ae7c54c
Partial draw: Correct traces selected based on fill
rreusser Aug 4, 2016
4e23c21
Handle the case where no module found
rreusser Aug 4, 2016
b98be71
supplyDataDefaults instead of supplyDefaults for transitions
rreusser Aug 4, 2016
00bfd52
Dragbox compares axes by value instead of reference
rreusser Aug 4, 2016
f46e5fb
Attempt simultaneous axis and data transitions
rreusser Aug 9, 2016
981c1a8
Fall back to disallowing simultaneous data + axis transitions
rreusser Aug 11, 2016
80078e4
lib function to interleave trace updates into a restyle
rreusser Aug 12, 2016
a36fb6e
Add supplyTransitionDefaults to coerce input
rreusser Aug 12, 2016
b249f7b
Remove unexposed cascade option
rreusser Aug 19, 2016
d06699d
Group transitions to avoid race conditions
rreusser Aug 23, 2016
4ea79b2
Overhaul transition completion behavior
rreusser Aug 23, 2016
639faa2
Trigger transition completion even if nothing else happened
rreusser Aug 23, 2016
36207ee
Fixes from first review pass
rreusser Aug 24, 2016
4834703
Fix broken tests
rreusser Aug 24, 2016
6f0b42b
Mirror changes from #878 and small typo fix
rreusser Aug 25, 2016
a311922
Fix errorbar typo
rreusser Aug 25, 2016
d5c82c6
Add a tests for scatter simplify: false
rreusser Aug 25, 2016
0f848ab
Fix the scatter select id field
rreusser Aug 25, 2016
a6be166
Disable mouse interaction during finite-duration transition
rreusser Aug 25, 2016
dd0b1f8
Expand the animate API
rreusser Aug 25, 2016
bd6e8c0
Rework transition and animate to resolve at the *end*
rreusser Aug 28, 2016
1b497e3
Regroup animate tests to prevent race conditions
rreusser Aug 28, 2016
9079632
Add a couple more purge tests
rreusser Aug 28, 2016
14516cf
Tweak point enter/exit transitions
rreusser Aug 28, 2016
9c83914
Write Plotly.transition out of the picture yayyy
rreusser Aug 28, 2016
ee95be1
Fix frame attributes
rreusser Aug 29, 2016
dfd2037
Update attributes to improve interop with animations
rreusser Aug 29, 2016
82fefa9
Move point symbol style to single point style func
rreusser Aug 30, 2016
db6b942
Test moving transition and doCalcdata to plots.js
rreusser Sep 2, 2016
0d3da5e
Change namespace of transition
rreusser Sep 2, 2016
0221c79
Refactor animationOpts API
rreusser Sep 2, 2016
f3a292d
Apply non-range props from layout to transition
rreusser Sep 2, 2016
f709572
Use Lib.isPlainObject instead of typeof
rreusser Sep 2, 2016
68b9a0c
Stop testing the things that don't pass the tests 😑
rreusser Sep 6, 2016
29c14d7
Switch to window.[request|cancel]AnimationFrame for consistency
rreusser Sep 6, 2016
84c93fe
Remove .transition from core
rreusser Sep 6, 2016
75ec8a5
Add immediate interrupt
rreusser Sep 6, 2016
c8e46f2
Fix one of the animate tests
rreusser Sep 6, 2016
1d43355
Tweak tests
rreusser Sep 6, 2016
1fe652d
Fix race condition in .animate
rreusser Sep 6, 2016
2bc29b8
Limit transition duration to <= frame duration
rreusser Sep 6, 2016
0f23eef
jsDoc for animate, addFrames, and deleteFrames
rreusser Sep 6, 2016
c85c3a2
Verify gd is a plot div for animate, addFrames, deleteFrames
rreusser Sep 6, 2016
4e88184
Throw animate API errors whne gd is not a plot
rreusser Sep 6, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Disable mouse interaction during finite-duration transition
  • Loading branch information
rreusser committed Sep 6, 2016
commit a6be16621982f1b752a0b4d4e6185ef988e8acbf
42 changes: 31 additions & 11 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Plotly.plot = function(gd, data, layout, config) {

// if the user is trying to drag the axes, allow new data and layout
// to come in but don't allow a replot.
if(gd._dragging) {
if(gd._dragging && !gd._transitioning) {
// signal to drag handler that after everything else is done
// we need to replot, because something has changed
gd._replotPending = true;
Expand Down Expand Up @@ -235,6 +235,7 @@ Plotly.plot = function(gd, data, layout, config) {
}

function doAutoRange() {
if(gd._transitioning) return;
var axList = Plotly.Axes.list(gd, '', true);
for(var i = 0; i < axList.length; i++) {
Plotly.Axes.doAutoRange(axList[i]);
Expand Down Expand Up @@ -2597,6 +2598,8 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
doCalcdata(gd);

ErrorBars.calc(gd);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. This thing shouldn't exist. Oh well, that will be for another clean up PR. Nice find.


return Promise.resolve();
}

function executeCallbacks(list) {
Expand All @@ -2618,6 +2621,16 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
var aborted = false;

function executeTransitions() {
// This flag is used to disabled things like autorange:
gd._transitioning = true;

// When instantaneous updates are coming through quickly, it's too much to simply disable
// all interaction, so store this flag so we can disambiguate whether mouse interactions
// should be fully disabled or not:
if(transitionConfig.duration > 0) {
gd._transitioningWithDuration = true;
}

gd._transitionData._interruptCallbacks.push(function() {
aborted = true;
});
Expand All @@ -2638,7 +2651,6 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
}

var traceTransitionConfig;
var hasTraceTransition = false;
var j;
var basePlotModules = fullLayout._basePlotModules;
var hasAxisTransition = false;
Expand Down Expand Up @@ -2671,12 +2683,7 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
}

// If nothing else creates a callback, then this will trigger the completion in the next tick:
setTimeout(makeCallback());

if(!hasAxisTransition && !hasTraceTransition) {
return false;
}

setTimeout(makeCallback('first'));
}

function completeTransition() {
Expand All @@ -2687,13 +2694,25 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
return Plotly.redraw(gd);
}
}).then(function() {
// Set transitioning false again once the redraw has occurred. This is used, for example,
// to prevent the trailing redraw from autoranging:
gd._transitioning = false;
gd._transitioningWithDuration = false;

gd.emit('plotly_transitioned', []);
});
}

function interruptPreviousTransitions() {
gd.emit('plotly_transitioninterrupted', []);

// If a transition is interrupted, set this to false. At the moment, the only thing that would
// interrupt a transition is another transition, so that it will momentarily be set to true
// again, but this determines whether autorange or dragbox work, so it's for the sake of
// cleanliness:
gd._transitioning = false;
gd._transtionWithDuration = false;

return executeCallbacks(gd._transitionData._interruptCallbacks);
}

Expand All @@ -2715,11 +2734,12 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {

var seq = [Plots.previousPromises, interruptPreviousTransitions, prepareTransitions, executeTransitions];

var plotDone = Lib.syncOrAsync(seq, gd);

if(!plotDone || !plotDone.then) plotDone = Promise.resolve();
var transitionStarting = Lib.syncOrAsync(seq, gd);

return plotDone.then(function() {
if(!transitionStarting || !transitionStarting.then) transitionStarting = Promise.resolve();

return transitionStarting.then(function() {
gd.emit('plotly_transitioning', []);
return gd;
});
Expand Down
20 changes: 19 additions & 1 deletion src/plots/cartesian/dragbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
}

function zoomMove(dx0, dy0) {
if(gd._transitioningWithDuration) {
return false;
}

var x1 = Math.max(0, Math.min(pw, dx0 + x0)),
y1 = Math.max(0, Math.min(ph, dy0 + y0)),
dx = Math.abs(x1 - x0),
Expand Down Expand Up @@ -380,15 +384,22 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
fullLayout._plots[plotinfo.mainplot] : plotinfo;

function zoomWheel(e) {
recomputeAxisLists();
// deactivate mousewheel scrolling on embedded graphs
// devs can override this with layout._enablescrollzoom,
// but _ ensures this setting won't leave their page
if(!gd._context.scrollZoom && !fullLayout._enablescrollzoom) {
return;
}

// If a transition is in progress, then disable any behavior:
if(gd._transitioningWithDuration) {
return Lib.pauseEvent(e);
}

var pc = gd.querySelector('.plotly');

recomputeAxisLists();

// if the plot has scrollbars (more than a tiny excess)
// disable scrollzoom too.
if(pc.scrollHeight - pc.clientHeight > 10 ||
Expand Down Expand Up @@ -456,6 +467,11 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {

// plotDrag: move the plot in response to a drag
function plotDrag(dx, dy) {
// If a transition is in progress, then disable any behavior:
if(gd._transitioningWithDuration) {
return;
}

recomputeAxisLists();

function dragAxList(axList, pix) {
Expand Down Expand Up @@ -558,6 +574,8 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
}

function doubleClick() {
if(gd._transitioningWithDuration) return;

var doubleClickConfig = gd._context.doubleClick,
axList = (xActive ? xa : []).concat(yActive ? ya : []),
attrs = {};
Expand Down
20 changes: 11 additions & 9 deletions src/traces/scatter/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var linkTraces = require('./link_traces');
var polygonTester = require('../../lib/polygon').tester;

module.exports = function plot(gd, plotinfo, cdscatter, transitionConfig, makeOnCompleteCallback) {
var i, uids, selection, join;
var i, uids, selection, join, onComplete;

var scatterlayer = plotinfo.plot.select('g.scatterlayer');

Expand All @@ -31,14 +31,6 @@ module.exports = function plot(gd, plotinfo, cdscatter, transitionConfig, makeOn
var isFullReplot = !transitionConfig;
var hasTransition = !!transitionConfig && transitionConfig.duration > 0;

var onComplete;
if(makeOnCompleteCallback && hasTransition) {
// If it was passed a callback to register completion, make a callback. If
// this is created, then it must be executed on completion, otherwise the
// pos-transition redraw will not execute:
onComplete = makeOnCompleteCallback();
}

selection = scatterlayer.selectAll('g.trace');

join = selection.data(cdscatter, function(d) {return d[0].trace.uid;});
Expand Down Expand Up @@ -71,11 +63,21 @@ module.exports = function plot(gd, plotinfo, cdscatter, transitionConfig, makeOn
});

if(hasTransition) {
if(makeOnCompleteCallback) {
// If it was passed a callback to register completion, make a callback. If
// this is created, then it must be executed on completion, otherwise the
// pos-transition redraw will not execute:
onComplete = makeOnCompleteCallback();
}

var transition = d3.transition()
.duration(transitionConfig.duration)
.ease(transitionConfig.ease)
.each('end', function() {
onComplete && onComplete();
})
.each('interrupt', function() {
onComplete && onComplete();
});

transition.each(function() {
Expand Down