Skip to content

fix(xychart): prevent flipped point label from clipping x-axis#3

Closed
DominicBurkart wants to merge 5 commits intoclaude/fix-label-line-collision-HNiTafrom
claude/fix-axis-label-collision-83QoO
Closed

fix(xychart): prevent flipped point label from clipping x-axis#3
DominicBurkart wants to merge 5 commits intoclaude/fix-label-line-collision-HNiTafrom
claude/fix-axis-label-collision-83QoO

Conversation

@DominicBurkart
Copy link
Copy Markdown
Owner

Summary

  • Fixes a regression introduced in fix(xychart): auto-flip point labels to avoid line collision #2 where the "Mistral 7B" label gets flipped below its data point (to avoid line collision) but lands on top of the x-axis line and tick labels
  • Before flipping a label below a point, the code now checks that py + labelOffset + fontSize/2 stays within yAxis.getRange()[1] — the inner bottom boundary of the plot area. If it would clip the axis, the label stays above (accepting the line collision as the lesser visual evil)
  • Exposes getRange(): [number, number] on the Axis interface — the method was already implemented on BaseAxis but wasn't part of the public interface

Stacked on #2.

Changes

File Change
chartBuilder/components/axis/index.ts Add getRange() to Axis interface
chartBuilder/components/plot/linePlot.ts Guard downward flip with axis-bounds check
scripts/qa-screenshots.mjs Playwright-based QA screenshot script for autonomous iteration
qa-screenshots/collision-*.png Updated screenshots showing the fix

Test plan

  • All 4008 vitest unit tests pass (0 failures)
  • QA screenshot: steep descent — "Mistral 7B" label stays above x-axis
  • QA screenshot: gentle slope — labels remain above (no regression)
  • QA screenshot: zigzag — low-value labels stay above (not clipped)

https://claude.ai/code/session_016Sz6E37rqhUbbTQZ72FrB6

claude added 3 commits March 29, 2026 09:35
When a line segment has a steep slope, labels placed above a data point
can collide with the line. This adds collision detection that estimates
each label's bounding box and checks for intersection with adjacent line
segments. When a collision is detected, the label is flipped to the
opposite side of the point (below for vertical charts, left for
horizontal charts).

https://claude.ai/code/session_01UCV1QCaRsRtQjRspaVrqUp
The previous 3-point sampling approach missed cases where a steep line
segment crossed through the label bounding box between sample points
(e.g., valley points in a zigzag). Now computes the segment's y-range
within the box's x-range and checks for overlap, which correctly
detects all crossing scenarios.

https://claude.ai/code/session_01UCV1QCaRsRtQjRspaVrqUp
Copy link
Copy Markdown
Owner Author

QA Results v3: X-Axis Label Collision Fix


1. Steep Descent — MMLU Real-World Example

PASS — "Mistral 7B" now stays above its data point, within the chart area. No longer clips the x-axis. Other low-value labels ("LLaMA-65B", "Llama 2 34B", "Phi-3-mini") also stay above without axis collision.

collision-01-steep-descent


2. Gentle Slope — No Collision (regression check)

PASS — "Start", "Mid", "End" labels remain above their points. No regression introduced.

collision-02-gentle-slope


3. Zigzag Pattern — Low-value labels at bottom

PASS — "Low" and "Bottom" labels (near the x-axis) correctly stay above their points rather than flipping below and clipping the axis.

collision-03-zigzag


Summary

# Test Case Label Position Result
1 Steep descent (MMLU) — regression from PR#2 All labels above, within chart bounds PASS
2 Gentle slope Labels above (no false positives) PASS
3 Zigzag — low valley points Labels above (no axis clip) PASS

Automated tests: 4008/4008 vitest unit tests pass, 0 regressions.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

QA Results v3: X-Axis Label Collision Fix

(Replaces previous comment — fixing broken image URLs)


1. Steep Descent — MMLU Real-World Example

PASS — "Mistral 7B" now stays above its data point, within the chart area. No longer clips the x-axis. Other low-value labels ("LLaMA-65B", "Llama 2 34B", "Phi-3-mini") also stay above without axis collision.

collision-01-steep-descent


2. Gentle Slope — No Collision (regression check)

PASS — "Start", "Mid", "End" labels remain above their points. No regression introduced.

collision-02-gentle-slope


3. Zigzag Pattern — Low-value labels at bottom

PASS — "Low" and "Bottom" labels (near the x-axis) correctly stay above their points rather than flipping below and clipping the axis.

collision-03-zigzag


Summary

# Test Case Label Position Result
1 Steep descent (MMLU) — regression from PR#2 All labels above, within chart bounds PASS
2 Gentle slope Labels above (no false positives) PASS
3 Zigzag — low valley points Labels above (no axis clip) PASS

Automated tests: 4008/4008 vitest unit tests pass, 0 regressions.


Generated by Claude Code

claude added 2 commits March 29, 2026 11:17
When shouldFlipLabelVertical() recommends placing a label below its
data point (to avoid line collision), check that py + labelOffset +
fontSize/2 stays within yAxis.getRange()[1] — the inner bottom
boundary of the plot area. If the flipped position would collide with
the x-axis, keep the label above instead.

Exposes getRange() on the Axis interface (already implemented on
BaseAxis) so linePlot.ts can query the plot boundary.

Fixes the "Mistral 7B" label regression introduced in PR#2 where the
label was flipped below its point but landed on top of the x-axis
line and tick labels.

https://claude.ai/code/session_016Sz6E37rqhUbbTQZ72FrB6
@DominicBurkart DominicBurkart force-pushed the claude/fix-axis-label-collision-83QoO branch from 0a77dd5 to 7d4341a Compare March 29, 2026 11:18
@DominicBurkart DominicBurkart force-pushed the claude/fix-label-line-collision-HNiTa branch from b085228 to 8c36d1d Compare March 29, 2026 11:20
@DominicBurkart
Copy link
Copy Markdown
Owner Author

Superseded by mermaid-js#7552

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.

2 participants