Skip to content

fix(xaxis): prevent label overlap with adaptive tick thinning#126

Open
ansaganie wants to merge 2 commits into
microsoft:mainfrom
ansaganie:fix/xaxis-label-overlap
Open

fix(xaxis): prevent label overlap with adaptive tick thinning#126
ansaganie wants to merge 2 commits into
microsoft:mainfrom
ansaganie:fix/xaxis-label-overlap

Conversation

@ansaganie

@ansaganie ansaganie commented Jun 30, 2026

Copy link
Copy Markdown

Summary

X-axis labels overlap when font size is increased because \preRender()\ sizes the axis with a 50-tick formatter (short labels), while \render()\ uses the actual formatter (wide labels). The axis ends up with too many ticks for the viewport width.

- Add computeAdaptiveTicks() to reduce tick density when rendered label
  width exceeds available slot width
- Sample up to maxTickSample=20 ticks per render to cap O(n) cost
- Preserve first and last tick in all thinning paths
- Handle slotsAvailable=1 edge case: emit only the last tick
- Extract formatTickLabel() with DateType/string/numeric branches and
  Invalid Date fallback to avoid passing NaN timestamps to the formatter
- Always write back axis.tickValues() as a defensive reset
- Add 8 unit tests: thinning, stability, endpoint preservation,
  zero-width early exit, density recovery, single-slot edge case,
  and formatTickLabel branch coverage (Invalid Date, StringType passthrough)
- Bump version to 3.1.1.0
In headless Chrome, preRender() measures real font widths (~90 px per
date label), causing createAxis to produce only ~4 quarterly ticks.
With 4 ticks on a 400 px viewport (slot = 133 px), a 60 px label fits
without thinning — making all three count/position assertions tie.

- Bump wide-label spy 60 px -> 150 px in 'should reduce' and 'should
  restore' tests: slotsAvailable = floor(400/158) = 2 < n for any
  n >= 3, guaranteeing thinning in both JSDOM and headless Chrome
- In 'should preserve first and last tick': also change endDate from
  Dec 31 2017 -> Jan 1 2018 (a D3 nice-time boundary); the last
  generated tick now maps to the domain endpoint (~400 px), satisfying
  the >80% position assertion regardless of font metrics environment
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.

1 participant