diff --git a/src/plots/cartesian/constraint_defaults.js b/src/plots/cartesian/constraint_defaults.js index 3b275c457e4..3095a51be22 100644 --- a/src/plots/cartesian/constraint_defaults.js +++ b/src/plots/cartesian/constraint_defaults.js @@ -18,11 +18,9 @@ module.exports = function handleConstraintDefaults(containerIn, containerOut, co var thisID = containerOut._id; var letter = thisID.charAt(0); - if(containerOut.fixedrange) return; - // coerce the constraint mechanics even if this axis has no scaleanchor // because it may be the anchor of another axis. - coerce('constrain'); + var constrain = coerce('constrain'); Lib.coerce(containerIn, containerOut, { constraintoward: { valType: 'enumerated', @@ -31,9 +29,9 @@ module.exports = function handleConstraintDefaults(containerIn, containerOut, co } }, 'constraintoward'); - if(!containerIn.scaleanchor) return; + if(!containerIn.scaleanchor || (constrain === 'range' && containerOut.fixedrange)) return; - var constraintOpts = getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut); + var constraintOpts = getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut, constrain); var scaleanchor = Lib.coerce(containerIn, containerOut, { scaleanchor: { @@ -62,12 +60,13 @@ module.exports = function handleConstraintDefaults(containerIn, containerOut, co } }; -function getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut) { +function getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut, constrain) { // If this axis is already part of a constraint group, we can't // scaleanchor any other axis in that group, or we'd make a loop. // Filter allAxisIds to enforce this, also matching axis types. var thisType = layoutOut[id2name(thisID)].type; + var doesConstrainRange = constrain === 'range'; var i, j, idj, axj; @@ -77,7 +76,9 @@ function getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut) { if(idj === thisID) continue; axj = layoutOut[id2name(idj)]; - if(axj.type === thisType && !axj.fixedrange) linkableAxes.push(idj); + if(axj.type === thisType && !(doesConstrainRange && axj.fixedrange)) { + linkableAxes.push(idj); + } } for(i = 0; i < constraintGroups.length; i++) { diff --git a/test/image/baselines/axes_scaleanchor-constrain-domain-fixedrange.png b/test/image/baselines/axes_scaleanchor-constrain-domain-fixedrange.png new file mode 100644 index 00000000000..60bd3831990 Binary files /dev/null and b/test/image/baselines/axes_scaleanchor-constrain-domain-fixedrange.png differ diff --git a/test/image/mocks/axes_scaleanchor-constrain-domain-fixedrange.json b/test/image/mocks/axes_scaleanchor-constrain-domain-fixedrange.json new file mode 100644 index 00000000000..47b6c7b3f86 --- /dev/null +++ b/test/image/mocks/axes_scaleanchor-constrain-domain-fixedrange.json @@ -0,0 +1,28 @@ +{ + "data": [ + { + "y": [2, 3, 4, 5, 6], + "x": [2, 3, 4, 5, 6], + "z": [ + [0.5, 0.8, 0.6, 0.8, 0.2], + [0.4, 0.3, 0.7, 0.2, 0.1], + [0.7, 0.5, 0.9, 0.5, 0.3], + [0.5, 0.8, 0.6, 0.8, 0.2], + [0.4, 0.3, 0.7, 0.2, 0.1] + ], + "type": "heatmap" + } + ], + "layout": { + "xaxis": { + "constrain": "domain", + "fixedrange": true + }, + "yaxis": { + "constrain": "domain", + "scaleanchor": "x", + "scaleratio": 1, + "fixedrange": true + } + } +}