Repository navigation
fall back to the remaining active pointer’s value - #2467
Open
SahinurDEV wants to merge 1 commit into
Open
SahinurDEV wants to merge 1 commit into
SahinurDEV wants to merge 1 commit into
Conversation
When several pointer marks are active (e.g., a pointerY on a rect and a tip on a dot, or pooled tips), each render dispatched its own value, so clearing one pointer set the plot’s value to null even though another pointer was still focused. Track the focused datum per rendered mark and dispatch the value of the most recently focused pointer that is still active. Fixes observablehq#2431
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the mouse is within range of several pointers, clearing one of them resets the plot’s
valuetonull, even though another pointer is still focused (#2431):Plot.rect(…, Plot.pointerY({maxRadius: Infinity}))plusPlot.dot(…, {tip: true}): move near the dot (value is the dot’s datum), then away from it inside the frame → value becomesnullinstead of the rect’s datum, although the rect pointer is still active.tip: {maxRadius: 100}), moving from the second dot back to the first sets the value tonull: the pool renders the winner first and then the loser withnull, and the loser’s render dispatchesnulllast.Cause
Each pointer’s
renderdispatches its own value directly (context.dispatchValue(i == null ? null : datum)), so whichever pointer renders last wins, including a pointer that just cleared. The other pointers don’t re-render (their focused index didn’t change), so nothing restores their value.Fix
Keep a per-plot
focusmap (render index → focused datum) in the shared pointer state. On each render, the mark updates its own entry (removed when cleared, re-inserted when focused so the most recently focused pointer is last), and the dispatched value is that of the most recently focused pointer still active, ornullwhen none is. The existing facet guard (prefer the entering facet when exiting another) is unchanged; clearing all pointers onpointerleaveor when releasing a sticky pointer still yieldsnull.Tests
Added a
pointer valuesuite intest/pointer-test.js:pointerY+ dot tip scenario from the issue: value goes"foo"→ dot datum → back to"foo"→nullonpointerleave;Both fail on
main(value isnull) and pass with this change. Fullvitest --typecheck runpasses (404 files, 1351 tests), andtsc,eslint src testandprettier --check src testare clean.Fixes #2431