Skip to content

fix: Account for marker size when picking the hovered WebGL point - #8170

Open
adimalkar wants to merge 4 commits into
plotly:mainfrom
adimalkar:fix/8082-gl-hover-marker-size
Open

adimalkar wants to merge 4 commits into
plotly:mainfrom
adimalkar:fix/8082-gl-hover-marker-size

Conversation

@adimalkar

Copy link
Copy Markdown

This PR makes scattergl, scatterpolargl and splom use marker size when they pick the hovered point, as scatter does.

Closes #8082.

Why this is correct

  • scatter scores a point by its distance to the marker edge. Inside a marker, a smaller marker wins.
  • scattergl and splom measured only the distance to the marker center. So the marker drawn on top always won.
  • This PR moves the existing scatter math into getAxisDistance and getPointDistance in scatter/hover.js, with no change in behavior. scattergl and splom now call them.
  • Each radius is half of the sizes/size that convert already computes for the WebGL markers.
  • For large traces, the spatial index search box grows by the largest marker radius.
  • scatterpolargl gets the fix through scattergl.

Behavior change

The WebGL traces now give the same result as their SVG counterparts. I checked this with real pointer events in Chrome:

Case SVG WebGL before WebGL after
Issue snippet (A size 6, B size 20, same point) A B A
One trace, sizes [6, 20] at the same point small big small
Big marker drawn first, pointer 8px from center B A B
splom, sizes [6, 20] — big small
scatterpolargl vs scatterpolar, sizes [6, 20] small big small
1e5 points, pointer 30px inside an 80px marker big no hover big

Changes that affect every WebGL plot with markers:

  • A point is in range when the pointer is within hoverdistance of the marker edge.
  • spikedistance and the label order in x hovermode use the scatter scoring.
  • When the pointer is inside several markers of the same size, the point drawn last wins. Before, WebGL picked the nearest center.

The last item changes five expectations in scatterpolargl_test.js. The default pointer is 3.7px from point 2 and 5.8px from point 26 of 'Trial 3'. Both markers have a 6px radius. scatterpolar picks point 26 for the same figure.

The hover label still anchors at the marker center in WebGL. I left that out of this PR.

Tests

  • New tests in hover_test.js (hover on points at the same position):
    • the smaller marker wins for scatter, scattergl and splom;
    • a marker hovers when its edge, but not its center, is within hoverdistance;
    • a 1e5-point scattergl trace finds a marker whose center is outside the search box.
  • Suites run locally (Chrome 157):
    • hover 237/237, scattergl 48/48, splom 51/51, gl2d_click 12/12;
    • hover_spikeline 45/45, scatterpolargl 32/32, gl2d_plot_interact 16/16, scattergl_select 20/20.
  • select: 115/117. The two failures are the ohlc and candlestick lasso tests, which fail the same way on main (90f954a) on this machine.
  • npm run lint and npm run test-syntax pass.
  • No image baselines change. Hover does not draw in the image tests. I did not run regl-codegen, because no shader code changed.

This change was developed with AI assistance (Claude Code). A human reviewed the code and ran the jasmine suites.

scatter scores a point by its distance to the marker edge, and inside a marker
it prefers the smaller one. scattergl and splom used the distance to the
marker center only, so the marker drawn on top always won when markers of
different sizes overlapped, and a large marker did not hover until the
pointer came near its center. scatterpolargl inherits the scattergl result.

Share the scatter scoring with scattergl and splom and take each radius from
the WebGL marker sizes. Widen the spatial index search box by the largest
radius, so large traces find markers whose edge is in range.

Fixes plotly#8082
…laps

With three size-80 markers on a 400px plot, the pointer 30px from the middle
marker was also inside the next one, which correctly won the tie.
The default pointer position is inside two same-size markers of one trace.
scatterpolar gives the tie to the point drawn last (point 26), and now
scatterpolargl does too, instead of picking the nearer center (point 2).
Copilot AI balanced review requested due to automatic review settings November 11, 2026 09:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: scattergl and splom hover ignores marker size for overlapping points

2 participants