Skip to content

fix(render): adapt axis ticks to available plot space - #2

Merged
nmrtist merged 1 commit into
mainfrom
fix/adaptive-axis-tick-layout
Jul 22, 2026
Merged

fix(render): adapt axis ticks to available plot space#2
nmrtist merged 1 commit into
mainfrom
fix/adaptive-axis-tick-layout

Conversation

@nmrtist

@nmrtist nmrtist commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

Axis tick counts were previously fixed at eight for x and five for y,
regardless of the final plot dimensions. Because PlotX uses absolute
publication-sized typography, shrinking a plot could cause adjacent tick
labels to overlap.

This change introduces a shared, size-aware axis layout used by the screen,
SVG, and EMF renderers. Tick density is derived from the final plot rectangle
after margins, projection bands, and aspect-ratio locking are applied.

Key changes:

  • Move shared tick generation, formatting, and width estimation into a
    dedicated render module.
  • Add AxisLayout, which computes margins and x/y tick sets together for the
    requested output dimensions.
  • Thin numeric and categorical ticks according to available width and height.
  • Validate actual x-label intervals after nice-tick generation rather than
    assuming the requested target equals the resulting tick count.
  • Drop an axis's ticks and labels when two labels cannot fit, while preserving
    the axis line.
  • Keep canvas zoom independent from layout density by calculating screen
    layouts in page units.
  • Use the same adaptive margins for painting, export, hit testing, and phase
    editing so rendered and interactive plot rectangles stay aligned.
  • Make the first layout pass conservative across every visible category,
    preventing later stride choices from increasing margins and invalidating
    label-fit checks.
  • Reserve space for endpoint x labels even when y ticks are dropped.
  • Use Unicode East Asian Width data for CJK, full-width, supplementary-plane,
    combining, and other Unicode characters.
  • Escape categorical tick labels in SVG output.
  • Clarify the intrinsic-size semantics of Margins::for_figure.
  • Update the English and Simplified Chinese layout documentation.

The intentionally conservative categorical first pass may reserve space for a
long category that is not ultimately labeled. This tradeoff ensures the final
plot rectangle never becomes smaller than the rectangle used to validate tick
spacing.

Validation

  • cargo test -p plotx-render — 48 tests passed
  • cargo pr-check — all 7 checks passed, including:
    • formatting
    • Rust source-size limits
    • dependency policy
    • default frontend builds
    • Clippy with warnings denied
    • all-feature workspace tests
    • reference-backend tests
  • npm run build from docs/ — passed
  • git diff --check — passed

Regression coverage includes:

  • adjacent x-label interval separation across narrow and wide figures
  • monotonic tick-density changes
  • extremely small figures retaining their axis lines
  • long categorical labels and changing categorical strides
  • CJK and supplementary-plane character widths
  • reversed axes and scientific multipliers
  • aspect locking and marginal projection bands
  • SVG escaping for user-provided category names
  • screen/export layout consistency

Centralize axis tick and margin calculation across screen, SVG, and EMF renderers. Thin labels according to the final plot rectangle, account for categorical and East Asian text widths, and drop ticks gracefully when the available space is insufficient.

Keep canvas interaction geometry aligned with rendering, escape categorical labels in SVG output, and document the adaptive behavior in English and Simplified Chinese.
@nmrtist
nmrtist merged commit 26b54a2 into main Jul 22, 2026
11 checks passed
@nmrtist
nmrtist deleted the fix/adaptive-axis-tick-layout branch July 22, 2026 05:37
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 22, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant