Skip to content

Component | Plotline | Plotband: Auto-position labels on collision (1.7) - #777

Open
50rayn wants to merge 11 commits into
f5:mainfrom
50rayn:feat/plot-label-auto-position
Open

Component | Plotline | Plotband: Auto-position labels on collision (1.7)#777
50rayn wants to merge 11 commits into
f5:mainfrom
50rayn:feat/plot-label-auto-position

Conversation

@50rayn

@50rayn 50rayn commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Stacking multiple VisPlotlines for a percentile threshold view, every label rendered at the same top-right anchor and they piled on top of each other. Same problem with VisPlotband once two ands overlap. labelPosition was fixed; no way out.

Two new opt-in props on each — labelAutoPosition and labelOverflow:

  • smart (default) — try the preferred anchor, then walk candidates clockwise and pick the lowest-overlap fit
  • hide — keep the preferred anchor; drop the label if it collides
  • stack — keep the preferred anchor regardless

Resolver lives in xy-container/plot-label-resolver.ts and runs once per render after components draw their labels. Components opt in via getLabelLayoutInfo() returning candidate anchors + a computeLayout callback. The container projects each candidate into a rect, tracks placed rects, and avoids them.

Vertical-orientation labels (rotate(-90, x, y)) needed special handling — getBBox() returns pre-rotation bounds, so the projector swaps width/height and shifts by text-anchor along the rotated y-axis. isRotatedQuarter keeps the math local to the resolver.

Split the old plotband-plotline example into two playgrounds (plotlines-playground, plotbands-playground) with sliders + an labelOverflow dropdown — drag labels into collision and watch each strategy live. Plus a synced-auto-position stress demo (React/Vue/Svelte/Solid/Angular) that drops N plotlines onto the same y-region.

Snapshot tests for every label-position layout under components/{plotline,plotband}/constants.test.ts; resolver semantics under plot-label-resolver.test.ts.

Drive-by: docs/wrappers/base/doc-tabs.tsx — components.find was returning the first match, but DocWrapper appends the main component last. Reversed the find so the doc preview matches the imported main.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not sure this is the best place for the test.ts file and the resolver. Personally I think this should go under utils, or even better, as part of the plotband or plotline components? @rokotyan @suryahanumandla thoughts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

😄 I was thinking a lot about the test location. I was inspired by reka-ui, locating the test near the components themselves. It brings some benefits:

  1. near the components - comfortable to "find"
  2. don't need to keep the file tree structure synced with the tests folder with src.
  3. lower chance of missing a unit test. Or see if the test exists for the component/script.

Personally, if will be decided to move tests to the tests folder, I would like to keep the same folder tree structure. But the chance of breaking this "rule" is big.

@50rayn
50rayn force-pushed the feat/plot-label-auto-position branch 3 times, most recently from c365b00 to 267d5e3 Compare May 6, 2026 17:31
@50rayn
50rayn force-pushed the feat/plot-label-auto-position branch 2 times, most recently from 331b4a8 to efe24b5 Compare May 14, 2026 21:08
@lee00678 lee00678 changed the title Component | Plotline | Plotband: Auto-position labels on collision Component | Plotline | Plotband: Auto-position labels on collision (1.7) Jun 15, 2026
@50rayn
50rayn force-pushed the feat/plot-label-auto-position branch from efe24b5 to c5ac8a0 Compare June 30, 2026 09:34
@lee00678
lee00678 force-pushed the feat/plot-label-auto-position branch 2 times, most recently from a58cbc5 to f20cc05 Compare July 1, 2026 18:21
@rokotyan

rokotyan commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

A small related update: I added a few library-wide text overlapping utilities in my latest PR 62f15f9

@50rayn
50rayn force-pushed the feat/plot-label-auto-position branch from f20cc05 to 6a19b60 Compare July 3, 2026 07:47
@50rayn

50rayn commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@rokotyan good call — plugged them in. Hide overflow now runs through your resolveRectsOverlap (candidate-vs-candidate) + rectIntersect (against fixed labels), and I dropped the local Rect for the shared types/misc one.

The Smart path I left alone — it repositions labels rather than hiding, so the batch pass doesn't really apply there.

@50rayn
50rayn force-pushed the feat/plot-label-auto-position branch 2 times, most recently from 729a5cc to b252eca Compare July 17, 2026 06:31
@50rayn
50rayn force-pushed the feat/plot-label-auto-position branch 2 times, most recently from 2e84f0f to 6ec3dee Compare August 10, 2026 21:03
@50rayn
50rayn force-pushed the feat/plot-label-auto-position branch from 6ec3dee to e1b9838 Compare August 12, 2026 10:23
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.

3 participants