Skip to content

Cache the last mousemove event #1304

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 11 commits into from
Feb 15, 2017
38 changes: 28 additions & 10 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ Plotly.plot = function(gd, data, layout, config) {
Registry.getComponentMethod('updatemenus', 'draw')(gd);
}

Lib.syncOrAsync([
var seq = [
Plots.previousPromises,
addFrames,
drawFramework,
Expand All @@ -347,8 +347,14 @@ Plotly.plot = function(gd, data, layout, config) {
subroutines.layoutStyles,
drawAxes,
drawData,
finalDraw
], gd);
finalDraw,
];

if(gd._fullLayout._rehover) {
seq.push(function() { Plots.rehover(gd); });
}

Lib.syncOrAsync(seq, gd);

// even if everything we did was synchronous, return a promise
// so that the caller doesn't care which route we took
Expand Down Expand Up @@ -1201,8 +1207,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {

if(flags.fullReplot) {
seq.push(Plotly.plot);
}
else {
} else {
seq.push(Plots.previousPromises);

Plots.supplyDefaults(gd);
Expand All @@ -1211,6 +1216,10 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
if(flags.docolorbars) seq.push(subroutines.doColorBars);
}

if(gd._fullLayout._rehover) {
seq.push(function() { Plots.rehover(gd); });
}

Queue.add(gd,
restyle, [gd, specs.undoit, specs.traces],
restyle, [gd, specs.redoit, specs.traces]
Expand Down Expand Up @@ -1695,9 +1704,11 @@ Plotly.relayout = function relayout(gd, astr, val) {
}

var aobj = {};
if(typeof astr === 'string') aobj[astr] = val;
else if(Lib.isPlainObject(astr)) aobj = astr;
else {
if(typeof astr === 'string') {
aobj[astr] = val;
} else if(Lib.isPlainObject(astr)) {
aobj = astr;
} else {
Lib.warn('Relayout fail.', astr, val);
return Promise.reject();
}
Expand All @@ -1715,8 +1726,7 @@ Plotly.relayout = function relayout(gd, astr, val) {

if(flags.layoutReplot) {
seq.push(subroutines.layoutReplot);
}
else if(Object.keys(aobj).length) {
} else if(Object.keys(aobj).length) {
seq.push(Plots.previousPromises);
Plots.supplyDefaults(gd);

Expand All @@ -1727,6 +1737,10 @@ Plotly.relayout = function relayout(gd, astr, val) {
if(flags.docamera) seq.push(subroutines.doCamera);
}

if(gd._fullLayout._rehover) {
seq.push(function() { Plots.rehover(gd); });
}

Queue.add(gd,
relayout, [gd, specs.undoit],
relayout, [gd, specs.redoit]
Expand Down Expand Up @@ -2127,6 +2141,10 @@ Plotly.update = function update(gd, traceUpdate, layoutUpdate, traces) {
if(relayoutFlags.doCamera) seq.push(subroutines.doCamera);
}

if(gd._fullLayout._rehover) {
seq.push(function() { Plots.rehover(gd); });
}

Queue.add(gd,
update, [gd, restyleSpecs.undoit, relayoutSpecs.undoit, restyleSpecs.traces],
update, [gd, restyleSpecs.redoit, relayoutSpecs.redoit, restyleSpecs.traces]
Expand Down
20 changes: 20 additions & 0 deletions src/plots/cartesian/graph_interact.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,21 @@ fx.init = function(gd) {
xa._length, ya._length, 'ns', 'ew');

maindrag.onmousemove = function(evt) {
// This is on `gd._fullLayout`, *not* fullLayout because the reference
// changes by the time this is called again.
gd._fullLayout._rehover = function() {
if(gd._fullLayout._hoversubplot === plotinfo.id) {
fx.hover(gd, evt, subplot);
}
};

// Track the hovered subplot. This prevents rehover from accidetally
// reapplying a hover label after the mouse has left the plot or if
// the mouse has entered another subplot.
gd._fullLayout._hoversubplot = plotinfo.id;

gd._fullLayout._rehover();

fx.hover(gd, evt, subplot);
fullLayout._lasthover = maindrag;
fullLayout._hoversubplot = subplot;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are this fx.hover and fullLayout._hoversubplot = subplot still necessary then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops! Good catch. I change this back and forth and accidentally left both. Fixed in the commit below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops. Yeah, you're right. There's still an extra item or two there. Fixing (and looking at the full diff when doing so this time)

Expand All @@ -129,6 +144,11 @@ fx.init = function(gd) {
maindrag.onmouseout = function(evt) {
if(gd._dragging) return;

// When the mouse leaves this maindrag, unset the hovered subplot.
// This may cause problems if it leaves the subplot directly *onto*
// another subplot, but that's a tiny corner case at the moment.
gd._fullLayout._hoversubplot = null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Inset plots seem like a not-so-tiny corner case. But does this actually cause problems? Presumably mouseout happens before mouseover in that case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, which happens first was the question. If mouseover and then mouseout, it would end up unset, but the only time that could happen is if you move exactly one pixel outside of the inset region, which is where it started to seem like a small corner case. The second pixel moved will immediately fix things.


dragElement.unhover(gd, evt);
};

Expand Down
12 changes: 11 additions & 1 deletion src/plots/plots.js
Original file line number Diff line number Diff line change
Expand Up @@ -1934,7 +1934,11 @@ plots.transition = function(gd, data, layout, traces, frameOpts, transitionOpts)
}
}

var seq = [plots.previousPromises, interruptPreviousTransitions, prepareTransitions, executeTransitions];
function rehover() {
plots.rehover(gd);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This wrapper isn't necessary, as all the items get gd passed as an arg.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahh, thanks. Wondered about that but assumed the opposite.


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

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

Expand Down Expand Up @@ -2057,6 +2061,12 @@ plots.doCalcdata = function(gd, traces) {
}
};

plots.rehover = function(gd) {
if(gd._fullLayout._rehover) {
gd._fullLayout._rehover();
}
};

plots.generalUpdatePerTraceModule = function(subplot, subplotCalcData, subplotLayout) {
var traceHashOld = subplot.traceHash,
traceHash = {},
Expand Down