Skip to content

Commit a7ca755

Browse files
committed
bar: add functions stackBars and normalizeBars
* Renamed setBaseAndSize to stackBars. * Refactor code to normalize bars into function normalizeBars.
1 parent 3b87e85 commit a7ca755

File tree

1 file changed

+99
-90
lines changed

1 file changed

+99
-90
lines changed

src/traces/bar/set_positions.js

+99-90
Original file line numberDiff line numberDiff line change
@@ -81,23 +81,27 @@ function setGroupPositionsInOverlayMode(gd, pa, sa, traces) {
8181
minDiff = sieve.minDiff,
8282
distinctPositions = sieve.distinctPositions;
8383

84+
// set bar offsets and widths
8485
setOffsetAndWidth(gd, pa, sieve);
8586

87+
// update position axis
8688
Axes.minDtick(pa, minDiff, distinctPositions[0]);
8789
Axes.expand(pa, distinctPositions, {vpad: minDiff / 2});
88-
});
89-
90-
// update size axis and set bar bases and sizes
91-
//
92-
// make sure the size axis includes zero,
93-
// along with the tops of each bar,
94-
// and store these bar tops in calcdata
95-
var sLetter = getAxisLetter(sa),
96-
fs = function(v) { v[sLetter] = v.s; return v.s; };
9790

98-
for(var i = 0; i < traces.length; i++) {
99-
Axes.expand(sa, traces[i].map(fs), {tozero: true, padded: true});
100-
}
91+
// update size axis and set bar bases and sizes
92+
if(barnorm) {
93+
stackBars(gd, sa, sieve);
94+
}
95+
else {
96+
// make sure the size axis includes zero,
97+
// along with the tops of each bar,
98+
// and store these bar tops in calcdata
99+
var sLetter = getAxisLetter(sa),
100+
fs = function(v) { v[sLetter] = v.s; return v.s; };
101+
102+
Axes.expand(sa, trace.map(fs), {tozero: true, padded: true});
103+
}
104+
});
101105
}
102106

103107

@@ -119,8 +123,21 @@ function setGroupPositionsInGroupMode(gd, pa, sa, traces) {
119123
Axes.minDtick(pa, minDiff, distinctPositions[0]);
120124
Axes.expand(pa, distinctPositions, {vpad: minDiff / 2});
121125

122-
// set bar bases and sizes
123-
setBaseAndSize(gd, sa, sieve);
126+
// update size axis and set bar bases and sizes
127+
if(barnorm) {
128+
stackBars(gd, sa, sieve);
129+
}
130+
else {
131+
// make sure the size axis includes zero,
132+
// along with the tops of each bar,
133+
// and store these bar tops in calcdata
134+
var sLetter = getAxisLetter(sa),
135+
fs = function(v) { v[sLetter] = v.s; return v.s; };
136+
137+
for(var i = 0; i < traces.length; i++) {
138+
Axes.expand(sa, traces[i].map(fs), {tozero: true, padded: true});
139+
}
140+
}
124141
}
125142

126143

@@ -146,7 +163,7 @@ function setGroupPositionsInStackOrRelativeMode(gd, pa, sa, traces) {
146163
Axes.expand(pa, distinctPositions, {vpad: minDiff / 2});
147164

148165
// set bar bases and sizes
149-
setBaseAndSize(gd, sa, sieve);
166+
stackBars(gd, sa, sieve);
150167
}
151168

152169

@@ -229,7 +246,7 @@ function setOffsetAndWidthInGroupMode(gd, pa, sieve) {
229246
}
230247

231248

