-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
fix for spikedistance set to infinity #4627
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
Conversation
src/components/fx/hover.js
Outdated
@@ -549,7 +549,7 @@ function _hover(gd, evt, subplot, noHoverEvent) { | |||
var thisSpikeDistance; | |||
for(var i = 0; i < pointsData.length; i++) { | |||
thisSpikeDistance = pointsData[i].spikeDistance; | |||
if(thisSpikeDistance < minDistance && thisSpikeDistance <= spikedistance) { | |||
if(thisSpikeDistance <= minDistance && thisSpikeDistance <= spikedistance) { |
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.
The problem stems from thisSpikeDistance
being Infinity
and minDistance
also being Infinity
. Without an equal sign, this will never be true and no spikelines will appear hence the bug.
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.
Are there any cases this changes which point we get spikes to? It might still be OK in that case, I just want to know what those cases are. The loop indicates this way if we have multiple items in pointData
all with the same spikeDistance
, previously we'd get the first one, but with the new logic we'll get the last one.
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.
Are there any cases this changes which point we get spikes to?
@alexcjohnson I'm not sure how to proceed to find out.
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.
Should we check whether minDistance
is Infinity
and handle that case separately?
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.
That's a much better solution, IMO.
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.
if((minDistance === Infinity || thisSpikeDistance < minDistance) &&
thisSpikeDistance <= spikedistance
) {
looks like the right logic to apply.
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.
Ok so I went with this safer approach. If spikedistance
is Infinity
we visit that if
block. It should preserve any existing behavior but fix the edge case for Infinity
.
See 583ad64
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.
The key is to first identify the relevant test cases. I suspect the relevant ones are (with hovermode: 'x'
):
- Two scatter traces with exactly identical points, so there aren't closer and farther ones. Maybe we don't care which one gets the spike line... though offhand I'd suggest the last one, since it'll be drawn on top so you'll see a spike line color matching the visible point.
- Stacked bar traces with the cursor at a larger (or smaller) y value than any of the bars. Ideally I'd think it would be nice to draw the spike line to the one that's closest; but that would require getting away from using
Infinity
for all points outside the bar, at least forsizeFn
. Perhaps we giveFx.inbox
another (optional) argumentfailVal
that, in this case, will be set very large, and increasing the farther away you get from the bar either above or below, but not infinite. Or, at that point it seems silly to useFx.inbox
at all, just inline this logic.
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.
Thanks for the clarification @alexcjohnson . I now better understand the purpose of this code. I will take another approach.
@antoinerg Thanks very much for the PR. |
Nicely done. |
Please hold on. There is a new comment: #4627 (comment). |
7e787ad
to
9a0143f
Compare
9a0143f
to
ebf75e6
Compare
I think my first solution has to go back in otherwise we have too many non-scatter traces for which no spike lines appear for @alexcjohnson can you have a look at branch
If it's satisfactory, I can open a new PR or simply force push here. Let me know what you prefer. |
@archmoj you might also want to review my new branch described in #4627 (comment) |
Looks great, my only question about it is the test "correctly select the closest bar even when setting spikedistance to -1" - you do |
Force-pushing on PRs is discouraged on the plotly.js repo. |
I'm not completely sure: maybe it's above or below. I tested it manually on mock
Yes they should have the same
Right now, for
I think this case is covered: https://codepen.io/antoinerg/pen/vYORyLV |
I missed that behavior! Let me see if I can get it right :) Thanks for the review @alexcjohnson 🕵️♂️ EDIT: I am not sure I can at the moment. I don't understand the current calculation of |
I'll open a new PR. Closing in favor of #4637 |
Fixes #4626 and #3805
Commit 9d1325c adds a test which fail.
For #4626:
Before: https://codepen.io/antoinerg/pen/BaNYJve
After: https://codepen.io/antoinerg/pen/oNXEENy
For #3805:
Before: https://codepen.io/anon/pen/eoPXJE
After: https://codepen.io/antoinerg/pen/ExjQQYw
cc @archmoj @alexcjohnson @etpinard