Skip to content

Commit 0b70a3a

Browse files
authored
Merge pull request #1475 from plotly/log-bar-autorange
Log bar autorange fix
2 parents 25057d6 + fc977a1 commit 0b70a3a

File tree

2 files changed

+74
-47
lines changed

2 files changed

+74
-47
lines changed

src/traces/bar/set_positions.js

+32-46
Original file line numberDiff line numberDiff line change
@@ -449,15 +449,22 @@ function updatePositionAxis(gd, pa, sieve, allowMinDtick) {
449449
Axes.expand(pa, [pMin, pMax], {padded: false});
450450
}
451451

452+
function expandRange(range, newValue) {
453+
if(isNumeric(range[0])) range[0] = Math.min(range[0], newValue);
454+
else range[0] = newValue;
455+
456+
if(isNumeric(range[1])) range[1] = Math.max(range[1], newValue);
457+
else range[1] = newValue;
458+
}
452459

453460
function setBaseAndTop(gd, sa, sieve) {
454461
// store these bar bases and tops in calcdata
455462
// and make sure the size axis includes zero,
456463
// along with the bases and tops of each bar.
457464
var traces = sieve.traces,
458465
sLetter = getAxisLetter(sa),
459-
sMax = sa.l2c(sa.c2l(0)),
460-
sMin = sMax;
466+
s0 = sa.l2c(sa.c2l(0)),
467+
sRange = [s0, s0];
461468

462469
for(var i = 0; i < traces.length; i++) {
463470
var trace = traces[i];
@@ -469,18 +476,12 @@ function setBaseAndTop(gd, sa, sieve) {
469476

470477
bar[sLetter] = barTop;
471478

472-
if(isNumeric(sa.c2l(barTop))) {
473-
sMax = Math.max(sMax, barTop);
474-
sMin = Math.min(sMin, barTop);
475-
}
476-
if(isNumeric(sa.c2l(barBase))) {
477-
sMax = Math.max(sMax, barBase);
478-
sMin = Math.min(sMin, barBase);
479-
}
479+
if(isNumeric(sa.c2l(barTop))) expandRange(sRange, barTop);
480+
if(isNumeric(sa.c2l(barBase))) expandRange(sRange, barBase);
480481
}
481482
}
482483

483-
Axes.expand(sa, [sMin, sMax], {tozero: true, padded: true});
484+
Axes.expand(sa, sRange, {tozero: true, padded: true});
484485
}
485486

486487

@@ -492,8 +493,8 @@ function stackBars(gd, sa, sieve) {
492493
i, trace,
493494
j, bar;
494495

495-
var sMax = sa.l2c(sa.c2l(0)),
496-
sMin = sMax;
496+
var s0 = sa.l2c(sa.c2l(0)),
497+
sRange = [s0, s0];
497498

498499
for(i = 0; i < traces.length; i++) {
499500
trace = traces[i];
@@ -512,20 +513,14 @@ function stackBars(gd, sa, sieve) {
512513
bar[sLetter] = barTop;
513514

514515
if(!barnorm) {
515-
if(isNumeric(sa.c2l(barTop))) {
516-
sMax = Math.max(sMax, barTop);
517-
sMin = Math.min(sMin, barTop);
518-
}
519-
if(isNumeric(sa.c2l(barBase))) {
520-
sMax = Math.max(sMax, barBase);
521-
sMin = Math.min(sMin, barBase);
522-
}
516+
if(isNumeric(sa.c2l(barTop))) expandRange(sRange, barTop);
517+
if(isNumeric(sa.c2l(barBase))) expandRange(sRange, barBase);
523518
}
524519
}
525520
}
526521

527522
// if barnorm is set, let normalizeBars update the axis range
528-
if(!barnorm) Axes.expand(sa, [sMin, sMax], {tozero: true, padded: true});
523+
if(!barnorm) Axes.expand(sa, sRange, {tozero: true, padded: true});
529524
}
530525

531526