232-
function setBaseAndSize(gd, sa, sieve) {
249+
function stackBars(gd, sa, sieve) {
233250
var fullLayout = gd._fullLayout,
234251
sLetter = getAxisLetter(sa),
235252
traces = sieve.traces,
@@ -241,96 +258,88 @@ function setBaseAndSize(gd, sa, sieve) {
241258
norm = fullLayout.barnorm;
242259

243260
// bar size range and stacking calculation
244-
if(stack || relative || norm) {
245-
// for stacked bars, we need to evaluate every step in every
246-
// stack, because negative bars mean the extremes could be
247-
// anywhere
248-
// also stores the base (b) of each bar in calcdata
249-
// so we don't have to redo this later
250-
var sMax = sa.l2c(sa.c2l(0)),
251-
sMin = sMax,
252-
barEnd;
253-
254-
// stack bars that only differ by rounding
255-
sieve.binWidth = traces[0][0].t.barwidth / 100;
256-
257-
for(i = 0; i < traces.length; i++) {
258-
trace = traces[i];
259-
260-
for(j = 0; j < trace.length; j++) {
261-
bar = trace[j];
262-
263-
// skip over bars with no size,
264-
// so that we don't try to stack them
265-
if(!isNumeric(bar.s)) continue;
266-
267-
// stack current bar and get previous sum
268-
var previousSum = sieve.put(bar.p, bar.s);
269-
270-
if(stack || relative) bar.b = previousSum;
271-
barEnd = bar.b + bar.s;
272-
273-
// store the bar top in each calcdata item
274-
if(stack || relative) {
275-
bar[sLetter] = barEnd;
276-
if(!norm && isNumeric(sa.c2l(barEnd))) {
277-
sMax = Math.max(sMax, barEnd);
278-
sMin = Math.min(sMin, barEnd);
279-
}
280-
}
281-
}
282-
}
261+
// for stacked bars, we need to evaluate every step in every
262+
// stack, because negative bars mean the extremes could be
263+
// anywhere
264+
// also stores the base (b) of each bar in calcdata
265+
// so we don't have to redo this later
266+
var sMax = sa.l2c(sa.c2l(0)),
267+
sMin = sMax;
283268

284-
var padded = true;
269+
// stack bars that only differ by rounding
270+
sieve.binWidth = traces[0][0].t.barwidth / 100;
285271

286-
if(norm) {
287-
padded = false;
288-
289-
var sTop = (norm === 'fraction') ? 1 : 100,
290-
sTiny = sTop / 1e9; // in case of rounding error in sum
291-
292-
sMin = 0;
293-
sMax = (stack) ? sTop : 0;
272+
for(i = 0; i < traces.length; i++) {
273+
trace = traces[i];
294274

295-
for(i = 0; i < traces.length; i++) {
296-
trace = traces[i];
275+
for(j = 0; j < trace.length; j++) {
276+
bar = trace[j];
297277

298-
for(j = 0; j < trace.length; j++) {
299-
bar = trace[j];
278+
// skip over bars with no size,
279+
// so that we don't try to stack them
280+
if(!isNumeric(bar.s)) continue;
300281

301-
var scale = Math.abs(sTop / sieve.get(bar.p, bar.s));
282+
// stack current bar and get previous sum
283+
var previousSum = sieve.put(bar.p, bar.s);
302284

303-
bar.b *= scale;
304-
bar.s *= scale;
305-
barEnd = bar.b + bar.s;
306-
bar[sLetter] = barEnd;
285+
if(stack || relative) bar.b = previousSum;
307286

308-
if(isNumeric(sa.c2l(barEnd))) {
309-
if(barEnd < sMin - sTiny) {
310-
padded = true;
311-
sMin = barEnd;
312-
}
313-
if(barEnd > sMax + sTiny) {
314-
padded = true;
315-
sMax = barEnd;
316-
}
317-
}
287+
// store the bar top in each calcdata item
288+
if(stack || relative) {
289+
var barEnd = bar.b + bar.s;
290+
bar[sLetter] = barEnd;
291+
if(!norm && isNumeric(sa.c2l(barEnd))) {
292+
sMax = Math.max(sMax, barEnd);
293+
sMin = Math.min(sMin, barEnd);
318294
}
319295
}
320296
}
297+
}
321298

322-
Axes.expand(sa, [sMin, sMax], {tozero: true, padded: padded});
299+
if(norm) {
300+
normalizeBars(gd, sa, sieve);
323301
}
324302
else {
325-
// for grouped or overlaid bars, just make sure zero is
326-
// included, along with the tops of each bar, and store
327-
// these bar tops in calcdata
328-
var fs = function(v) { v[sLetter] = v.s; return v.s; };
303+
Axes.expand(sa, [sMin, sMax], {tozero: true, padded: true});
304+
}
305+
}
329306

330-
for(i = 0; i < traces.length; i++) {
331-
Axes.expand(sa, traces[i].map(fs), {tozero: true, padded: true});
307+
308+
function normalizeBars(gd, sa, sieve) {
309+
var traces = sieve.traces,
310+
sLetter = getAxisLetter(sa),
311+
sTop = (gd._fullLayout.barnorm === 'fraction') ? 1 : 100,
312+
sTiny = sTop / 1e9, // in case of rounding error in sum
313+
sMin = 0,
314+
sMax = (gd._fullLayout.barmode === 'stack') ? sTop : 0,
315+
padded = false;
316+
317+
for(var i = 0; i < traces.length; i++) {
318+
var trace = traces[i];
319+
320+
for(var j = 0; j < trace.length; j++) {
321+
var bar = trace[j],
322+
scale = Math.abs(sTop / sieve.get(bar.p, bar.s));
323+
324+
bar.b *= scale;
325+
bar.s *= scale;
326+
var barEnd = bar.b + bar.s;
327+
bar[sLetter] = barEnd;
328+
329+
if(isNumeric(sa.c2l(barEnd))) {
330+
if(barEnd < sMin - sTiny) {
331+
padded = true;
332+
sMin = barEnd;
333+
}
334+
if(barEnd > sMax + sTiny) {
335+
padded = true;
336+
sMax = barEnd;
337+
}
338+
}
332339
}
333340
}
341+
342+
Axes.expand(sa, [sMin, sMax], {tozero: true, padded: padded});
334343
}
335344

336345

0 commit comments

Comments
 (0)