Skip to content

Commit 189ad5d

Browse files
authored
Merge pull request #3701 from plotly/outsidetext-on-blank-bars
Draw blank bars as empty paths + allow blank bars to draw outsidetext
2 parents e674979 + f05a29a commit 189ad5d

File tree

5 files changed

+60
-26
lines changed

5 files changed

+60
-26
lines changed

src/traces/bar/plot.js

+19-18
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,11 @@ module.exports = function plot(gd, plotinfo, cdModule, traceLayer) {
8383
di.ct = [(x0 + x1) / 2, y1];
8484
}
8585

86-
if(!isNumeric(x0) || !isNumeric(x1) ||
87-
!isNumeric(y0) || !isNumeric(y1) ||
88-
x0 === x1 || y0 === y1) {
89-
bar.remove();
90-
return;
91-
}
86+
var isBlank = di.isBlank = (
87+
!isNumeric(x0) || !isNumeric(x1) ||
88+
!isNumeric(y0) || !isNumeric(y1) ||
89+
x0 === x1 || y0 === y1
90+
);
9291

9392
// in waterfall mode `between` we need to adjust bar end points to match the connector width
9493
if(adjustPixel) {
@@ -158,7 +157,7 @@ module.exports = function plot(gd, plotinfo, cdModule, traceLayer) {
158157

159158
Lib.ensureSingle(bar, 'path')
160159
.style('vector-effect', 'non-scaling-stroke')
161-
.attr('d', 'M' + x0 + ',' + y0 + 'V' + y1 + 'H' + x1 + 'V' + y0 + 'Z')
160+
.attr('d', isBlank ? 'M0,0Z' : 'M' + x0 + ',' + y0 + 'V' + y1 + 'H' + x1 + 'V' + y0 + 'Z')
162161
.call(Drawing.setClipUrl, plotinfo.layerClipId, gd);
163162

164163
appendBarText(gd, bar, cd, i, x0, x1, y0, y1);
@@ -206,11 +205,6 @@ function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) {
206205
var text = getText(trace, i);
207206
textPosition = getTextPosition(trace, i);
208207

209-
if(!text || textPosition === 'none') {
210-
bar.select('text').remove();
211-
return;
212-
}
213-
214208
var layoutFont = fullLayout.font;
215209
var barColor = style.getBarColor(calcTrace[i], trace);
216210
var insideTextFont = style.getInsideTextFont(trace, i, layoutFont, barColor);
@@ -219,15 +213,20 @@ function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) {
219213
// compute text position
220214
var prefix = trace.type === 'waterfall' ? 'waterfall' : 'bar';
221215
var barmode = fullLayout[prefix + 'mode'];
222-
var inStackMode = (barmode === 'stack');
223-
var inRelativeMode = (barmode === 'relative');
224-
var inStackOrRelativeMode = inStackMode || inRelativeMode;
216+
var inStackOrRelativeMode = barmode === 'stack' || barmode === 'relative';
225217

226218
var calcBar = calcTrace[i];
227219
var isOutmostBar = !inStackOrRelativeMode || calcBar._outmost;
228220

229-
var barWidth = Math.abs(x1 - x0) - 2 * TEXTPAD; // padding excluded
230-
var barHeight = Math.abs(y1 - y0) - 2 * TEXTPAD; // padding excluded
221+
// padding excluded
222+
var barWidth = Math.abs(x1 - x0) - 2 * TEXTPAD;
223+
var barHeight = Math.abs(y1 - y0) - 2 * TEXTPAD;
224+
225+
if(!text || textPosition === 'none' ||
226+
(calcBar.isBlank && (textPosition === 'auto' || textPosition === 'inside'))) {
227+
bar.select('text').remove();
228+
return;
229+
}
231230

232231
var textSelection;
233232
var textBB;
@@ -263,7 +262,9 @@ function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) {
263262
textSelection.remove();
264263
textSelection = null;
265264
}
266-
} else textPosition = 'inside';
265+
} else {
266+
textPosition = 'inside';
267+
}
267268
}
268269

269270
if(!textSelection) {
12.3 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"data": [
3+
{
4+
"type": "bar",
5+
"x": [ "textposition:outside" ],
6+
"y": [ 0 ],
7+
"text": [ "Text" ],
8+
"textposition": [ "outside" ]
9+
},
10+
{
11+
"type": "bar",
12+
"x": [ "textpostion:auto" ],
13+
"y": [ 0 ],
14+
"text": [ "should not see" ],
15+
"textposition": [ "auto" ]
16+
},
17+
{
18+
"type": "bar",
19+
"x": [ "textpostion:inside" ],
20+
"y": [ 0 ],
21+
"text": [ "should not see" ],
22+
"textposition": [ "inside" ]
23+
}
24+
],
25+
"layout": {
26+
"showlegend": false,
27+
"width": 600
28+
}
29+
}

