fix: correct left-edge guard for dataLabels textAnchor:start in horizontal bar charts (Closes #5094) - #5262
Conversation
…ontal bar charts (Closes apexcharts#5094)
junedchhipa
left a comment
There was a problem hiding this comment.
Thanks for digging into #5094 — the direction here is right for positive values, but the change over-applies and the new test doesn't currently guard the fix. Two things before this can land.
1. Negative bars get pushed outside the plot
In src/charts/common/bar/DataLabels.js, dropping - textRects.width from the left-edge guard is correct for positive values (anchor stays start, text extends right, so only the anchor x matters). But the same branch also handles negatives, and drawCalculatedDataLabels flips start -> end when val < 0 on horizontal bars. With anchor end the label extends left from dataLabelsX, so the width term was load-bearing there. The branch's own negative pin (textRects.width + strokeWidth - offX) and the right-edge sibling (gridWidth - strokeWidth) both confirm the anchor-end semantics.
Verified in Chromium against samples/source/tests/position-top-text-anchor-start-series-neg.xml: the India: -1380 label moves from x=63.39 (bbox left -2.6) on main to x=49.04 (bbox left -16.99) with this PR, i.e. ~17px now sits outside the plot area. A tighter case ([-17332, -16000, -15000] with xaxis: { min: -17332, max: 0 }) pushes the label fully off-screen at x=0, where main pinned it at x=72.
Suggested fix — keep the width term only on the anchor-end path:
if (valIsNegative ? dataLabelsX - textRects.width < 0 : dataLabelsX < 0) {The e2e snapshot matrix doesn't catch this because the per-sample tolerance is 5% of pixels.
2. The new spec passes without the fix
tests/unit/issue-5094-datalabel-horizontal-bar.spec.js is green (4/4) against the pre-fix source — I reverted DataLabels.js and re-ran to confirm. The reason is noted in the spec's own header: the jsdom getBBox stub in tests/unit/setup.js returns a fixed 10px width, so the textRects.width term can never influence the outcome.
Overriding SVGGraphicsElement.prototype.getBBox with a length-proportional width makes both the original bug and the negative-value regression above reproducible in unit tests. Please also add coverage for negative series values.
Minor: the new test file is missing a trailing newline.
Summary
Fixes #5094 — Data label is misaligned when the label text is wider than the bar in a horizontal bar chart with
textAnchor: 'start'.Root cause
In
src/charts/common/bar/DataLabels.js, the left-edge overflow guard fortextAnchor: 'start'used:This condition is correct for
textAnchor: 'end'(where text extends left from the anchor), but wrong fortextAnchor: 'start', where the text extends right fromdataLabelsX.As a result, whenever a label's text was wider than the bar tip position (
dataLabelsX), the condition fired even though the anchor was comfortably inside the plot — pinning the label tostrokeWidth + offX(near the left edge) and misaligning it with the other labels in the chart.Fix
Change the guard to check the anchor point itself:
Now the left-edge guard only fires when the anchor point is genuinely off-screen to the left — which is the correct behavior for
textAnchor: 'start'.Tests
Added
tests/unit/issue-5094-datalabel-horizontal-bar.spec.jswith 4 regression tests verifying:All 1980 unit tests pass (92 files, 0 new failures).
Type of change