Skip to content

Commit 5c20d5d

Browse files
authored
Merge pull request #723 from plotly/fix-bar-relative-first-bucket
Fix bar relative first bucket
2 parents 46bbbae + 71155cd commit 5c20d5d

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

src/traces/bar/set_positions.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,11 @@ module.exports = function setPositions(gd, plotinfo) {
148148
if(!isNumeric(ti[j].s)) continue;
149149

150150
sv = Math.round(ti[j].p / sumround);
151-
// store the negative sum value for p at the same key, with sign flipped
152-
if(relative && ti[j].s < 0) sv = -sv;
151+
152+
// store the negative sum value for p at the same key,
153+
// with sign flipped using string to ensure -0 !== 0.
154+
if(relative && ti[j].s < 0) sv = '-' + sv;
155+
153156
var previousSum = sums[sv] || 0;
154157
if(stack || relative) ti[j].b = previousSum;
155158
barEnd = ti[j].b + ti[j].s;
@@ -167,20 +170,29 @@ module.exports = function setPositions(gd, plotinfo) {
167170
}
168171

169172
if(norm) {
170-
padded = false;
171173
var top = norm === 'fraction' ? 1 : 100,
172174
relAndNegative = false,
173175
tiny = top / 1e9; // in case of rounding error in sum
176+
177+
padded = false;
174178
sMin = 0;
175179
sMax = stack ? top : 0;
180+
176181
for(i = 0; i < bl.length; i++) { // trace index
177182
ti = gd.calcdata[bl[i]];
183+
178184
for(j = 0; j < ti.length; j++) {
179-
relAndNegative = relative && ti[j].s < 0;
185+
relAndNegative = (relative && ti[j].s < 0);
186+
180187
sv = Math.round(ti[j].p / sumround);
181-
if(relAndNegative) sv = -sv; // locate negative sum amount for this p val
188+
189+
// locate negative sum amount for this p val
190+
if(relAndNegative) sv = '-' + sv;
191+
182192
scale = top / sums[sv];
183-
if(relAndNegative) scale *= -1; // preserve sign if negative
193+
194+
// preserve sign if negative
195+
if(relAndNegative) scale *= -1;
184196
ti[j].b *= scale;
185197
ti[j].s *= scale;
186198
barEnd = ti[j].b + ti[j].s;

test/jasmine/tests/bar_test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,44 @@ describe('heatmap calc / setPositions', function() {
183183
assertTraceField(out, 't.dbar', [1, 1]);
184184
});
185185

186+
it('should fill in calc pt fields (relative case)', function() {
187+
var out = _calc([{
188+
y: [20, 14, -23]
189+
}, {
190+
y: [-12, -18, -29]
191+
}], {
192+
barmode: 'relative'
193+
});
194+
195+
assertPtField(out, 'x', [[0, 1, 2], [0, 1, 2]]);
196+
assertPtField(out, 'y', [[20, 14, -23], [-12, -18, -52]]);
197+
assertPtField(out, 'b', [[0, 0, 0], [0, 0, -23]]);
198+
assertPtField(out, 's', [[20, 14, -23], [-12, -18, -29]]);
199+
assertPtField(out, 'p', [[0, 1, 2], [0, 1, 2]]);
200+
assertTraceField(out, 't.barwidth', [0.8, 0.8]);
201+
assertTraceField(out, 't.poffset', [-0.4, -0.4]);
202+
assertTraceField(out, 't.dbar', [1, 1]);
203+
});
204+
205+
it('should fill in calc pt fields (relative / percent case)', function() {
206+
var out = _calc([{
207+
x: ['A', 'B', 'C', 'D'],
208+
y: [20, 14, 40, -60]
209+
}, {
210+
x: ['A', 'B', 'C', 'D'],
211+
y: [-12, -18, 60, -40]
212+
}], {
213+
barmode: 'relative',
214+
barnorm: 'percent'
215+
});
216+
217+
assertPtField(out, 'x', [[0, 1, 2, 3], [0, 1, 2, 3]]);
218+
assertPtField(out, 'y', [[100, 100, 40, -60], [-100, -100, 100, -100]]);
219+
assertPtField(out, 'b', [[0, 0, 0, 0], [0, 0, 40, -60]]);
220+
assertPtField(out, 's', [[100, 100, 40, -60], [-100, -100, 60, -40]]);
221+
assertPtField(out, 'p', [[0, 1, 2, 3], [0, 1, 2, 3]]);
222+
assertTraceField(out, 't.barwidth', [0.8, 0.8]);
223+
assertTraceField(out, 't.poffset', [-0.4, -0.4]);
224+
assertTraceField(out, 't.dbar', [1, 1]);
225+
});
186226
});

0 commit comments

Comments
 (0)