test/jasmine/tests/bar_test.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,8 @@ describe('A bar plot', function() {
15471547
assertTraceField(cd, 't.bargroupwidth', [0.8, 0.8, 0.8, 0.8]);
15481548

15491549
return Plotly.restyle(gd, 'offset', 0);
1550-
}).then(function() {
1550+
})
1551+
.then(function() {
15511552
var cd = gd.calcdata;
15521553
assertPointField(cd, 'x', [
15531554
[1.5, 2.4, 3.3, 4.2], [1.2, 2.3, 3.4, 4.5],
@@ -1584,7 +1585,7 @@ describe('A bar plot', function() {
15841585
var trace2Bar0 = getAllBarNodes(traceNodes[2])[0];
15851586
var path20 = trace2Bar0.querySelector('path');
15861587
var text20 = trace2Bar0.querySelector('text');
1587-
var trace3Bar0 = getAllBarNodes(traceNodes[3])[0];
1588+
var trace3Bar0 = getAllBarNodes(traceNodes[3])[1];
15881589
var path30 = trace3Bar0.querySelector('path');
15891590
var text30 = trace3Bar0.querySelector('text');
15901591

@@ -1610,7 +1611,8 @@ describe('A bar plot', function() {
16101611
Drawing.savedBBoxes = {};
16111612

16121613
return Plotly.restyle(gd, 'textposition', 'inside');
1613-
}).then(function() {
1614+
})
1615+
.then(function() {
16141616
var cd = gd.calcdata;
16151617
assertPointField(cd, 'x', [
16161618
[1.5, 2.4, 3.3, 4.2], [1.2, 2.3, 3.4, 4.5],
@@ -1647,7 +1649,7 @@ describe('A bar plot', function() {
16471649
var trace2Bar0 = getAllBarNodes(traceNodes[2])[0];
16481650
var path20 = trace2Bar0.querySelector('path');
16491651
var text20 = trace2Bar0.querySelector('text');
1650-
var trace3Bar0 = getAllBarNodes(traceNodes[3])[0];
1652+
var trace3Bar0 = getAllBarNodes(traceNodes[3])[1];
16511653
var path30 = trace3Bar0.querySelector('path');
16521654
var text30 = trace3Bar0.querySelector('text');
16531655

test/jasmine/tests/waterfall_test.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,8 @@ describe('A waterfall plot', function() {
802802
assertTraceField(cd, 't.bargroupwidth', [0.8, 0.8, 0.8, 0.8]);
803803

804804
return Plotly.restyle(gd, 'offset', 0);
805-
}).then(function() {
805+
})
806+
.then(function() {
806807
var cd = gd.calcdata;
807808
assertPointField(cd, 'x', [
808809
[1.5, 2.4, 3.3, 4.2], [1.2, 2.3, 3.4, 4.5],
@@ -836,7 +837,7 @@ describe('A waterfall plot', function() {
836837
var trace2Waterfall0 = getAllWaterfallNodes(traceNodes[2])[0];
837838
var path20 = trace2Waterfall0.querySelector('path');
838839
var text20 = trace2Waterfall0.querySelector('text');
839-
var trace3Waterfall0 = getAllWaterfallNodes(traceNodes[3])[0];
840+
var trace3Waterfall0 = getAllWaterfallNodes(traceNodes[3])[1];
840841
var path30 = trace3Waterfall0.querySelector('path');
841842
var text30 = trace3Waterfall0.querySelector('text');
842843

@@ -862,7 +863,8 @@ describe('A waterfall plot', function() {
862863
Drawing.savedBBoxes = {};
863864

864865
return Plotly.restyle(gd, 'textposition', 'inside');
865-
}).then(function() {
866+
})
867+
.then(function() {
866868
var cd = gd.calcdata;
867869
assertPointField(cd, 'x', [
868870
[1.5, 2.4, 3.3, 4.2], [1.2, 2.3, 3.4, 4.5],
@@ -896,7 +898,7 @@ describe('A waterfall plot', function() {
896898
var trace2Waterfall0 = getAllWaterfallNodes(traceNodes[2])[0];
897899
var path20 = trace2Waterfall0.querySelector('path');
898900
var text20 = trace2Waterfall0.querySelector('text');
899-
var trace3Waterfall0 = getAllWaterfallNodes(traceNodes[3])[0];
901+
var trace3Waterfall0 = getAllWaterfallNodes(traceNodes[3])[1];
900902
var path30 = trace3Waterfall0.querySelector('path');
901903
var text30 = trace3Waterfall0.querySelector('text');
902904

0 commit comments

Comments
 (0)