Skip to content

Commit b5f5bef

Browse files
committed
bar: Implement layout.barbase
* Fix: do not normalise bars with no size * Fix: update minDtick if barmode is group and bars overlap. Closes plotly#475
1 parent a7ca755 commit b5f5bef

File tree

3 files changed

+54
-28
lines changed

3 files changed

+54
-28
lines changed

src/traces/bar/layout_attributes.js

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111

1212
module.exports = {
13+
barbase: {
14+
valType: 'number',
15+
dflt: 0,
16+
role: 'style',
17+
description: 'Sets where the bar base is drawn (in axis units).'
18+
},
1319
barmode: {
1420
valType: 'enumerated',
1521
values: ['stack', 'group', 'overlay', 'relative'],

src/traces/bar/layout_defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ module.exports = function(layoutIn, layoutOut, fullData) {
4848

4949
if(!hasBars) return;
5050

51+
coerce('barbase');
52+
5153
var mode = coerce('barmode');
5254
if(mode !== 'overlay') coerce('barnorm');
5355

src/traces/bar/set_positions.js

+46-28
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,12 @@ function setGroupPositionsInOverlayMode(gd, pa, sa, traces) {
7676
// update position axis and set bar offsets and widths
7777
traces.forEach(function(trace) {
7878
var sieve = new Sieve(
79-
[trace], separateNegativeValues, dontMergeOverlappingData
80-
),
81-
minDiff = sieve.minDiff,
82-
distinctPositions = sieve.distinctPositions;
79+
[trace], separateNegativeValues, dontMergeOverlappingData
80+
);
8381

84-
// set bar offsets and widths
82+
// set bar offsets and widths and update position axis
8583
setOffsetAndWidth(gd, pa, sieve);
8684

87-
// update position axis
88-
Axes.minDtick(pa, minDiff, distinctPositions[0]);
89-
Axes.expand(pa, distinctPositions, {vpad: minDiff / 2});
90-
9185
// update size axis and set bar bases and sizes
9286
if(barnorm) {
9387
stackBars(gd, sa, sieve);
@@ -102,6 +96,8 @@ function setGroupPositionsInOverlayMode(gd, pa, sa, traces) {
10296
Axes.expand(sa, trace.map(fs), {tozero: true, padded: true});
10397
}
10498
});
99+
100+
applyBarbase(gd, sa, traces);
105101
}
106102

107103

@@ -112,17 +108,11 @@ function setGroupPositionsInGroupMode(gd, pa, sa, traces) {
112108
dontMergeOverlappingData = !barnorm,
113109
sieve = new Sieve(
114110
traces, separateNegativeValues, dontMergeOverlappingData
115-
),
116-
minDiff = sieve.minDiff,
117-
distinctPositions = sieve.distinctPositions;
111+
);
118112

119-
// set bar offsets and widths
113+
// set bar offsets and widths and update position axis
120114
setOffsetAndWidthInGroupMode(gd, pa, sieve);
121115

122-
// update position axis
123-
Axes.minDtick(pa, minDiff, distinctPositions[0]);
124-
Axes.expand(pa, distinctPositions, {vpad: minDiff / 2});
125-
126116
// update size axis and set bar bases and sizes
127117
if(barnorm) {
128118
stackBars(gd, sa, sieve);
@@ -138,6 +128,8 @@ function setGroupPositionsInGroupMode(gd, pa, sa, traces) {
138128
Axes.expand(sa, traces[i].map(fs), {tozero: true, padded: true});
139129
}
140130
}
131+
132+
applyBarbase(gd, sa, traces);
141133
}
142134

143135

@@ -151,18 +143,12 @@ function setGroupPositionsInStackOrRelativeMode(gd, pa, sa, traces) {
151143
dontMergeOverlappingData = !(barnorm || stack || relative),
152144
sieve = new Sieve(
153145
traces, separateNegativeValues, dontMergeOverlappingData
154-
),
155-
minDiff = sieve.minDiff,
156-
distinctPositions = sieve.distinctPositions;
146+
);
157147

158-
// set bar offsets and widths
148+
// set bar offsets and widths and update position axis
159149
setOffsetAndWidth(gd, pa, sieve);
160150

161-
// update position axis
162-
Axes.minDtick(pa, minDiff, distinctPositions[0]);
163-
Axes.expand(pa, distinctPositions, {vpad: minDiff / 2});
164-
165-
// set bar bases and sizes
151+
// set bar bases and sizes and update size axis
166152
stackBars(gd, sa, sieve);
167153
}
168154

@@ -199,6 +185,11 @@ function setOffsetAndWidth(gd, pa, sieve) {
199185
bar[pLetter] = bar.p + barCenter;
200186
}
201187
}
188+
189+
// update position axis
190+
var distinctPositions = sieve.distinctPositions;
191+
Axes.minDtick(pa, minDiff, distinctPositions[0]);
192+
Axes.expand(pa, distinctPositions, {vpad: minDiff / 2});
202193
}
203194

204195

@@ -243,6 +234,10 @@ function setOffsetAndWidthInGroupMode(gd, pa, sieve) {
243234
bar[pLetter] = bar.p + barCenter;
244235
}
245236
}
237+
238+
// update position axis
239+
Axes.minDtick(pa, minDiff, distinctPositions[0], overlap);
240+
Axes.expand(pa, distinctPositions, {vpad: minDiff / 2});
246241
}
247242

248243

@@ -318,9 +313,11 @@ function normalizeBars(gd, sa, sieve) {
318313
var trace = traces[i];
319314

320315
for(var j = 0; j < trace.length; j++) {
321-
var bar = trace[j],
322-
scale = Math.abs(sTop / sieve.get(bar.p, bar.s));
316+
var bar = trace[j];
317+
318+
if(!isNumeric(bar.s)) continue;
323319

320+
var scale = Math.abs(sTop / sieve.get(bar.p, bar.s));
324321
bar.b *= scale;
325322
bar.s *= scale;
326323
var barEnd = bar.b + bar.s;
@@ -343,6 +340,27 @@ function normalizeBars(gd, sa, sieve) {
343340
}
344341

345342

343+
function applyBarbase(gd, sa, traces) {
344+
var barbase = gd._fullLayout.barbase;
345+
if(!barbase || !isNumeric(sa.c2l(barbase))) return;
346+
347+
for(var i = 0; i < traces.length; i++) {
348+
var trace = traces[i];
349+
350+
for(var j = 0; j < trace.length; j++) {
351+
var bar = trace[j],
352+
bartop = bar.b + bar.s;
353+
if(isNumeric(sa.c2l(bartop))) {
354+
bar.b = barbase;
355+
bar.s = bartop - barbase;
356+
}
357+
}
358+
}
359+
360+
Axes.expand(sa, [barbase], {tozero: true, padded: true});
361+
}
362+
363+
346364
function getAxisLetter(ax) {
347365
return ax._id.charAt(0);
348366
}

0 commit comments

Comments
 (0)