Skip to content

Commit 99a9edb

Browse files
committed
allow fixedrange subplots to scaleanchor with constrain:domain
more info in: #3460
1 parent 6b34ae3 commit 99a9edb

File tree

4 files changed

+61
-20
lines changed

4 files changed

+61
-20
lines changed

Diff for: src/plots/cartesian/constraints.js

+32-19
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,10 @@ exports.handleConstraintDefaults = function(containerIn, containerOut, coerce, a
2626
var thisID = containerOut._id;
2727
var letter = thisID.charAt(0);
2828

29-
if(containerOut.fixedrange) return;
30-
3129
// coerce the constraint mechanics even if this axis has no scaleanchor
3230
// because it may be the anchor of another axis.
3331
var constrain = coerce('constrain');
32+
3433
Lib.coerce(containerIn, containerOut, {
3534
constraintoward: {
3635
valType: 'enumerated',
@@ -39,27 +38,31 @@ exports.handleConstraintDefaults = function(containerIn, containerOut, coerce, a
3938
}
4039
}, 'constraintoward');
4140

42-
if(!containerIn.scaleanchor && !containerIn.matches && !splomStash.matches) return;
41+
var scaleOpts = containerIn.scaleanchor && !(containerOut.fixedrange && constrain !== 'domain') ?
42+
getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut, constrain) :
43+
{};
4344

44-
var opts = getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut);
45+
var matchOpts = (containerIn.matches || splomStash.matches) && !containerOut.fixedrange ?
46+
getConstraintOpts(matchGroups, thisID, allAxisIds, layoutOut) :
47+
{};
4548

4649
var scaleanchor = Lib.coerce(containerIn, containerOut, {
4750
scaleanchor: {
4851
valType: 'enumerated',
49-
values: opts.linkableAxes
52+
values: scaleOpts.linkableAxes || []
5053
}
5154
}, 'scaleanchor');
5255

5356
var matches = Lib.coerce(containerIn, containerOut, {
5457
matches: {
5558
valType: 'enumerated',
56-
values: opts.linkableAxes,
59+
values: matchOpts.linkableAxes || [],
5760
dflt: splomStash.matches
5861
}
5962
}, 'matches');
6063

6164
// disallow constraining AND matching range
62-
if(constrain === 'range' && scaleanchor === matches) {
65+
if(constrain === 'range' && scaleanchor && matches && scaleanchor === matches) {
6366
delete containerOut.scaleanchor;
6467
delete containerOut.constrain;
6568
scaleanchor = null;
@@ -77,12 +80,12 @@ exports.handleConstraintDefaults = function(containerIn, containerOut, coerce, a
7780
// Likewise with super-huge values.
7881
if(!scaleratio) scaleratio = containerOut.scaleratio = 1;
7982

80-
updateConstraintGroups(constraintGroups, opts.thisGroup, thisID, scaleanchor, scaleratio);
83+
updateConstraintGroups(constraintGroups, scaleOpts.thisGroup, thisID, scaleanchor, scaleratio);
8184
found = true;
8285
}
8386

8487
if(matches) {
85-
updateConstraintGroups(matchGroups, opts.thisGroup, thisID, matches, 1);
88+
updateConstraintGroups(matchGroups, matchOpts.thisGroup, thisID, matches, 1);
8689
found = true;
8790
}
8891

@@ -94,13 +97,12 @@ exports.handleConstraintDefaults = function(containerIn, containerOut, coerce, a
9497
}
9598
};
9699

97-
function getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut) {
98-
// If this axis is already part of a constraint group, we can't
99-
// scaleanchor any other axis in that group, or we'd make a loop.
100-
// Filter allAxisIds to enforce this, also matching axis types.
101-
100+
// If this axis is already part of a constraint group, we can't
101+
// scaleanchor any other axis in that group, or we'd make a loop.
102+
// Filter allAxisIds to enforce this, also matching axis types.
103+
function getConstraintOpts(groups, thisID, allAxisIds, layoutOut, constrain) {
104+
var doesNotConstrainRange = constrain !== 'range';
102105
var thisType = layoutOut[id2name(thisID)].type;
103-
104106
var i, j, idj, axj;
105107

106108
var linkableAxes = [];
@@ -109,12 +111,23 @@ function getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut) {
109111
if(idj === thisID) continue;
110112

111113
axj = layoutOut[id2name(idj)];
112-
if(axj.type === thisType && !axj.fixedrange) linkableAxes.push(idj);
114+
if(axj.type === thisType) {
115+
if(!axj.fixedrange) {
116+
linkableAxes.push(idj);
117+
} else if(doesNotConstrainRange && axj.anchor) {
118+
// allow domain constraints on subplots where
119+
// BOTH axes have fixedrange:true and constrain:domain
120+
var counterAxj = layoutOut[id2name(axj.anchor)];
121+
if(counterAxj.fixedrange) {
122+
linkableAxes.push(idj);
123+
}
124+
}
125+
}
113126
}
114127

115-
for(i = 0; i < constraintGroups.length; i++) {
116-
if(constraintGroups[i][thisID]) {
117-
var thisGroup = constraintGroups[i];
128+
for(i = 0; i < groups.length; i++) {
129+
if(groups[i][thisID]) {
130+
var thisGroup = groups[i];
118131

119132
var linkableAxesNoLoops = [];
120133
for(j = 0; j < linkableAxes.length; j++) {
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"data": [
3+
{
4+
"y": [2, 3, 4, 5, 6],
5+
"x": [2, 3, 4, 5, 6],
6+
"z": [
7+
[0.5, 0.8, 0.6, 0.8, 0.2],
8+
[0.4, 0.3, 0.7, 0.2, 0.1],
9+
[0.7, 0.5, 0.9, 0.5, 0.3],
10+
[0.5, 0.8, 0.6, 0.8, 0.2],
11+
[0.4, 0.3, 0.7, 0.2, 0.1]
12+
],
13+
"type": "heatmap"
14+
}
15+
],
16+
"layout": {
17+
"xaxis": {
18+
"constrain": "domain",
19+
"fixedrange": true
20+
},
21+
"yaxis": {
22+
"constrain": "domain",
23+
"scaleanchor": "x",
24+
"scaleratio": 1,
25+
"fixedrange": true
26+
}
27+
}
28+
}

Diff for: test/jasmine/tests/axes_test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,7 @@ describe('Test axes', function() {
826826
_assertMatchingAxes(['xaxis', 'xaxis2'], true, [-1, 6]);
827827
_assertMatchingAxes(['yaxis', 'yaxis2'], false, [0, 1]);
828828
_assertMatchingAxes(['xaxis3', 'yaxis3'], true, [-1, 6]);
829-
_assertMatchingAxes(['xaxis4', 'yaxis4'], false, [0, 2]);
829+
_assertMatchingAxes(['xaxis4', 'yaxis4'], false, [-1, 3]);
830830
});
831831
});
832832

0 commit comments

Comments
 (0)