@@ -57,52 +57,57 @@ function setGroupPositions(gd, pa, sa, calcTraces) {
57
57
if ( ! calcTraces . length ) return ;
58
58
59
59
var barmode = gd . _fullLayout . barmode ;
60
- var overlay = ( barmode === 'overlay' ) ;
61
- var group = ( barmode === 'group' ) ;
62
60
var excluded ;
63
61
var included ;
64
62
var i , calcTrace , fullTrace ;
65
63
66
64
initBase ( gd , pa , sa , calcTraces ) ;
67
65
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
+ }
81
82
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
+ }
99
103
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 ;
106
111
}
107
112
108
113
collectExtents ( calcTraces , pa ) ;
@@ -154,13 +159,15 @@ function initBase(gd, pa, sa, calcTraces) {
154
159
155
160
function setGroupPositionsInOverlayMode ( gd , pa , sa , calcTraces ) {
156
161
var barnorm = gd . _fullLayout . barnorm ;
157
- var separateNegativeValues = false ;
158
- var dontMergeOverlappingData = ! barnorm ;
159
162
160
163
// update position axis and set bar offsets and widths
161
164
for ( var i = 0 ; i < calcTraces . length ; i ++ ) {
162
165
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
+ } ) ;
164
171
165
172
// set bar offsets and widths, and update position axis
166
173
setOffsetAndWidth ( gd , pa , sieve ) ;
@@ -182,13 +189,19 @@ function setGroupPositionsInOverlayMode(gd, pa, sa, calcTraces) {
182
189
function setGroupPositionsInGroupMode ( gd , pa , sa , calcTraces ) {
183
190
var fullLayout = gd . _fullLayout ;
184
191
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
+ } ) ;
188
197
189
198
// set bar offsets and widths, and update position axis
190
199
setOffsetAndWidthInGroupMode ( gd , pa , sieve ) ;
191
200
201
+ // relative-stack bars within the same trace that would otherwise
202
+ // be hidden
203
+ unhideBarsWithinTrace ( gd , sa , sieve ) ;
204
+
192
205
// set bar bases and sizes, and update size axis
193
206
if ( barnorm ) {
194
207
sieveBars ( gd , sa , sieve ) ;
@@ -201,12 +214,12 @@ function setGroupPositionsInGroupMode(gd, pa, sa, calcTraces) {
201
214
function setGroupPositionsInStackOrRelativeMode ( gd , pa , sa , calcTraces ) {
202
215
var fullLayout = gd . _fullLayout ;
203
216
var barmode = fullLayout . barmode ;
204
- var stack = barmode === 'stack' ;
205
- var relative = barmode === 'relative' ;
206
217
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
+ } ) ;
210
223
211
224
// set bar offsets and widths, and update position axis
212
225
setOffsetAndWidth ( gd , pa , sieve ) ;
@@ -563,7 +576,39 @@ function sieveBars(gd, sa, sieve) {
563
576
for ( var j = 0 ; j < calcTrace . length ; j ++ ) {
564
577
var bar = calcTrace [ j ] ;
565
578
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
+ }
567
612
}
568
613
}
569
614
}
0 commit comments