@@ -554,10 +549,20 @@ function normalizeBars(gd, sa, sieve) {
554549
sLetter = getAxisLetter(sa),
555550
sTop = (gd._fullLayout.barnorm === 'fraction') ? 1 : 100,
556551
sTiny = sTop / 1e9, // in case of rounding error in sum
557-
sMin = 0,
558-
sMax = (gd._fullLayout.barmode === 'stack') ? sTop : 0,
552+
sMin = sa.l2c(sa.c2l(0)),
553+
sMax = (gd._fullLayout.barmode === 'stack') ? sTop : sMin,
554+
sRange = [sMin, sMax],
559555
padded = false;
560556

557+
function maybeExpand(newValue) {
558+
if(isNumeric(sa.c2l(newValue)) &&
559+
((newValue < sMin - sTiny) || (newValue > sMax + sTiny) || !isNumeric(sMin))
560+
) {
561+
padded = true;
562+
expandRange(sRange, newValue);
563+
}
564+
}
565+
561566
for(var i = 0; i < traces.length; i++) {
562567
var trace = traces[i];
563568

@@ -574,32 +579,13 @@ function normalizeBars(gd, sa, sieve) {
574579
barTop = barBase + bar.s;
575580
bar[sLetter] = barTop;
576581

577-
if(isNumeric(sa.c2l(barTop))) {
578-
if(barTop < sMin - sTiny) {
579-
padded = true;
580-
sMin = barTop;
581-
}
582-
if(barTop > sMax + sTiny) {
583-
padded = true;
584-
sMax = barTop;
585-
}
586-
}
587-
588-
if(isNumeric(sa.c2l(barBase))) {
589-
if(barBase < sMin - sTiny) {
590-
padded = true;
591-
sMin = barBase;
592-
}
593-
if(barBase > sMax + sTiny) {
594-
padded = true;
595-
sMax = barBase;
596-
}
597-
}
582+
maybeExpand(barTop);
583+
maybeExpand(barBase);
598584
}
599585
}
600586

601587
// update range of size axis
602-
Axes.expand(sa, [sMin, sMax], {tozero: true, padded: padded});
588+
Axes.expand(sa, sRange, {tozero: true, padded: padded});
603589
}
604590

605591

test/jasmine/tests/bar_test.js

+42-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ describe('Bar.supplyDefaults', function() {
144144
});
145145
});
146146

147-
describe('heatmap calc / setPositions', function() {
147+
describe('bar calc / setPositions', function() {
148148
'use strict';
149149

150150
beforeAll(function() {
@@ -697,6 +697,47 @@ describe('Bar.setPositions', function() {
697697
expect(gd.calcdata[1][0].placeholder).toBe(true);
698698
expect(gd.calcdata[1][0].t.barwidth).toBeUndefined();
699699
});
700+
701+
it('works with log axes (grouped bars)', function() {
702+
var gd = mockBarPlot([
703+
{y: [1, 10, 1e10, -1]},
704+
{y: [2, 20, 2e10, -2]}
705+
], {
706+
yaxis: {type: 'log'},
707+
barmode: 'group'
708+
});
709+
710+
var ya = gd._fullLayout.yaxis;
711+
expect(Axes.getAutoRange(ya)).toBeCloseToArray([-0.572, 10.873], undefined, '(ya.range)');
712+
});
713+
714+
it('works with log axes (stacked bars)', function() {
715+
var gd = mockBarPlot([
716+
{y: [1, 10, 1e10, -1]},
717+
{y: [2, 20, 2e10, -2]}
718+
], {
719+
yaxis: {type: 'log'},
720+
barmode: 'stack'
721+
});
722+
723+
var ya = gd._fullLayout.yaxis;
724+
expect(Axes.getAutoRange(ya)).toBeCloseToArray([-0.582, 11.059], undefined, '(ya.range)');
725+
});
726+
727+
it('works with log axes (normalized bars)', function() {
728+
// strange case... but it should work!
729+
var gd = mockBarPlot([
730+
{y: [1, 10, 1e10, -1]},
731+
{y: [2, 20, 2e10, -2]}
732+
], {
733+
yaxis: {type: 'log'},
734+
barmode: 'stack',
735+
barnorm: 'percent'
736+
});
737+
738+
var ya = gd._fullLayout.yaxis;
739+
expect(Axes.getAutoRange(ya)).toBeCloseToArray([1.496, 2.027], undefined, '(ya.range)');
740+
});
700741
});
701742

702743
describe('A bar plot', function() {

0 commit comments

Comments
 (0)