@@ -57,52 +57,57 @@ function setGroupPositions(gd, pa, sa, calcTraces) {
5757 if ( ! calcTraces . length ) return ;
5858
5959 var barmode = gd . _fullLayout . barmode ;
60- var overlay = ( barmode === 'overlay' ) ;
61- var group = ( barmode === 'group' ) ;
6260 var excluded ;
6361 var included ;
6462 var i , calcTrace , fullTrace ;
6563
6664 initBase ( gd , pa , sa , calcTraces ) ;
6765
68- if ( overlay ) {
69- setGroupPositionsInOverlayMode ( gd , pa , sa , calcTraces ) ;
70- } else if ( group ) {
71- // exclude from the group those traces for which the user set an offset
72- excluded = [ ] ;
73- included = [ ] ;
74- for ( i = 0 ; i < calcTraces . length ; i ++ ) {
75- calcTrace = calcTraces [ i ] ;
76- fullTrace = calcTrace [ 0 ] . trace ;
77-
78- if ( fullTrace . offset === undefined ) included . push ( calcTrace ) ;
79- else excluded . push ( calcTrace ) ;
80- }
66+ switch ( barmode ) {
67+ case 'overlay' :
68+ setGroupPositionsInOverlayMode ( gd , pa , sa , calcTraces ) ;
69+ break ;
70+
71+ case 'group' :
72+ // exclude from the group those traces for which the user set an offset
73+ excluded = [ ] ;
74+ included = [ ] ;
75+ for ( i = 0 ; i < calcTraces . length ; i ++ ) {
76+ calcTrace = calcTraces [ i ] ;
77+ fullTrace = calcTrace [ 0 ] . trace ;
78+
79+ if ( fullTrace . offset === undefined ) included . push ( calcTrace ) ;
80+ else excluded . push ( calcTrace ) ;
81+ }
8182
82- if ( included . length ) {
83- setGroupPositionsInGroupMode ( gd , pa , sa , included ) ;
84- }
85- if ( excluded . length ) {
86- setGroupPositionsInOverlayMode ( gd , pa , sa , excluded ) ;
87- }
88- } else {
89- // exclude from the stack those traces for which the user set a base
90- excluded = [ ] ;
91- included = [ ] ;
92- for ( i = 0 ; i < calcTraces . length ; i ++ ) {
93- calcTrace = calcTraces [ i ] ;
94- fullTrace = calcTrace [ 0 ] . trace ;
95-
96- if ( fullTrace . base === undefined ) included . push ( calcTrace ) ;
97- else excluded . push ( calcTrace ) ;
98- }
83+ if ( included . length ) {
84+ setGroupPositionsInGroupMode ( gd , pa , sa , included ) ;
85+ }
86+ if ( excluded . length ) {
87+ setGroupPositionsInOverlayMode ( gd , pa , sa , excluded ) ;
88+ }
89+ break ;
90+
91+ case 'stack' :
92+ case 'relative' :
93+ // exclude from the stack those traces for which the user set a base
94+ excluded = [ ] ;
95+ included = [ ] ;
96+ for ( i = 0 ; i < calcTraces . length ; i ++ ) {
97+ calcTrace = calcTraces [ i ] ;
98+ fullTrace = calcTrace [ 0 ] . trace ;
99+
100+ if ( fullTrace . base === undefined ) included . push ( calcTrace ) ;
101+ else excluded . push ( calcTrace ) ;
102+ }
99103
100- if ( included . length ) {
101- setGroupPositionsInStackOrRelativeMode ( gd , pa , sa , included ) ;
102- }
103- if ( excluded . length ) {
104- setGroupPositionsInOverlayMode ( gd , pa , sa , excluded ) ;
105- }
104+ if ( included . length ) {
105+ setGroupPositionsInStackOrRelativeMode ( gd , pa , sa , included ) ;
106+ }
107+ if ( excluded . length ) {
108+ setGroupPositionsInOverlayMode ( gd , pa , sa , excluded ) ;
109+ }
110+ break ;
106111 }
107112
108113 collectExtents ( calcTraces , pa ) ;
@@ -154,13 +159,15 @@ function initBase(gd, pa, sa, calcTraces) {
154159
155160function setGroupPositionsInOverlayMode ( gd , pa , sa , calcTraces ) {
156161 var barnorm = gd . _fullLayout . barnorm ;
157- var separateNegativeValues = false ;
158- var dontMergeOverlappingData = ! barnorm ;
159162
160163 // update position axis and set bar offsets and widths
161164 for ( var i = 0 ; i < calcTraces . length ; i ++ ) {
162165 var calcTrace = calcTraces [ i ] ;
163- var sieve = new Sieve ( [ calcTrace ] , separateNegativeValues , dontMergeOverlappingData ) ;
166+
167+ var sieve = new Sieve ( [ calcTrace ] , {
168+ sepNegVal : false ,
169+ overlapNoMerge : ! barnorm
170+ } ) ;
164171
165172 // set bar offsets and widths, and update position axis
166173 setOffsetAndWidth ( gd , pa , sieve ) ;
@@ -182,13 +189,19 @@ function setGroupPositionsInOverlayMode(gd, pa, sa, calcTraces) {
182189function setGroupPositionsInGroupMode ( gd , pa , sa , calcTraces ) {
183190 var fullLayout = gd . _fullLayout ;
184191 var barnorm = fullLayout . barnorm ;
185- var separateNegativeValues = false ;
186- var dontMergeOverlappingData = ! barnorm ;
187- var sieve = new Sieve ( calcTraces , separateNegativeValues , dontMergeOverlappingData ) ;
192+
193+ var sieve = new Sieve ( calcTraces , {
194+ sepNegVal : false ,
195+ overlapNoMerge : ! barnorm
196+ } ) ;
188197
189198 // set bar offsets and widths, and update position axis
190199 setOffsetAndWidthInGroupMode ( gd , pa , sieve ) ;
191200
201+ // relative-stack bars within the same trace that would otherwise
202+ // be hidden
203+ unhideBarsWithinTrace ( gd , sa , sieve ) ;
204+
192205 // set bar bases and sizes, and update size axis
193206 if ( barnorm ) {
194207 sieveBars ( gd , sa , sieve ) ;
@@ -201,12 +214,12 @@ function setGroupPositionsInGroupMode(gd, pa, sa, calcTraces) {
201214function setGroupPositionsInStackOrRelativeMode ( gd , pa , sa , calcTraces ) {
202215 var fullLayout = gd . _fullLayout ;
203216 var barmode = fullLayout . barmode ;
204- var stack = barmode === 'stack' ;
205- var relative = barmode === 'relative' ;
206217 var barnorm = fullLayout . barnorm ;
207- var separateNegativeValues = relative ;
208- var dontMergeOverlappingData = ! ( barnorm || stack || relative ) ;
209- var sieve = new Sieve ( calcTraces , separateNegativeValues , dontMergeOverlappingData ) ;
218+
219+ var sieve = new Sieve ( calcTraces , {
220+ sepNegVal : barmode === 'relative' ,
221+ overlapNoMerge : ! ( barnorm || barmode === 'stack' || barmode === 'relative' )
222+ } ) ;
210223
211224 // set bar offsets and widths, and update position axis
212225 setOffsetAndWidth ( gd , pa , sieve ) ;
@@ -563,7 +576,39 @@ function sieveBars(gd, sa, sieve) {
563576 for ( var j = 0 ; j < calcTrace . length ; j ++ ) {
564577 var bar = calcTrace [ j ] ;
565578
566- if ( bar . s !== BADNUM ) sieve . put ( bar . p , bar . b + bar . s ) ;
579+ if ( bar . s !== BADNUM ) {
580+ sieve . put ( bar . p , bar . b + bar . s ) ;
581+ }
582+ }
583+ }
584+ }
585+
586+ function unhideBarsWithinTrace ( gd , sa , sieve ) {
587+ var calcTraces = sieve . traces ;
588+
589+ for ( var i = 0 ; i < calcTraces . length ; i ++ ) {
590+ var calcTrace = calcTraces [ i ] ;
591+ var fullTrace = calcTrace [ 0 ] . trace ;
592+
593+ if ( fullTrace . base === undefined ) {
594+ var inTraceSieve = new Sieve ( [ calcTrace ] , {
595+ sepNegVal : true ,
596+ overlapNoMerge : true
597+ } ) ;
598+
599+ for ( var j = 0 ; j < calcTrace . length ; j ++ ) {
600+ var bar = calcTrace [ j ] ;
601+
602+ if ( bar . p !== BADNUM ) {
603+ // stack current bar and get previous sum
604+ var barBase = inTraceSieve . put ( bar . p , bar . b + bar . s ) ;
605+
606+ // if previous sum if non-zero, this means:
607+ // multiple bars have same starting point are potentially hidden,
608+ // shift them vertically so that all bars are visible by default
609+ if ( barBase ) bar . b = barBase ;
610+ }
611+ }
567612 }
568613 }
569614}
0 commit comments