@@ -111,6 +111,10 @@ function setGroupPositions(gd, pa, sa, calcTraces, opts) {
111111 else excluded . push ( calcTrace ) ;
112112 }
113113
114+ // If any trace in `included` has a cornerradius, set cornerradius of all bars
115+ // in `included` to match the first trace which has a cornerradius
116+ standardizeCornerradius ( included ) ;
117+
114118 if ( included . length ) {
115119 setGroupPositionsInStackOrRelativeMode ( gd , pa , sa , included , opts ) ;
116120 }
@@ -119,10 +123,57 @@ function setGroupPositions(gd, pa, sa, calcTraces, opts) {
119123 }
120124 break ;
121125 }
122-
126+ setCornerradius ( calcTraces ) ;
123127 collectExtents ( calcTraces , pa ) ;
124128}
125129
130+ // Set cornerradiusvalue and cornerradiusform in calcTraces[0].t
131+ function setCornerradius ( calcTraces ) {
132+ var i , calcTrace , fullTrace , t , cr , crValue , crForm ;
133+
134+ for ( i = 0 ; i < calcTraces . length ; i ++ ) {
135+ calcTrace = calcTraces [ i ] ;
136+ fullTrace = calcTrace [ 0 ] . trace ;
137+ t = calcTrace [ 0 ] . t ;
138+
139+ if ( t . cornerradiusvalue === undefined ) {
140+ cr = fullTrace . marker ? fullTrace . marker . cornerradius : undefined ;
141+ if ( cr !== undefined ) {
142+ crValue = isNumeric ( cr ) ? + cr : + cr . slice ( 0 , - 1 ) ;
143+ crForm = isNumeric ( cr ) ? 'px' : '%' ;
144+ t . cornerradiusvalue = crValue ;
145+ t . cornerradiusform = crForm ;
146+ }
147+ }
148+ }
149+ }
150+
151+ // Make sure all traces in a stack use the same cornerradius
152+ function standardizeCornerradius ( calcTraces ) {
153+ if ( calcTraces . length < 2 ) return ;
154+ var i , calcTrace , fullTrace , t ;
155+ var cr , crValue , crForm ;
156+ for ( i = 0 ; i < calcTraces . length ; i ++ ) {
157+ calcTrace = calcTraces [ i ] ;
158+ fullTrace = calcTrace [ 0 ] . trace ;
159+ cr = fullTrace . marker ? fullTrace . marker . cornerradius : undefined ;
160+ if ( cr !== undefined ) break ;
161+ }
162+ // If any trace has cornerradius, store first cornerradius
163+ // in calcTrace[0].t so that all traces in stack use same cornerradius
164+ if ( cr !== undefined ) {
165+ crValue = isNumeric ( cr ) ? + cr : + cr . slice ( 0 , - 1 ) ;
166+ crForm = isNumeric ( cr ) ? 'px' : '%' ;
167+ for ( i = 0 ; i < calcTraces . length ; i ++ ) {
168+ calcTrace = calcTraces [ i ] ;
169+ t = calcTrace [ 0 ] . t ;
170+
171+ t . cornerradiusvalue = crValue ;
172+ t . cornerradiusform = crForm ;
173+ }
174+ }
175+ }
176+
126177function initBase ( sa , calcTraces ) {
127178 var i , j ;
128179
@@ -713,6 +764,23 @@ function normalizeBars(sa, sieve, opts) {
713764 }
714765}
715766
767+ // Add an `_sMin` and `_sMax` value for each bar representing the min and max size value
768+ // across all bars sharing the same position as that bar. These values are used for rounded
769+ // bar corners, to carry rounding down to lower bars in the stack as needed.
770+ function setHelperValuesForRoundedCorners ( calcTraces , sMinByPos , sMaxByPos , pa ) {
771+ var pLetter = getAxisLetter ( pa ) ;
772+ // Set `_sMin` and `_sMax` value for each bar
773+ for ( var i = 0 ; i < calcTraces . length ; i ++ ) {
774+ var calcTrace = calcTraces [ i ] ;
775+ for ( var j = 0 ; j < calcTrace . length ; j ++ ) {
776+ var bar = calcTrace [ j ] ;
777+ var pos = bar [ pLetter ] ;
778+ bar . _sMin = sMinByPos [ pos ] ;
779+ bar . _sMax = sMaxByPos [ pos ] ;
780+ }
781+ }
782+ }
783+
716784// find the full position span of bars at each position
717785// for use by hover, to ensure labels move in if bars are
718786// narrower than the space they're in.
@@ -745,6 +813,18 @@ function collectExtents(calcTraces, pa) {
745813 return String ( Math . round ( roundFactor * ( p - pMin ) ) ) ;
746814 } ;
747815
816+ // Find min and max size axis extent for each position
817+ // This is used for rounded bar corners, to carry rounding
818+ // down to lower bars in the case of stacked bars
819+ var sMinByPos = { } ;
820+ var sMaxByPos = { } ;
821+
822+ // Check whether any trace has rounded corners
823+ var anyTraceHasCornerradius = calcTraces . some ( function ( x ) {
824+ var trace = x [ 0 ] . trace ;
825+ return 'marker' in trace && trace . marker . cornerradius ;
826+ } ) ;
827+
748828 for ( i = 0 ; i < calcTraces . length ; i ++ ) {
749829 cd = calcTraces [ i ] ;
750830 cd [ 0 ] . t . extents = extents ;
@@ -770,8 +850,19 @@ function collectExtents(calcTraces, pa) {
770850 di . p1 = di . p0 + di . w ;
771851 di . s0 = di . b ;
772852 di . s1 = di . s0 + di . s ;
853+
854+ if ( anyTraceHasCornerradius ) {
855+ var sMin = Math . min ( di . s0 , di . s1 ) || 0 ;
856+ var sMax = Math . max ( di . s0 , di . s1 ) || 0 ;
857+ var pos = di [ pLetter ] ;
858+ sMinByPos [ pos ] = ( pos in sMinByPos ) ? Math . min ( sMinByPos [ pos ] , sMin ) : sMin ;
859+ sMaxByPos [ pos ] = ( pos in sMaxByPos ) ? Math . max ( sMaxByPos [ pos ] , sMax ) : sMax ;
860+ }
773861 }
774862 }
863+ if ( anyTraceHasCornerradius ) {
864+ setHelperValuesForRoundedCorners ( calcTraces , sMinByPos , sMaxByPos , pa ) ;
865+ }
775866}
776867
777868function getAxisLetter ( ax ) {
0 commit comments