Skip to content

Commit dfada6a

Browse files
committed
add bar autorange tests & move 'b' init to setPositions
- Bar.setPositions mutates 'b' in bar trace calcdata, so to reinit 'b' during setPositions so that it doesn't conflit with Bar.calc
1 parent 9cc5fbe commit dfada6a

File tree

3 files changed

+123
-43
lines changed

3 files changed

+123
-43
lines changed

src/traces/bar/calc.js

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9-
109
'use strict';
1110

12-
var isNumeric = require('fast-isnumeric');
13-
var isArrayOrTypedArray = require('../../lib').isArrayOrTypedArray;
14-
1511
var Axes = require('../../plots/cartesian/axes');
1612
var hasColorscale = require('../../components/colorscale/has_colorscale');
1713
var colorscaleCalc = require('../../components/colorscale/calc');
@@ -27,24 +23,14 @@ module.exports = function calc(gd, trace) {
2723
var xa = Axes.getFromId(gd, trace.xaxis || 'x'),
2824
ya = Axes.getFromId(gd, trace.yaxis || 'y'),
2925
orientation = trace.orientation || ((trace.x && !trace.y) ? 'h' : 'v'),
30-
sa, pos, size, i, scalendar;
26+
pos, size, i;
3127

3228
if(orientation === 'h') {
33-
sa = xa;
3429
size = xa.makeCalcdata(trace, 'x');
3530
pos = ya.makeCalcdata(trace, 'y');
36-
37-
// not sure if it really makes sense to have dates for bar size data...
38-
// ideally if we want to make gantt charts or something we'd treat
39-
// the actual size (trace.x or y) as time delta but base as absolute
40-
// time. But included here for completeness.
41-
scalendar = trace.xcalendar;
42-
}
43-
else {
44-
sa = ya;
31+
} else {
4532
size = ya.makeCalcdata(trace, 'y');
4633
pos = xa.makeCalcdata(trace, 'x');
47-
scalendar = trace.ycalendar;
4834
}
4935

5036
// create the "calculated data" to plot
@@ -60,33 +46,6 @@ module.exports = function calc(gd, trace) {
6046
}
6147
}
6248

