Skip to content
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

Unified hover with hi-freq scatter on low-freq bars #5292

Closed
nicolaskruchten opened this issue Nov 19, 2020 · 11 comments
Closed

Unified hover with hi-freq scatter on low-freq bars #5292

nicolaskruchten opened this issue Nov 19, 2020 · 11 comments
Assignees
Labels
bug something broken

Comments

@nicolaskruchten
Copy link
Contributor

nicolaskruchten commented Nov 19, 2020

In this pen, the behaviour of unified hoverlabels and spikelines is unsatisfying: https://codepen.io/nicolaskruchten/pen/abZrYJO?editors=0010

  1. the behaviour is fairly different while moving the cursor in the middle of the y-range within the x-range of the short vs tall bar... this can be tracked in Spike position in unified hover mode #4716
  2. although the bar spans the period, it's basically impossible to see the value of the bar in the same hoverlabel as any of the scatter-points, which is desired.
@nicolaskruchten nicolaskruchten added bug something broken sponsored labels Nov 19, 2020
@nicolaskruchten
Copy link
Contributor Author

Some thoughts on some orthogonal modifications we should make to proceed (assuming orientation is v, and applying to hovermodes x and x unified, as well as the reverse):

  1. If the cursor's x-position is within the x-range of the bar, the bar's point should be included in the set of points that get a hoverlabel.
  2. For tall bars like the one on the right here, when hovering over a scatter point, the spikeline should be on the scatter point, not the centerline of the bar

Both of these seem like bug fixes to me. Then there is the annoyance of having the spikeline flip back and forth between the scatter point and the bar as I move my cursor across the plot between two points. This is basically a hoverdistance problem but perhaps there is some improvement we could make here?

@alexcjohnson
Copy link
Collaborator

Offhand it seems to me we need:

(1) A way for the scatter trace to always win the hover label when there is a scatter trace. This is tricky because we probably want the bar to still produce a hover label when there’s no scatter trace at all - ie in years other than 2017 in their example. But we probably also want to NOT revert to hovering on the bar when you’ve zoomed in and your pointer is halfway between two scatter points. So I’m thinking what we need is some sort of a per-trace per-axis data-referenced hoverdistance - ie rather than a pixel distance (which isn't even really pixels but it sort of approximates pixels) we set a data distance - in this case two months, in milliseconds - that the cursor can be offset from the point and still trigger the label. This could also be useful even without multiple traces, to prevent gaps in hovering as the mouse moves across the data. And as an extension, we could imagine an "auto" mode where this value gets set to half the minimum delta between points (Lib.distinctVals().minDiff)

(2) Let the bar participate in unified hover whenever the hover label is anchored to any point within the bar’s period. I suspect we can treat the current behavior as a bug rather than a feature you need to enable. We’d have to look into whether there are any cases this becomes problematic but I don’t see any offhand.

(3) Why does the spike line stay anchored to the bar and not the point when the points are actually on top of the bar, even when only the point is listed in the label? That seems also like simply a bug. If you have a hover label and a spikeline, the spikeline should be anchored to one of the points that generated the label. This may get a little bit complicated when we fix (2), as we'll need to distinguish between "points that generated the label" and "other points that are close enough to include." For example if there are multiple scatter traces with points of matching x values, all of them should be considered equivalent for this purpose, and you anchor the spikeline to the closest one in y - doesn't matter when there's only a full-height vertical spikeline but if it ends at the point or if there's also a horizontal spikeline it matters which point you're anchored to. But the bar, which has a different x value but is (will be 😏 ) still included in the hover label because its period spans the x value you're hovering on, should not be eligible to become the spikeline anchor.

@nicolaskruchten
Copy link
Contributor Author

@alexcjohnson re your point 1, some questions:

  1. How would we handle situations where we have two adjacent bars A and B, with scatter points Q (close to left edge of A) and R (close to left edge of B) and the cursor is close to the right edge of A... In that case we'd get a hoverlabel with A and R, which seems wrong. It almost seems like we need to do some cross-trace work here?
  2. If in effect we can set the hoverdistance to be half the minimum inter-point distance, we're essentially saying "this trace always has an active hoverlabel" right?

@alexcjohnson
Copy link
Collaborator

How would we handle situations where we have two adjacent bars A and B, with scatter points Q (close to left edge of A) and R (close to left edge of B) and the cursor is close to the right edge of A... In that case we'd get a hoverlabel with A and R, which seems wrong. It almost seems like we need to do some cross-trace work here?

This will be a good test case. But hover already uses a multi-step process, that I think will do the right thing here: first we figure out which point is the "best", then we look at the other traces and see which ones have a compatible point with the "best" one. One weird thing with this case is if you set a large enough hover distance, scatter point R will win even if the cursor is over the right edge of bar A, which will then lead to bar B getting included in the hover label. But in that case I think that's basically what you asked for with the large hover distance, so it's OK, just kind of weird.

If in effect we can set the hoverdistance to be half the minimum inter-point distance, we're essentially saying "this trace always has an active hoverlabel" right?

To be clear I don't think "auto" should be the default for this setting. But yes, assuming the trace has a consistent point spacing, no null points, spans the full range that other traces on the plot do, and you're in compare / unified hover mode (not closest), then it will always have an active hover label.

@nicolaskruchten
Copy link
Contributor Author

One weird thing with this case is if you set a large enough hover distance, scatter point R will win even if the cursor is over the right edge of bar A, which will then lead to bar B getting included in the hover label. But in that case I think that's basically what you asked for with the large hover distance, so it's OK, just kind of weird.

So in this case, the spikeline will be on R, and the hoverlabel points will be R and B, even though the cursor is over A?

@archmoj archmoj self-assigned this Jan 26, 2021
@nicolaskruchten
Copy link
Contributor Author

So per @alexcjohnson there's this notion of one point "winning" the hover, in that the label will be positioned with respect to that point, and the spikeline, if present, will also be on that point (NB: one of the bugs highlighted here is that this spikeline invariant is not holding). As a second consideration, there is some set of rules about which other points get included in the hover label(s) in compare or unified modes: these points could be called "contributors". In the case of the issue above, the idea is that any bar-like mark that has a 'width' should be a contributor so long as the cursor and/or the winner is within that range?

These both interact with hoverdistance and spikedistance in... some way. I would guess that the intention is that hoverdistance is related to computing the winner, and possibly the contributors? spikedistance should basically activate spikelines before hovers if it's greater than hoverdistance but if it's less than hoverdistance it has no effect unless hovers are disabled (i.e. there can be no winner). In no case should we get a spikeline and a hover at the same time that are not on the same point.

@alexcjohnson please confirm that this roughly captures your intention/understanding?

@nicolaskruchten
Copy link
Contributor Author

This feels related BTW: #4787

@nicolaskruchten
Copy link
Contributor Author

This is basically the issue in point 1: #4716

@nicolaskruchten
Copy link
Contributor Author

I just remembered there's also the layout(x|y)axis.spikesnap attribute to think about here also. See #4657

@nicolaskruchten
Copy link
Contributor Author

There's also a bunch of discussion in #4656

@nicolaskruchten
Copy link
Contributor Author

nicolaskruchten commented Apr 20, 2021

Closing in favour of #5553 and #5554 and #5619

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken
Projects
None yet
Development

No branches or pull requests

3 participants