Skip to content

Cleanup: generate axis ticks in-range instead of pruning after the fact (follow-up to #634) #997

Description

@timmolter

Follow-up / tech-debt cleanup from the fix for #634 (PR #996).

Context

#634 was a negative Y-axis label appearing with all-positive data. Root cause: AxisTickCalculator_.calculate() deliberately overshoots the tick range — getFirstPosition() starts one grid step below minValue and the loop runs to maxValue + 2*gridStep — and the tick-label renderer (AxisTickLabels) clips only to the taller axis-column bounds, so overshoot labels leak into the plot margin. (Gridlines and tick marks already clip correctly to the plot bounds in PlotSurface_AxesChart.)

PR #996 fixed the visible bug by pruning ticks outside the data band [margin, margin+tickSpace] after the generation do-while settles. That was chosen deliberately to be behavior-preserving: pruning post-loop leaves the grid-step selection heuristics (areAllTickLabelsUnique / willLabelsFitInTickSpaceHint) seeing the exact same full set as before, so tick density on existing charts is unchanged.

What this issue tracks

Do the structurally cleaner version when there's time to validate it more broadly:

  1. Preferred: make AxisTickLabels clip tick labels to the plot-content band, the same way PlotSurface_AxesChart already clips gridlines and tick marks — so all three consumers of the tick list clip consistently, instead of the calculator emitting values one consumer must drop.

    or

  2. Generate ticks in-range from the start (fix getFirstPosition + the loop upper bound to emit exactly the nice multiples within [minValue, maxValue]), removing the overshoot entirely.

Why it wasn't done in #996

  • Changing generation inputs (option 2) alters what the termination heuristics see, which can change the selected grid step / tick density on charts that never had the bug — a wide regression surface with no pixel-baseline tests to catch it.
  • Option 1 needs the plot-content band (margin / tickSpace) plumbed into AxisTickLabels, which doesn't currently have it.

Bonus wart to fix along the way

With the current pruning approach, the user's tick-label formatting function is still called on the out-of-range values during generation (label computed, then discarded). A generate-in-range approach would avoid invoking the formatter on values outside the data band — relevant if a formatter has side effects or throws on unexpected inputs.

Acceptance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions