-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Fix unhover event data for gl3d subplots #5954
Conversation
Thanks very much for the PR. You could run the test using the following command: npm run test-jasmine gl3d_hover_click |
I'll just quickly note that a bunch of tests were failing for me when running |
Yes please feel free to open a PR to improve the CONTRIBUTING.md. |
@archmoj It looks like the test I wrote is failing probably due to a race condition. Basically, the I can modify the test to avoid the race, but this behavior does strike me as a bit unexpected. My expectation is that the Fx.loneUnhover(svgContainer);
gd.emit('plotly_unhover', this.oldEventData);
this.oldEventData = undefined; to if (this.oldEventData) {
Fx.loneUnhover(svgContainer);
gd.emit('plotly_unhover', this.oldEventData);
this.oldEventData = undefined;
} But I'm not sure what the implications of such a change would be, especially if other code relies on |
@@ -550,6 +550,77 @@ describe('Test gl3d trace click/hover:', function() { | |||
.then(done, done.fail); | |||
}); | |||
|
|||
it('@gl should emit correct event data on unhover', function(done) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move this test to the end of Test gl3d trace click/hover:
block and it will solve the race condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, well, I tried moving the test to the bottom of the Test gl3d trace click/hover:
block, and the race still appears to be present.
To be clear, I don't think there is a race between this test and other tests; as far as I can tell, they're run sequentially in the browser. I do think there's a race to check ptData
before it is reassigned by a pseudo unhover event triggered by the graph re-rendering. For example, if I change
gd.on('plotly_unhover', function(eventData) {
ptData = eventData.points[0];
});
to
gd.on('plotly_unhover', function(eventData) {
console.log("UNHOVER", eventData);
if (eventData) {
ptData = eventData.points[0];
} else {
ptData = {};
}
});
and run the full gl3d_hover_click test suite, I get 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', undefined
LOG: 'UNHOVER', undefined
I assume the undefined
event data is due to Scene.prototype.render
being called a bunch of times for reasons unrelated to mouse movement.
Interestingly, I don't get any unhover events with undefined
event data when I run this test as a standalone using fit
.
Please create - Fix unhover event data for gl3d subplots [[#5954](https://github.com/plotly/plotly.js/pull/5954)],
with thanks to @dwoznicki for the contribution! Thank you! |
…over being called without even data remains
@@ -456,10 +454,11 @@ proto.render = function() { | |||
gd.emit('plotly_hover', eventData); | |||
} | |||
|
|||
oldEventData = eventData; | |||
this.oldEventData = eventData; |
There was a problem hiding this comment.
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;
?
There was a problem hiding this comment.
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.
src/plots/gl3d/scene.js
Outdated
} else { | ||
Fx.loneUnhover(svgContainer); | ||
gd.emit('plotly_unhover', oldEventData); | ||
gd.emit('plotly_unhover', this.oldEventData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gd.emit('plotly_unhover', this.oldEventData); | |
if(this.oldEventData) gd.emit('plotly_unhover', this.oldEventData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we shouldn't fire Fx.loneUnhover
either if this.oldEventData
is nullish?
if (this.oldEventData) {
Fx.loneUnhover(svgContainer);
gd.emit('plotly_unhover', this.oldEventData);
this.oldEventData = undefined;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. But that could possibly be done in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dwoznicki did you try my suggestion above? #5954 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, and it solves the issue as far as I can tell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then please commit the suggestion :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I did here 46c5b8f, but I did it in my local copy instead of through the GitHub UI. Is that okay?
Great. Would you mind fixing the syntax failure and we should be good to go. npm run test-syntax |
Hmm, I'm not sure what the syntax failure is. When I run
Any ideas? |
Please try |
These two lines are causing the error: /home/circleci/plotly.js/test/jasmine/tests/gl3d_hover_click_test.js 1316:19 error Unexpected space(s) after "if" keyword-spacing 1345:8 error Block must not be padded by blank lines padded-blocks |
💃 |
This is a potential fix for #5953. I've modified the
plotly_unhover
event to use the event data from the lastplotly_click
/plotly_hover
event, which I think was the original intention, but I'm not totally sure.