@@ -10,6 +10,7 @@ var getAxisGroup = require('../../plots/cartesian/constraints').getAxisGroup;
1010var Sieve = require ( './sieve.js' ) ;
1111
1212var TEXTPAD = require ( './constants' ) . TEXTPAD ;
13+ var BR_TAG_ALL = require ( '../../lib/svg_text_utils' ) . BR_TAG_ALL ;
1314
1415/*
1516 * Bar chart stacking/grouping positioning and autoscaling calculations
@@ -567,11 +568,12 @@ function setBaseAndTop(sa, sieve) {
567568 }
568569 }
569570
570- const textPadding = estimateExtraPaddingForText ( fullTrace ) ;
571+ const textPadding = estimateExtraPaddingForText ( fullTrace , calcTrace ) ;
571572 fullTrace . _extremes [ sa . _id ] = Axes . findExtremes ( sa , pts , {
572573 tozero : tozero ,
573574 padded : true ,
574- ppad : textPadding
575+ ppadplus : textPadding . ppadplus ,
576+ ppadminus : textPadding . ppadminus
575577 } ) ;
576578 }
577579}
@@ -641,7 +643,7 @@ function stackBars(sa, sieve, opts) {
641643 }
642644 }
643645
644- const textPadding = estimateExtraPaddingForText ( fullTrace ) ;
646+ const textPadding = estimateExtraPaddingForText ( fullTrace , calcTrace ) ;
645647
646648 // if barnorm is set, let normalizeBars update the axis range
647649 if ( ! opts . norm ) {
@@ -650,7 +652,8 @@ function stackBars(sa, sieve, opts) {
650652 // so set tozero:true always!
651653 tozero : true ,
652654 padded : true ,
653- ppad : textPadding
655+ ppadplus : textPadding . ppadplus ,
656+ ppadminus : textPadding . ppadminus
654657 } ) ;
655658 }
656659 }
@@ -754,16 +757,20 @@ function normalizeBars(sa, sieve, opts) {
754757 }
755758 }
756759
760+ const textPadding = estimateExtraPaddingForText ( fullTrace , calcTrace ) ;
761+
757762 fullTrace . _extremes [ sa . _id ] = Axes . findExtremes ( sa , pts , {
758763 tozero : tozero ,
759- padded : padded
764+ padded : padded ,
765+ ppadplus : textPadding . ppadplus ,
766+ ppadminus : textPadding . ppadminus
760767 } ) ;
761768 }
762769}
763770
764771// Returns a very lightweight estimate of extra padding (in pixels)
765772// needed to accommodate outside text labels on bars. Only adds padding
766- // vertical bars with textposition 'outside' and cliponaxis 'true '
773+ // vertical bars with textposition 'outside' and textangle 0 or 'auto '
767774// for now.
768775//
769776// This mitigates the most common scenario where a simple vertical
@@ -772,17 +779,31 @@ function normalizeBars(sa, sieve, opts) {
772779//
773780// More complex scenarios (horizontal bars, multi-line text labels)
774781// are not (yet) handled here, but could be in the future.
775- function estimateExtraPaddingForText ( trace ) {
782+ // Returns an object with ppadplus and ppadminus values,
783+ // to be passed into Axes.findExtremes.
784+ function estimateExtraPaddingForText ( trace , calcTrace ) {
776785 if (
777786 trace . orientation === 'v' &&
778787 ( trace . text || trace . texttemplate ) &&
779788 trace . textposition == 'outside' &&
780- trace . cliponaxis
789+ ( trace . textangle == 'auto' || trace . textangle == 0 )
781790 ) {
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 ;
791+ // count number of lines by counting <br> elements
792+ function countLines ( text ) {
793+ const BR_TAG_ALL = / < b r \s * \/ ? > / gi;
794+ return ( text . match ( BR_TAG_ALL ) || [ ] ) . length + 1 ;
795+ }
796+ var nLines = trace . texttemplate
797+ ? countLines ( trace . texttemplate )
798+ : Math . max ( ...trace . text . map ( ( t ) => countLines ( t ) ) ) ;
799+
800+ const padAmount = trace . outsidetextfont . size * nLines + TEXTPAD ;
801+ return {
802+ // Yes, I know this looks backwards from what it should be,
803+ // but it works like this
804+ ppadplus : calcTrace . some ( ( bar ) => bar . s < 0 ) ? padAmount : 0 ,
805+ ppadminus : calcTrace . some ( ( bar ) => bar . s >= 0 ) ? padAmount : 0
806+ } ;
786807 }
787808 return 0 ;
788809}
0 commit comments