Conversation
Adds a pool option to the pointer transform, that defaults to true on the tip mark (including markes derived with {tip: true}). Pooled marks show only the closest point, preventing collisions. Non-pooled marks (like crosshair sub-marks) are unaffected. Pooling also handles facet deduplication.
There was a problem hiding this comment.
Nice! This worked as expected for me, for a variety of mark combinations. I only noticed once thing that might be related to pooled tips: in the density chart below (here), I am hovering over an individual point, but it looks like it's trying to also show the contour information. (Update: filed #2392 to exclude contours from default tip)
src/interactions/pointer.js
Outdated
| import {applyFrameAnchor} from "../style.js"; | ||
|
|
||
| const states = new WeakMap(); | ||
| const frames = new WeakMap(); |
There was a problem hiding this comment.
Can you add a comment on these maps saying what they store? It’s especially hard without types and the names are not obvious. Sometimes I use the convention thingByKey to name maps, if it helps.
src/interactions/pointer.js
Outdated
| frames.set( | ||
| pool, | ||
| requestAnimationFrame(() => { | ||
| frames.delete(pool); |
There was a problem hiding this comment.
Why use the pool as a key? Could you just store the current animation frame handle on the state object too, eliminating the frames map?
There was a problem hiding this comment.
oh, right! so we can simplify this further
src/interactions/pointer.js
Outdated
There was a problem hiding this comment.
Should this be called the facetPool now (and state.facetPools), since it serves the same purpose as state.pool?
src/interactions/pointer.js
Outdated
|
|
||
| // Isolate state per-pointer, per-plot; if the pointer is reused by | ||
| // multiple marks, they will share the same state (e.g., sticky modality). | ||
| // The pool groups various marks (_e.g._ tip) to compete for the closest point. |
There was a problem hiding this comment.
This doesn’t explain how the pool map is structured. The key is currently render instance… but that doesn’t sound right to me. Shouldn’t it be the renderIndex as described below instead? (You can reuse a render transform, theoretically.)
There was a problem hiding this comment.
(Also don’t use Markdown formatting in comments.)
Co-authored-by: Mike Bostock <mbostock@gmail.com>
Adds a
pooloption to the pointer transform, that defaults to true on the tip mark (including marks derived with thetip: truemark option). Marks that pool their pointer transform show only the closest point among all marks, preventing collisions. Non-pooled marks (like crosshair sub-marks) are unaffected. This also handles facet deduplication.closes #1835
Enregistrement.de.l.ecran.2026-03-17.a.15.30.41.mp4
You can opt out by setting
pool: false(but why would you?). In the future this could be extended to different named pools (but again, why?).