Skip to content

Commit 9cb20f0

Browse files
authored
Merge pull request #7872 from vizansh/fix-bar-label-overlap
fix(bar): prevent outside text labels from overlapping tilted axis ticks
2 parents aad9b94 + d0ded0d commit 9cb20f0

3 files changed

Lines changed: 70 additions & 2 deletions

File tree

draftlogs/7872_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Prevent outside bar text for zero-length bars from overlapping axis tick labels [[#7872](https://github.com/plotly/plotly.js/pull/7872)], with thanks to @vizansh for the contribution!

src/traces/bar/plot.js

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ function appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, r, overhead, op
554554
// get trace attributes
555555
var trace = cd[0].trace;
556556
var isHorizontal = trace.orientation === 'h';
557+
var zeroBarDir = getZeroBarDir(cd, isHorizontal, xa, ya);
557558

558559
var text = getText(fullLayout, cd, i, xa, ya);
559560

@@ -707,7 +708,8 @@ function appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, r, overhead, op
707708
transform = toMoveOutsideBar(x0, x1, y0, y1, textBB, {
708709
isHorizontal: isHorizontal,
709710
constrained: constrained,
710-
angle: angle
711+
angle: angle,
712+
zeroBarDir: zeroBarDir
711713
});
712714
} else {
713715
constrained = trace.constraintext === 'both' || trace.constraintext === 'inside';
@@ -957,7 +959,12 @@ function toMoveOutsideBar(x0, x1, y0, y1, textBB, opts) {
957959
var anchorX = 0;
958960
var anchorY = 0;
959961

960-
var dir = isHorizontal ? dirSign(x1, x0) : dirSign(y0, y1);
962+
var dir;
963+
if ((isHorizontal ? x0 === x1 : y0 === y1) && opts.zeroBarDir) {
964+
dir = opts.zeroBarDir;
965+
} else {
966+
dir = isHorizontal ? dirSign(x1, x0) : dirSign(y0, y1);
967+
}
961968
if (isHorizontal) {
962969
targetX = x1 - dir * textpad;
963970
anchorX = dir * extrapad;
@@ -999,6 +1006,38 @@ function getTextPosition(trace, index) {
9991006
return helpers.coerceEnumerated(attributeTextPosition, value);
10001007
}
10011008

1009+
function getZeroBarDir(cd, isHorizontal, xa, ya) {
1010+
var hasPositive = false;
1011+
var hasNegative = false;
1012+
1013+
for (var i = 0; i < cd.length; i++) {
1014+
var s = cd[i].s;
1015+
1016+
if (s > 0) {
1017+
hasPositive = true;
1018+
} else if (s < 0) {
1019+
hasNegative = true;
1020+
}
1021+
1022+
if (hasPositive && hasNegative) {
1023+
return 0;
1024+
}
1025+
}
1026+
1027+
var axis = isHorizontal ? xa : ya;
1028+
var positiveDir = -dirSign(axis.range[0], axis.range[1]);
1029+
1030+
if (!hasNegative) {
1031+
return positiveDir;
1032+
}
1033+
1034+
if (!hasPositive) {
1035+
return -positiveDir;
1036+
}
1037+
1038+
return 0;
1039+
}
1040+
10021041
function calcTexttemplate(fullLayout, cd, index, xa, ya) {
10031042
var trace = cd[0].trace;
10041043
var texttemplate = Lib.castOption(trace, index, 'texttemplate');

test/jasmine/tests/bar_test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,34 @@ describe('A bar plot', function() {
14111411
.then(done, done.fail);
14121412
});
14131413

1414+
it('should keep zero-value outside labels on the same side as negative bars', function(done) {
1415+
var data = [{
1416+
y: [-10, 0, -30],
1417+
type: 'bar',
1418+
text: ['a', 'zero', 'c'],
1419+
textposition: 'outside'
1420+
}];
1421+
1422+
Plotly.newPlot(gd, data).then(function() {
1423+
var traceNodes = getAllTraceNodes(gd);
1424+
var barNodes = getAllBarNodes(traceNodes[0]);
1425+
var foundTextNodes;
1426+
1427+
for(var i = 0; i < barNodes.length; i++) {
1428+
var barNode = barNodes[i];
1429+
var pathNode = barNode.querySelector('path');
1430+
var textNode = barNode.querySelector('text');
1431+
if(textNode) {
1432+
foundTextNodes = true;
1433+
assertTextIsBelowPath(textNode, pathNode);
1434+
}
1435+
}
1436+
1437+
expect(foundTextNodes).toBe(true);
1438+
})
1439+
.then(done, done.fail);
1440+
});
1441+
14141442
it('should show bar texts (horizontal case)', function(done) {
14151443
var data = [{
14161444
x: [10, -20, 30],

0 commit comments

Comments
 (0)