Skip to content

Commit 59a092a

Browse files
committed
update constraints.js to handle some more editing edge cases
1 parent b1c6b24 commit 59a092a

File tree

1 file changed

+29
-30
lines changed

1 file changed

+29
-30
lines changed

src/plots/cartesian/constraints.js

+29-30
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,16 @@ exports.enforce = function enforceAxisConstraints(gd) {
3737
var matchScale = Infinity;
3838
var normScales = {};
3939
var axes = {};
40+
var hasAnyDomainConstraint = false;
4041

4142
// find the (normalized) scale of each axis in the group
4243
for(j = 0; j < axisIDs.length; j++) {
4344
axisID = axisIDs[j];
4445
axes[axisID] = ax = fullLayout[id2name(axisID)];
4546

46-
if(!ax._inputDomain) ax._inputDomain = ax.domain.slice();
47+
if(ax._inputDomain) ax.domain = ax._inputDomain.slice();
48+
else ax._inputDomain = ax.domain.slice();
49+
4750
if(!ax._inputRange) ax._inputRange = ax.range.slice();
4851

4952
// set axis scale here so we can use _m rather than
@@ -53,18 +56,19 @@ exports.enforce = function enforceAxisConstraints(gd) {
5356
// abs: inverted scales still satisfy the constraint
5457
normScales[axisID] = normScale = Math.abs(ax._m) / group[axisID];
5558
minScale = Math.min(minScale, normScale);
56-
if(ax._constraintShrinkable) {
57-
// this has served its purpose, so remove it
58-
delete ax._constraintShrinkable;
59-
}
60-
else {
59+
if(ax.constrain === 'domain' || !ax._constraintShrinkable) {
6160
matchScale = Math.min(matchScale, normScale);
6261
}
62+
63+
// this has served its purpose, so remove it
64+
delete ax._constraintShrinkable;
6365
maxScale = Math.max(maxScale, normScale);
66+
67+
if(ax.constrain === 'domain') hasAnyDomainConstraint = true;
6468
}
6569

6670
// Do we have a constraint mismatch? Give a small buffer for rounding errors
67-
if(minScale > ALMOST_EQUAL * maxScale) continue;
71+
if(minScale > ALMOST_EQUAL * maxScale && !hasAnyDomainConstraint) continue;
6872

6973
// now increase any ranges we need to until all normalized scales are equal
7074
for(j = 0; j < axisIDs.length; j++) {
@@ -107,8 +111,7 @@ exports.enforce = function enforceAxisConstraints(gd) {
107111
factor *= rangeShrunk;
108112
}
109113

110-
// TODO
111-
if(ax.autorange) {
114+
if(ax.autorange && ax._min.length && ax._max.length) {
112115
/*
113116
* range & factor may need to change because range was
114117
* calculated for the larger scaling, so some pixel
@@ -121,12 +124,16 @@ exports.enforce = function enforceAxisConstraints(gd) {
121124
* outerMin/Max are for - if the expansion was going to
122125
* go beyond the original domain, it must be impossible
123126
*/
124-
var rangeMin = Math.min(ax.range[0], ax.range[1]);
125-
var rangeMax = Math.max(ax.range[0], ax.range[1]);
126-
var rangeCenter = (rangeMin + rangeMax) / 2;
127-
var halfRange = rangeMax - rangeCenter;
128-
var outerMin = rangeCenter - halfRange * factor;
129-
var outerMax = rangeCenter + halfRange * factor;
127+
var rl0 = ax.r2l(ax.range[0]);
128+
var rl1 = ax.r2l(ax.range[1]);
129+
var rangeCenter = (rl0 + rl1) / 2;
130+
var rangeMin = rangeCenter;
131+
var rangeMax = rangeCenter;
132+
var halfRange = Math.abs(rl1 - rangeCenter);
133+
// extra tiny bit for rounding errors, in case we actually
134+
// *are* expanding to the full domain
135+
var outerMin = rangeCenter - halfRange * factor * 1.0001;
136+
var outerMax = rangeCenter + halfRange * factor * 1.0001;
130137

131138
updateDomain(ax, factor);
132139
ax.setScale();
@@ -135,34 +142,26 @@ exports.enforce = function enforceAxisConstraints(gd) {
135142
var k;
136143

137144
for(k = 0; k < ax._min.length; k++) {
138-
newVal = ax._min[i].val - ax._min[i].pad / m;
145+
newVal = ax._min[k].val - ax._min[k].pad / m;
139146
if(newVal > outerMin && newVal < rangeMin) {
140147
rangeMin = newVal;
141148
}
142149
}
143150

144151
for(k = 0; k < ax._max.length; k++) {
145-
newVal = ax._max[i].val + ax._max[i].pad / m;
152+
newVal = ax._max[k].val + ax._max[k].pad / m;
146153
if(newVal < outerMax && newVal > rangeMax) {
147154
rangeMax = newVal;
148155
}
149156
}
150157

151-
ax.range = ax._input.range = (ax.range[0] < ax.range[1]) ?
152-
[rangeMin, rangeMax] : [rangeMax, rangeMin];
153-
154-
/*
155-
* In principle this new range can be shifted vs. what
156-
* you saw at the end of a zoom operation, like if you
157-
* have a big bubble on one side and a small bubble on
158-
* the other.
159-
* To fix this we'd have to be doing this calculation
160-
* continuously during the zoom, but it's enough of an
161-
* edge case and a subtle enough effect that I'm going
162-
* to ignore it for now.
163-
*/
164158
var domainExpand = (rangeMax - rangeMin) / (2 * halfRange);
165159
factor /= domainExpand;
160+
161+
rangeMin = ax.l2r(rangeMin);
162+
rangeMax = ax.l2r(rangeMax);
163+
ax.range = ax._input.range = (rl0 < rl1) ?
164+
[rangeMin, rangeMax] : [rangeMax, rangeMin];
166165
}
167166

168167
updateDomain(ax, factor);

0 commit comments

Comments
 (0)