Skip to content

Commit a3fbabf

Browse files
my-tienstephprobst
authored andcommitted
For bar traces make offsetgroup work with barmode 'stacked' and 'relative'
1 parent ef721c4 commit a3fbabf

File tree

5 files changed

+73
-54
lines changed

5 files changed

+73
-54
lines changed

src/traces/bar/cross_trace_calc.js

+10-46
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function setGroupPositions(gd, pa, sa, calcTraces, opts) {
7575

7676
switch(opts.mode) {
7777
case 'overlay':
78-
setGroupPositionsInOverlayMode(pa, sa, calcTraces, opts);
78+
setGroupPositionsInOverlayMode(gd, pa, sa, calcTraces, opts);
7979
break;
8080

8181
case 'group':
@@ -94,7 +94,7 @@ function setGroupPositions(gd, pa, sa, calcTraces, opts) {
9494
setGroupPositionsInGroupMode(gd, pa, sa, included, opts);
9595
}
9696
if(excluded.length) {
97-
setGroupPositionsInOverlayMode(pa, sa, excluded, opts);
97+
setGroupPositionsInOverlayMode(gd, pa, sa, excluded, opts);
9898
}
9999
break;
100100

@@ -119,7 +119,7 @@ function setGroupPositions(gd, pa, sa, calcTraces, opts) {
119119
setGroupPositionsInStackOrRelativeMode(gd, pa, sa, included, opts);
120120
}
121121
if(excluded.length) {
122-
setGroupPositionsInOverlayMode(pa, sa, excluded, opts);
122+
setGroupPositionsInOverlayMode(gd, pa, sa, excluded, opts);
123123
}
124124
break;
125125
}
@@ -217,7 +217,7 @@ function initBase(sa, calcTraces) {
217217
}
218218
}
219219

220-
function setGroupPositionsInOverlayMode(pa, sa, calcTraces, opts) {
220+
function setGroupPositionsInOverlayMode(gd, pa, sa, calcTraces, opts) {
221221
// update position axis and set bar offsets and widths
222222
for(var i = 0; i < calcTraces.length; i++) {
223223
var calcTrace = calcTraces[i];
@@ -229,7 +229,7 @@ function setGroupPositionsInOverlayMode(pa, sa, calcTraces, opts) {
229229
});
230230

231231
// set bar offsets and widths, and update position axis
232-
setOffsetAndWidth(pa, sieve, opts);
232+
setOffsetAndWidth(gd, pa, sieve, opts);
233233

234234
// set bar bases and sizes, and update size axis
235235
//
@@ -253,7 +253,7 @@ function setGroupPositionsInGroupMode(gd, pa, sa, calcTraces, opts) {
253253
});
254254

255255
// set bar offsets and widths, and update position axis
256-
setOffsetAndWidthInGroupMode(gd, pa, sieve, opts);
256+
setOffsetAndWidth(gd, pa, sieve, opts);
257257

258258
// relative-stack bars within the same trace that would otherwise
259259
// be hidden
@@ -276,7 +276,7 @@ function setGroupPositionsInStackOrRelativeMode(gd, pa, sa, calcTraces, opts) {
276276
});
277277

278278
// set bar offsets and widths, and update position axis
279-
setOffsetAndWidth(pa, sieve, opts);
279+
setOffsetAndWidth(gd, pa, sieve, opts);
280280

281281
// set bar bases and sizes, and update size axis
282282
stackBars(sa, sieve, opts);
@@ -300,43 +300,7 @@ function setGroupPositionsInStackOrRelativeMode(gd, pa, sa, calcTraces, opts) {
300300
if(opts.norm) normalizeBars(sa, sieve, opts);
301301
}
302302

