Skip to content

pool option for tip marks#2382

Open
Fil wants to merge 7 commits intomainfrom
fil/pooled-tips
Open

pool option for tip marks#2382
Fil wants to merge 7 commits intomainfrom
fil/pooled-tips

Conversation

@Fil
Copy link
Contributor

@Fil Fil commented Mar 17, 2026

Adds a pool option to the pointer transform, that defaults to true on the tip mark (including marks derived with the tip: true mark 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?).

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.
@Fil Fil requested a review from mbostock March 17, 2026 14:35
@Fil Fil requested a review from allisonhorst March 17, 2026 16:18
Copy link

@allisonhorst allisonhorst left a comment

Choose a reason for hiding this comment

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

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)

Image

import {applyFrameAnchor} from "../style.js";

const states = new WeakMap();
const frames = new WeakMap();
Copy link
Member

Choose a reason for hiding this comment

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

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.

Copy link
Member

Choose a reason for hiding this comment

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

(And the pool map too.)

frames.set(
pool,
requestAnimationFrame(() => {
frames.delete(pool);
Copy link
Member

@mbostock mbostock Mar 19, 2026

Choose a reason for hiding this comment

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

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh, right! so we can simplify this further

Copy link
Member

Choose a reason for hiding this comment

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

Should this be called the facetPool now (and state.facetPools), since it serves the same purpose as state.pool?


// 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.
Copy link
Member

Choose a reason for hiding this comment

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

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.)

Copy link
Member

Choose a reason for hiding this comment

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

(Also don’t use Markdown formatting in comments.)

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.

Tips are chaotic on compound marks

3 participants