63-
// set base
64-
var base = trace.base,
65-
b;
66-
67-
if(isArrayOrTypedArray(base)) {
68-
for(i = 0; i < Math.min(base.length, cd.length); i++) {
69-
b = sa.d2c(base[i], 0, scalendar);
70-
if(isNumeric(b)) {
71-
cd[i].b = +b;
72-
cd[i].hasB = 1;
73-
}
74-
else cd[i].b = 0;
75-
}
76-
for(; i < cd.length; i++) {
77-
cd[i].b = 0;
78-
}
79-
}
80-
else {
81-
b = sa.d2c(base, 0, scalendar);
82-
var hasBase = isNumeric(b);
83-
b = hasBase ? b : 0;
84-
for(i = 0; i < cd.length; i++) {
85-
cd[i].b = b;
86-
if(hasBase) cd[i].hasB = 1;
87-
}
88-
}
89-
9049
// auto-z and autocolorscale if applicable
9150
if(hasColorscale(trace, 'marker')) {
9251
colorscaleCalc(trace, trace.marker.color, 'marker', 'c');

src/traces/bar/set_positions.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ function setGroupPositions(gd, pa, sa, calcTraces) {
6565
included,
6666
i, calcTrace, fullTrace;
6767

68+
initBase(gd, pa, sa, calcTraces);
69+
6870
if(overlay) {
6971
setGroupPositionsInOverlayMode(gd, pa, sa, calcTraces);
7072
}
@@ -110,6 +112,45 @@ function setGroupPositions(gd, pa, sa, calcTraces) {
110112
collectExtents(calcTraces, pa);
111113
}
112114

115+
function initBase(gd, pa, sa, calcTraces) {
116+
var i, j;
117+
118+
for(i = 0; i < calcTraces.length; i++) {
119+
var cd = calcTraces[i];
120+
var trace = cd[0].trace;
121+
var base = trace.base;
122+
var b;
123+
124+
// not sure if it really makes sense to have dates for bar size data...
125+
// ideally if we want to make gantt charts or something we'd treat
126+
// the actual size (trace.x or y) as time delta but base as absolute
127+
// time. But included here for completeness.
128+
var scalendar = trace.orientation === 'h' ? trace.xcalendar : trace.ycalendar;
129+
130+
if(isArrayOrTypedArray(base)) {
131+
for(j = 0; j < Math.min(base.length, cd.length); j++) {
132+
b = sa.d2c(base[j], 0, scalendar);
133+
if(isNumeric(b)) {
134+
cd[j].b = +b;
135+
cd[j].hasB = 1;
136+
}
137+
else cd[j].b = 0;
138+
}
139+
for(; j < cd.length; j++) {
140+
cd[j].b = 0;
141+
}
142+
} else {
143+
b = sa.d2c(base, 0, scalendar);
144+
var hasBase = isNumeric(b);
145+
b = hasBase ? b : 0;
146+
for(j = 0; j < cd.length; j++) {
147+
cd[j].b = b;
148+
if(hasBase) cd[j].hasB = 1;
149+
}
150+
}
151+
}
152+
}
153+
113154

114155
function setGroupPositionsInOverlayMode(gd, pa, sa, calcTraces) {
115156
var barnorm = gd._fullLayout.barnorm,

test/jasmine/tests/bar_test.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,86 @@ describe('A bar plot', function() {
13331333
});
13341334
});
13351335

1336+
describe('bar visibility toggling:', function() {
1337+
var gd;
1338+
1339+
beforeEach(function() {
1340+
gd = createGraphDiv();
1341+
});
1342+
1343+
afterEach(destroyGraphDiv);
1344+
1345+
function _assert(msg, xrng, yrng, calls) {
1346+
var fullLayout = gd._fullLayout;
1347+
expect(fullLayout.xaxis.range).toBeCloseToArray(xrng, 2, msg + ' xrng');
1348+
expect(fullLayout.yaxis.range).toBeCloseToArray(yrng, 2, msg + ' yrng');
1349+
1350+
var setPositions = gd._fullData[0]._module.setPositions;
1351+
expect(setPositions).toHaveBeenCalledTimes(calls);
1352+
setPositions.calls.reset();
1353+
}
1354+
1355+
it('should update axis range according to visible edits (group case)', function(done) {
1356+
Plotly.plot(gd, [
1357+
{type: 'bar', x: [1, 2, 3], y: [1, 2, 1]},
1358+
{type: 'bar', x: [1, 2, 3], y: [-1, -2, -1]}
1359+
])
1360+
.then(function() {
1361+
spyOn(gd._fullData[0]._module, 'setPositions').and.callThrough();
1362+
1363+
_assert('base', [0.5, 3.5], [-2.222, 2.222], 0);
1364+
return Plotly.restyle(gd, 'visible', false, [1]);
1365+
})
1366+
.then(function() {
1367+
_assert('visible [true,false]', [0.5, 3.5], [0, 2.105], 1);
1368+
return Plotly.restyle(gd, 'visible', false, [0]);
1369+
})
1370+
.then(function() {
1371+
_assert('both invisible', [0.5, 3.5], [0, 2.105], 0);
1372+
return Plotly.restyle(gd, 'visible', true, [1]);
1373+
})
1374+
.then(function() {
1375+
_assert('visible [false,true]', [0.5, 3.5], [-2.105, 0], 1);
1376+
return Plotly.restyle(gd, 'visible', true);
1377+
})
1378+
.then(function() {
1379+
_assert('back to both visible', [0.5, 3.5], [-2.222, 2.222], 1);
1380+
})
1381+
.catch(failTest)
1382+
.then(done);
1383+
});
1384+
1385+
it('should update axis range according to visible edits (stack case)', function(done) {
1386+
Plotly.plot(gd, [
1387+
{type: 'bar', x: [1, 2, 3], y: [1, 2, 1]},
1388+
{type: 'bar', x: [1, 2, 3], y: [2, 3, 2]}
1389+
], {barmode: 'stack'})
1390+
.then(function() {
1391+
spyOn(gd._fullData[0]._module, 'setPositions').and.callThrough();
1392+
1393+
_assert('base', [0.5, 3.5], [0, 5.263], 0);
1394+
return Plotly.restyle(gd, 'visible', false, [1]);
1395+
})
1396+
.then(function() {
1397+
_assert('visible [true,false]', [0.5, 3.5], [0, 2.105], 1);
1398+
return Plotly.restyle(gd, 'visible', false, [0]);
1399+
})
1400+
.then(function() {
1401+
_assert('both invisible', [0.5, 3.5], [0, 2.105], 0);
1402+
return Plotly.restyle(gd, 'visible', true, [1]);
1403+
})
1404+
.then(function() {
1405+
_assert('visible [false,true]', [0.5, 3.5], [0, 3.157], 1);
1406+
return Plotly.restyle(gd, 'visible', true);
1407+
})
1408+
.then(function() {
1409+
_assert('back to both visible', [0.5, 3.5], [0, 5.263], 1);
1410+
})
1411+
.catch(failTest)
1412+
.then(done);
1413+
});
1414+
});
1415+
13361416
describe('bar hover', function() {
13371417
'use strict';
13381418

0 commit comments

Comments
 (0)