303-
function setOffsetAndWidth(pa, sieve, opts) {
304-
var minDiff = sieve.minDiff;
305-
var calcTraces = sieve.traces;
306-
307-
// set bar offsets and widths
308-
var barGroupWidth = minDiff * (1 - opts.gap);
309-
var barWidthPlusGap = barGroupWidth;
310-
var barWidth = barWidthPlusGap * (1 - (opts.groupgap || 0));
311-
312-
// computer bar group center and bar offset
313-
var offsetFromCenter = -barWidth / 2;
314-
315-
for(var i = 0; i < calcTraces.length; i++) {
316-
var calcTrace = calcTraces[i];
317-
var t = calcTrace[0].t;
318-
319-
// store bar width and offset for this trace
320-
t.barwidth = barWidth;
321-
t.poffset = offsetFromCenter;
322-
t.bargroupwidth = barGroupWidth;
323-
t.bardelta = minDiff;
324-
}
325-
326-
// stack bars that only differ by rounding
327-
sieve.binWidth = calcTraces[0][0].t.barwidth / 100;
328-
329-
// if defined, apply trace offset and width
330-
applyAttributes(sieve);
331-
332-
// store the bar center in each calcdata item
333-
setBarCenterAndWidth(pa, sieve);
334-
335-
// update position axes
336-
updatePositionAxis(pa, sieve);
337-
}
338-
339-
function setOffsetAndWidthInGroupMode(gd, pa, sieve, opts) {
303+
function setOffsetAndWidth(gd, pa, sieve, opts) {
340304
var fullLayout = gd._fullLayout;
341305
var positions = sieve.positions;
342306
var distinctPositions = sieve.distinctPositions;
@@ -615,6 +579,7 @@ function stackBars(sa, sieve, opts) {
615579

616580
isFunnel = (fullTrace.type === 'funnel');
617581

582+
var offset = calcTrace[0].t.poffset;
618583
var pts = [];
619584

620585
for(j = 0; j < calcTrace.length; j++) {
@@ -629,8 +594,7 @@ function stackBars(sa, sieve, opts) {
629594
value = bar.s + bar.b;
630595
}
631596

632-
var base = sieve.put(bar.p, value);
633-
597+
var base = sieve.put(bar.p + offset, value);
634598
var top = base + value;
635599

636600
// store the bar base and top in each calcdata item

src/traces/bar/defaults.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ function crossTraceDefaults(fullData, fullLayout) {
8080
traceOut.marker.cornerradius = validateCornerradius(r);
8181
}
8282

83-
if(fullLayout.barmode === 'group') {
84-
handleGroupingDefaults(traceIn, traceOut, fullLayout, coerce);
85-
}
83+
handleGroupingDefaults(fullLayout.barmode, traceIn, traceOut, fullLayout, coerce);
8684
}
8785
}
8886
}

src/traces/bar/layout_defaults.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module.exports = function(layoutIn, layoutOut, fullData) {
1919
var usedSubplots = {};
2020

2121
var mode = coerce('barmode');
22+
var isGroup = mode === 'group';
2223

2324
for(var i = 0; i < fullData.length; i++) {
2425
var trace = fullData[i];
@@ -27,10 +28,17 @@ module.exports = function(layoutIn, layoutOut, fullData) {
2728

2829
// if we have at least 2 grouped bar traces on the same subplot,
2930
// we should default to a gap anyway, even if the data is histograms
30-
if(mode === 'group') {
31-
var subploti = trace.xaxis + trace.yaxis;
31+
var subploti = trace.xaxis + trace.yaxis;
32+
if(isGroup) {
33+
// with barmode group, bars are grouped next to each other when sharing the same axes
3234
if(usedSubplots[subploti]) gappedAnyway = true;
3335
usedSubplots[subploti] = true;
36+
} else {
37+
// with other barmodes bars are grouped next to each other when sharing the same axes
38+
// and using different offsetgroups
39+
subploti += trace._input.offsetgroup;
40+
if(!usedSubplots[subploti]) gappedAnyway = true;
41+
usedSubplots[subploti] = true;
3442
}
3543

3644
if(trace.visible && trace.type === 'histogram') {

src/traces/scatter/grouping_defaults.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
var getAxisGroup = require('../../plots/cartesian/constraints').getAxisGroup;
44

5-
module.exports = function handleGroupingDefaults(traceIn, traceOut, fullLayout, coerce) {
5+
module.exports = function handleGroupingDefaults(barmode, traceIn, traceOut, fullLayout, coerce) {
66
var orientation = traceOut.orientation;
77
// N.B. grouping is done across all trace types that support it
88
var posAxId = traceOut[{v: 'x', h: 'y'}[orientation] + 'axis'];
@@ -29,8 +29,9 @@ module.exports = function handleGroupingDefaults(traceIn, traceOut, fullLayout,
2929
var offsetgroup = coerce('offsetgroup');
3030
var offsetGroups = alignmentGroupOpts.offsetGroups;
3131
var offsetGroupOpts = offsetGroups[offsetgroup];
32-
33-
if(offsetgroup) {
32+
// in barmode 'group', traces without offsetgroup receive their own offsetgroup
33+
// in other barmodes, traces without offsetgroup are assigned to the same offset group
34+
if(barmode !== 'group' || offsetgroup) {
3435
if(!offsetGroupOpts) {
3536
offsetGroupOpts = offsetGroups[offsetgroup] = {
3637
offsetIndex: Object.keys(offsetGroups).length
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"data": [
3+
{
4+
"type": "bar",
5+
"x": [ "A", "B", "C"],
6+
"y": [ 10, 10, 10 ],
7+
"offsetgroup": 1,
8+
"hovertext": "offsetgroup: 1"
9+
},
10+
{
11+
"type": "bar",
12+
"x": [ "A", "B", "C"],
13+
"y": [ 20, 20, 20 ],
14+
"offsetgroup": 1,
15+
"hovertext": "offsetgroup: 1"
16+
},
17+
{
18+
"type": "bar",
19+
"x": [ "A", "B", "C"],
20+
"y": [ 30, 30, 30 ],
21+
"offsetgroup": 2,
22+
"hovertext": "offsetgroup: 2"
23+
},
24+
{
25+
"type": "bar",
26+
"x": [ "A", "B", "C"],
27+
"y": [ 40, 40, 40 ],
28+
"offsetgroup": 2,
29+
"hovertext": "offsetgroup: 2"
30+
},
31+
{
32+
"type": "bar",
33+
"x": [ "A", "B", "C"],
34+
"y": [ -50, 50, 50 ],
35+
"offsetgroup": 2,
36+
"hovertext": "offsetgroup: 2"
37+
}
38+
],
39+
"layout": {
40+
"width": 600,
41+
"showlegend": false,
42+
"barmode": "relative",
43+
"title": {
44+
"text": "Separately stacked bars with barmode 'relative'"
45+
}
46+
}
47+
}
48+

0 commit comments

Comments
 (0)