Skip to content

Commit 46bbbae

Browse files
authored
Merge pull request #716 from plotly/fix-bar-height-bug
Fix stack with gaps bar height bug
2 parents 0725ea4 + ef0c67f commit 46bbbae

File tree

6 files changed

+379
-53
lines changed

6 files changed

+379
-53
lines changed

src/traces/bar/calc.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,13 @@ module.exports = function calc(gd, trace) {
3939
// create the "calculated data" to plot
4040
var serieslen = Math.min(pos.length, size.length),
4141
cd = [];
42+
4243
for(i = 0; i < serieslen; i++) {
44+
45+
// add bars with non-numeric sizes to calcdata
46+
// so that ensure that traces with gaps are
47+
// plotted in the correct order
48+
4349
if(isNumeric(pos[i])) {
4450
cd.push({p: pos[i], s: size[i], b: 0});
4551
}

src/traces/bar/set_positions.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ module.exports = function setPositions(gd, plotinfo) {
142142
for(i = 0; i < bl.length; i++) { // trace index
143143
ti = gd.calcdata[bl[i]];
144144
for(j = 0; j < ti.length; j++) {
145+
146+
// skip over bars with no size,
147+
// so that we don't try to stack them
148+
if(!isNumeric(ti[j].s)) continue;
149+
145150
sv = Math.round(ti[j].p / sumround);
146151
// store the negative sum value for p at the same key, with sign flipped
147152
if(relative && ti[j].s < 0) sv = -sv;
18.8 KB
Loading
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
{
2+
"data": [
3+
{
4+
"x": [
5+
"A",
6+
"B",
7+
"C",
8+
"D",
9+
"E",
10+
"F",
11+
"G"
12+
],
13+
"y": [
14+
null,
15+
null,
16+
null,
17+
null,
18+
7,
19+
null,
20+
6
21+
],
22+
"name": "AA",
23+
"type": "bar"
24+
},
25+
{
26+
"x": [
27+
"A",
28+
"B",
29+
"C",
30+
"D",
31+
"E",
32+
"F",
33+
"G"
34+
],
35+
"y": [
36+
8,
37+
null,
38+
null,
39+
null,
40+
null,
41+
null
42+
],
43+
"name": "BB",
44+
"type": "bar"
45+
},
46+
{
47+
"x": [
48+
"A",
49+
"B",
50+
"C",
51+
"D",
52+
"E",
53+
"F",
54+
"G"
55+
],
56+
"y": [
57+
null,
58+
null,
59+
null,
60+
1,
61+
3,
62+
null
63+
],
64+
"name": "CC",
65+
"type": "bar"
66+
},
67+
{
68+
"x": [
69+
"A",
70+
"B",
71+
"C",
72+
"D",
73+
"E",
74+
"F",
75+
"G"
76+
],
77+
"y": [
78+
null,
79+
4,
80+
4,
81+
null,
82+
null,
83+
null
84+
],
85+
"name": "DD",
86+
"type": "bar"
87+
},
88+
{
89+
"x": [
90+
"A",
91+
"B",
92+
"C",
93+
"D",
94+
"E",
95+
"F",
96+
"G"
97+
],
98+
"y": [
99+
null,
100+
null,
101+
null,
102+
8,
103+
null,
104+
null,
105+
3
106+
],
107+
"name": "EE",
108+
"type": "bar"
109+
},
110+
{
111+
"x": [
112+
"A",
113+
"B",
114+
"C",
115+
"D",
116+
"E",
117+
"F",
118+
"G"
119+
],
120+
"y": [
121+
null,
122+
null,
123+
null,
124+
2,
125+
null,
126+
null
127+
],
128+
"name": "FF",
129+
"type": "bar"
130+
},
131+
{
132+
"x": [
133+
"A",
134+
"B",
135+
"C",
136+
"D",
137+
"E",
138+
"F",
139+
"G"
140+
],
141+
"y": [
142+
null,
143+
null,
144+
null,
145+
null,
146+
null,
147+
1
148+
],
149+
"name": "GG",
150+
"type": "bar"
151+
}
152+
],
153+
"layout": {
154+
"xaxis": {
155+
"type": "category",
156+
"range": [
157+
-0.5,
158+
6.5
159+
],
160+
"autorange": true
161+
},
162+
"barmode": "stack",
163+
"yaxis": {
164+
"type": "linear",
165+
"range": [
166+
0,
167+
11.578947368421053
168+
],
169+
"autorange": true
170+
},
171+
"height": 450,
172+
"width": 1100,
173+
"autosize": true
174+
}
175+
}

test/jasmine/assets/custom_matchers.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
1+
'use strict';
2+
3+
var isNumeric = require('fast-isnumeric');
4+
5+
16
module.exports = {
27

38
// toBeCloseTo... but for arrays
49
toBeCloseToArray: function() {
510
return {
6-
compare: function(actual, expected, precision) {
11+
compare: function(actual, expected, precision, msgExtra) {
712
precision = coercePosition(precision);
813

914
var tested = actual.map(function(element, i) {
10-
return Math.abs(expected[i] - element) < precision;
15+
return isClose(element, expected[i], precision);
1116
});
1217

1318
var passed = (
1419
expected.length === actual.length &&
1520
tested.indexOf(false) < 0
1621
);
1722

23+
var message = [
24+
'Expected', actual, 'to be close to', expected, msgExtra
25+
].join(' ');
26+
1827
return {
1928
pass: passed,
20-
message: 'Expected ' + actual + ' to be close to ' + expected + '.'
29+
message: message
2130
};
2231
}
2332
};
@@ -26,7 +35,7 @@ module.exports = {
2635
// toBeCloseTo... but for 2D arrays
2736
toBeCloseTo2DArray: function() {
2837
return {
29-
compare: function(actual, expected, precision) {
38+
compare: function(actual, expected, precision, msgExtra) {
3039
precision = coercePosition(precision);
3140

3241
var passed = true;
@@ -40,9 +49,7 @@ module.exports = {
4049
}
4150

4251
for(var j = 0; j < expected[i].length; ++j) {
43-
var isClose = Math.abs(expected[i][j] - actual[i][j]) < precision;
44-
45-
if(!isClose) {
52+
if(!isClose(actual[i][j], expected[i][j], precision)) {
4653
passed = false;
4754
break;
4855
}
@@ -54,7 +61,8 @@ module.exports = {
5461
'Expected',
5562
arrayToStr(actual.map(arrayToStr)),
5663
'to be close to',
57-
arrayToStr(expected.map(arrayToStr))
64+
arrayToStr(expected.map(arrayToStr)),
65+
msgExtra
5866
].join(' ');
5967

6068
return {
@@ -66,6 +74,14 @@ module.exports = {
6674
}
6775
};
6876

77+
function isClose(actual, expected, precision) {
78+
if(isNumeric(actual) && isNumeric(expected)) {
79+
return Math.abs(actual - expected) < precision;
80+
}
81+
82+
return actual === expected;
83+
}
84+
6985
function coercePosition(precision) {
7086
if(precision !== 0) {
7187
precision = Math.pow(10, -precision) / 2 || 0.005;

0 commit comments

Comments
 (0)