@@ -9,6 +9,8 @@ var Axes = require('../../plots/cartesian/axes');
99var getAxisGroup = require ( '../../plots/cartesian/constraints' ) . getAxisGroup ;
1010var Sieve = require ( './sieve.js' ) ;
1111
12+ var TEXTPAD = require ( './constants' ) . TEXTPAD ;
13+
1214/*
1315 * Bar chart stacking/grouping positioning and autoscaling calculations
1416 * for each direction separately calculate the ranges and positions
@@ -565,9 +567,11 @@ function setBaseAndTop(sa, sieve) {
565567 }
566568 }
567569
570+ const textPadding = estimateExtraPaddingForText ( fullTrace ) ;
568571 fullTrace . _extremes [ sa . _id ] = Axes . findExtremes ( sa , pts , {
569572 tozero : tozero ,
570- padded : true
573+ padded : true ,
574+ ppad : textPadding
571575 } ) ;
572576 }
573577}
@@ -637,13 +641,16 @@ function stackBars(sa, sieve, opts) {
637641 }
638642 }
639643
644+ const textPadding = estimateExtraPaddingForText ( fullTrace ) ;
645+
640646 // if barnorm is set, let normalizeBars update the axis range
641647 if ( ! opts . norm ) {
642648 fullTrace . _extremes [ sa . _id ] = Axes . findExtremes ( sa , pts , {
643649 // N.B. we don't stack base with 'base',
644650 // so set tozero:true always!
645651 tozero : true ,
646- padded : true
652+ padded : true ,
653+ ppad : textPadding
647654 } ) ;
648655 }
649656 }
@@ -754,6 +761,32 @@ function normalizeBars(sa, sieve, opts) {
754761 }
755762}
756763
764+ // Returns a very lightweight estimate of extra padding (in pixels)
765+ // needed to accommodate outside text labels on bars. Only adds padding
766+ // vertical bars with textposition 'outside' and cliponaxis 'true'
767+ // for now.
768+ //
769+ // This mitigates the most common scenario where a simple vertical
770+ // bar chart with textposition set to 'outside' experiences text
771+ // labels being cut off at the edge of the plot area.
772+ //
773+ // More complex scenarios (horizontal bars, multi-line text labels)
774+ // are not (yet) handled here, but could be in the future.
775+ function estimateExtraPaddingForText ( trace ) {
776+ if (
777+ trace . orientation === 'v' &&
778+ ( trace . text || trace . texttemplate ) &&
779+ trace . textposition == 'outside' &&
780+ trace . cliponaxis
781+ ) {
782+ // could count <br> elements here
783+ // but before that, need to make sure we are only
784+ // adding padding on the side(s) where it is needed
785+ return trace . outsidetextfont . size + TEXTPAD ;
786+ }
787+ return 0 ;
788+ }
789+
757790// Add an `_sMin` and `_sMax` value for each bar representing the min and max size value
758791// across all bars sharing the same position as that bar. These values are used for rounded
759792// bar corners, to carry rounding down to lower bars in the stack as needed.
0 commit comments