Skip to content

Fix unhover event data for gl3d subplots #5954

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 7 commits into from
Oct 12, 2021
Merged
3 changes: 3 additions & 0 deletions draftlogs/5954_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Fix unhover event data for gl3d subplots [[#5954](https://github.com/plotly/plotly.js/pull/5954)],
with thanks to @dwoznicki for the contribution!

7 changes: 3 additions & 4 deletions src/plots/gl3d/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,6 @@ proto.render = function() {
return Axes.hoverLabelText(ax, val, hoverformat);
}

var oldEventData;

if(lastPicked !== null) {
var pdata = project(scene.glplot.cameraParams, selection.dataCoordinate);
trace = lastPicked.data;
Expand Down Expand Up @@ -456,10 +454,11 @@ proto.render = function() {
gd.emit('plotly_hover', eventData);
}

oldEventData = eventData;
this.oldEventData = eventData;
Copy link
Contributor

Choose a reason for hiding this comment

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

What if we change this line to

if(eventData) this.oldEventData = eventData;

?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this does the trick, unfortunately. Here's the logging output with this change.

LOG: 'UNHOVER', undefined
LOG: 'UNHOVER', undefined
LOG: 'UNHOVER', Object{points: [Object{x: ..., y: ..., z: ..., data: ..., fullData: ..., curveNumber: ..., pointNumber: ..., marker.symbol: ..., marker.size: ..., marker.line.color: ..., marker.color: ..., bbox: ...}]}
LOG: 'UNHOVER', undefined
LOG: 'UNHOVER', undefined

this.oldEventData still gets set back to undefined after the plotly_unhover event has been emitted.

gd.emit('plotly_unhover', this.oldEventData);    
this.oldEventData = undefined;

I could remove this.oldEventData = undefined; and then we could be pretty confident that the unhover event will have event data, as long as the user has hovered at least one point since graph creation (we'll still get undefined event data for renders before a point has been hovered). Here's the logging output.

LOG: 'UNHOVER', undefined
LOG: 'UNHOVER', undefined
LOG: 'UNHOVER', Object{points: [Object{x: ..., y: ..., z: ..., data: ..., fullData: ..., curveNumber: ..., pointNumber: ..., marker.symbol: ..., marker.size: ..., marker.line.color: ..., marker.color: ..., bbox: ...}]}
LOG: 'UNHOVER', Object{points: [Object{x: ..., y: ..., z: ..., data: ..., fullData: ..., curveNumber: ..., pointNumber: ..., marker.symbol: ..., marker.size: ..., marker.line.color: ..., marker.color: ..., bbox: ...}]}
LOG: 'UNHOVER', Object{points: [Object{x: ..., y: ..., z: ..., data: ..., fullData: ..., curveNumber: ..., pointNumber: ..., marker.symbol: ..., marker.size: ..., marker.line.color: ..., marker.color: ..., bbox: ...}]}

So this would solve the issue for the test case, but I think this behavior is misleading.

} else {
Fx.loneUnhover(svgContainer);
gd.emit('plotly_unhover', oldEventData);
if(this.oldEventData) gd.emit('plotly_unhover', this.oldEventData);
this.oldEventData = undefined;
}

scene.drawAnnotations(scene);
Expand Down
75 changes: 75 additions & 0 deletions test/jasmine/tests/gl3d_hover_click_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,81 @@ describe('Test gl3d trace click/hover:', function() {
});
});
});

it('@gl should emit correct event data on unhover', function(done) {
var _mock = Lib.extendDeep({}, mock2);
var x = 655;
var y = 221;

function _hover() {
mouseEvent('mouseover', x, y);
}

function _unhover() {
return new Promise(function(resolve) {
var x0 = x;
var y0 = y;
var initialElement = document.elementFromPoint(x0, y0);
var canceler = setInterval(function() {
x0 -= 2;
y0 -= 2;
mouseEvent('mouseover', x0, y0);

var nowElement = document.elementFromPoint(x0, y0);
if(nowElement !== initialElement) {
mouseEvent('mouseout', x0, y0, {element: initialElement});
}
}, 10);

gd.on('plotly_unhover', function(eventData) {
clearInterval(canceler);
resolve(eventData);
});

setTimeout(function() {
clearInterval(canceler);
resolve(null);
}, 350);
});
}

Plotly.newPlot(gd, _mock)
.then(delay(20))
.then(function() {
gd.on('plotly_hover', function(eventData) {
ptData = eventData.points[0];
});
gd.on('plotly_unhover', function(eventData) {
if(eventData) {
ptData = eventData.points[0];
} else {
ptData = {};
}
});
})
.then(delay(20))
.then(_hover)
.then(delay(20))
.then(function() {
assertEventData(100.75, -102.63, -102.63, 0, 0, {
'marker.symbol': 'circle',
'marker.size': 10,
'marker.color': 'blue',
'marker.line.color': 'black'
});
})
.then(_unhover)
.then(delay(20))
.then(function() {
assertEventData(100.75, -102.63, -102.63, 0, 0, {
'marker.symbol': 'circle',
'marker.size': 10,
'marker.color': 'blue',
'marker.line.color': 'black'
});
})
.then(done, done.fail);
});
});

describe('hover on traces with (x|y|z|u|v|w)hoverformat and valuehoverformat', function() {
Expand Down