diff --git a/src/traces/bar/attributes.js b/src/traces/bar/attributes.js index 9fa333fdf05..3a56661ec07 100644 --- a/src/traces/bar/attributes.js +++ b/src/traces/bar/attributes.js @@ -80,6 +80,17 @@ module.exports = { description: 'Sets the font used for `text` lying outside the bar.' }), + constraintext: { + valType: 'enumerated', + values: ['inside', 'outside', 'both', 'none'], + role: 'info', + dflt: 'both', + description: [ + 'Constrain the size of text inside or outside a bar to be no', + 'larger than the bar itself.' + ].join(' ') + }, + orientation: { valType: 'enumerated', role: 'info', diff --git a/src/traces/bar/defaults.js b/src/traces/bar/defaults.js index 6436dffb9d4..84e26f5a0f2 100644 --- a/src/traces/bar/defaults.js +++ b/src/traces/bar/defaults.js @@ -48,6 +48,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout var textFont = coerceFont(coerce, 'textfont', layout.font); if(hasInside) coerceFont(coerce, 'insidetextfont', textFont); if(hasOutside) coerceFont(coerce, 'outsidetextfont', textFont); + coerce('constraintext'); } handleStyleDefaults(traceIn, traceOut, coerce, defaultColor, layout); diff --git a/src/traces/bar/plot.js b/src/traces/bar/plot.js index fa5f6580f3e..fdd5bfd33c2 100644 --- a/src/traces/bar/plot.js +++ b/src/traces/bar/plot.js @@ -237,20 +237,22 @@ function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) { } // compute text transform - var transform; + var transform, constrained; if(textPosition === 'outside') { + constrained = trace.constraintext === 'both' || trace.constraintext === 'outside'; transform = getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB, - orientation); + orientation, constrained); } else { + constrained = trace.constraintext === 'both' || trace.constraintext === 'inside'; transform = getTransformToMoveInsideBar(x0, x1, y0, y1, textBB, - orientation); + orientation, constrained); } textSelection.attr('transform', transform); } -function getTransformToMoveInsideBar(x0, x1, y0, y1, textBB, orientation) { +function getTransformToMoveInsideBar(x0, x1, y0, y1, textBB, orientation, constrained) { // compute text and target positions var textWidth = textBB.width, textHeight = textBB.height, @@ -289,12 +291,12 @@ function getTransformToMoveInsideBar(x0, x1, y0, y1, textBB, orientation) { else if((textWidth < textHeight) === (barWidth < barHeight)) { // only scale is required rotate = false; - scale = Math.min(barWidth / textWidth, barHeight / textHeight); + scale = constrained ? Math.min(barWidth / textWidth, barHeight / textHeight) : 1; } else { // both scale and rotation are required rotate = true; - scale = Math.min(barHeight / textWidth, barWidth / textHeight); + scale = constrained ? Math.min(barHeight / textWidth, barWidth / textHeight) : 1; } if(rotate) rotate = 90; // rotate clockwise @@ -335,23 +337,25 @@ function getTransformToMoveInsideBar(x0, x1, y0, y1, textBB, orientation) { return getTransform(textX, textY, targetX, targetY, scale, rotate); } -function getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB, orientation) { +function getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB, orientation, constrained) { var barWidth = (orientation === 'h') ? Math.abs(y1 - y0) : Math.abs(x1 - x0), textpad; - // apply text padding if possible + // Keep the padding so the text doesn't sit right against + // the bars, but don't factor it into barWidth if(barWidth > 2 * TEXTPAD) { textpad = TEXTPAD; - barWidth -= 2 * textpad; } // compute rotation and scale - var rotate = false, + var scale = 1; + if(constrained) { scale = (orientation === 'h') ? Math.min(1, barWidth / textBB.height) : Math.min(1, barWidth / textBB.width); + } // compute text and target positions var textX = (textBB.left + textBB.right) / 2, @@ -360,14 +364,9 @@ function getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB, orientation) { targetHeight, targetX, targetY; - if(rotate) { - targetWidth = scale * textBB.height; - targetHeight = scale * textBB.width; - } - else { - targetWidth = scale * textBB.width; - targetHeight = scale * textBB.height; - } + + targetWidth = scale * textBB.width; + targetHeight = scale * textBB.height; if(orientation === 'h') { if(x1 < x0) { @@ -392,7 +391,7 @@ function getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB, orientation) { } } - return getTransform(textX, textY, targetX, targetY, scale, rotate); + return getTransform(textX, textY, targetX, targetY, scale, false); } function getTransform(textX, textY, targetX, targetY, scale, rotate) { diff --git a/test/image/baselines/bar_attrs_group_norm.png b/test/image/baselines/bar_attrs_group_norm.png index 2a6af739214..ceb86e17b82 100644 Binary files a/test/image/baselines/bar_attrs_group_norm.png and b/test/image/baselines/bar_attrs_group_norm.png differ diff --git a/test/image/baselines/bar_attrs_relative.png b/test/image/baselines/bar_attrs_relative.png index a9406c60670..a190cfc7e23 100644 Binary files a/test/image/baselines/bar_attrs_relative.png and b/test/image/baselines/bar_attrs_relative.png differ diff --git a/test/jasmine/tests/bar_test.js b/test/jasmine/tests/bar_test.js index 3b0aa922322..6de79cdf40a 100644 --- a/test/jasmine/tests/bar_test.js +++ b/test/jasmine/tests/bar_test.js @@ -95,6 +95,7 @@ describe('Bar.supplyDefaults', function() { expect(traceOut.texfont).toBeUndefined(); expect(traceOut.insidetexfont).toBeUndefined(); expect(traceOut.outsidetexfont).toBeUndefined(); + expect(traceOut.constraintext).toBeUndefined(); }); it('should default textfont to layout.font', function() { @@ -116,6 +117,7 @@ describe('Bar.supplyDefaults', function() { expect(traceOut.insidetextfont).not.toBe(layout.font); expect(traceOut.insidetextfont).not.toBe(traceOut.textfont); expect(traceOut.outsidetexfont).toBeUndefined(); + expect(traceOut.constraintext).toBe('both'); }); it('should inherit layout.calendar', function() {