Skip to content

Commit f521227

Browse files
committed
push final constraint management into relayout so it always works
1 parent 84d95a5 commit f521227

File tree

2 files changed

+53
-29
lines changed

2 files changed

+53
-29
lines changed

src/plot_api/plot_api.js

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var helpers = require('./helpers');
3333
var subroutines = require('./subroutines');
3434
var cartesianConstants = require('../plots/cartesian/constants');
3535
var enforceAxisConstraints = require('../plots/cartesian/constraints');
36+
var axisIds = require('../plots/cartesian/axis_ids');
3637

3738

3839
/**
@@ -1860,6 +1861,16 @@ function _relayout(gd, aobj) {
18601861
return (ax || {}).autorange;
18611862
}
18621863

1864+
// for constraint enforcement: keep track of all axes (as {id: name})
1865+
// we're editing the (auto)range of, so we can tell the others constrained
1866+
// to scale with them that it's OK for them to shrink
1867+
var rangesAltered = {};
1868+
1869+
function recordAlteredAxis(pleafPlus) {
1870+
var axId = axisIds.name2id(pleafPlus.split('.')[0]);
1871+
rangesAltered[axId] = 1;
1872+
}
1873+
18631874
// alter gd.layout
18641875
for(var ai in aobj) {
18651876
if(helpers.hasParent(aobj, ai)) {
@@ -1894,15 +1905,17 @@ function _relayout(gd, aobj) {
18941905
//
18951906
// To do so, we must manually set them back here using the _initialAutoSize cache.
18961907
if(['width', 'height'].indexOf(ai) !== -1 && vi === null) {
1897-
gd._fullLayout[ai] = gd._initialAutoSize[ai];
1908+
fullLayout[ai] = gd._initialAutoSize[ai];
18981909
}
18991910
// check autorange vs range
19001911
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.range(\[[0|1]\])?$/)) {
19011912
doextra(ptrunk + '.autorange', false);
1913+
recordAlteredAxis(pleafPlus);
19021914
}
19031915
else if(pleafPlus.match(/^[xyz]axis[0-9]*\.autorange$/)) {
19041916
doextra([ptrunk + '.range[0]', ptrunk + '.range[1]'],
19051917
undefined);
1918+
recordAlteredAxis(pleafPlus);
19061919
}
19071920
else if(pleafPlus.match(/^aspectratio\.[xyz]$/)) {
19081921
doextra(proot + '.aspectmode', 'manual');
@@ -2121,16 +2134,37 @@ function _relayout(gd, aobj) {
21212134
if(!finished) flags.doplot = true;
21222135
}
21232136

2124-
var oldWidth = gd._fullLayout.width,
2125-
oldHeight = gd._fullLayout.height;
2137+
// figure out if we need to recalculate axis constraints
2138+
var constraints = fullLayout._axisConstraintGroups;
2139+
for(var axId in rangesAltered) {
2140+
for(i = 0; i < constraints.length; i++) {
2141+
var group = constraints[i];
2142+
if(group[axId]) {
2143+
// Always recalc if we're changing constrained ranges.
2144+
// Otherwise it's possible to violate the constraints by
2145+
// specifying arbitrary ranges for all axes in the group.
2146+
// this way some ranges may expand beyond what's specified,
2147+
// as they do at first draw, to satisfy the constraints.
2148+
flags.docalc = true;
2149+
for(var groupAxId in group) {
2150+
if(!rangesAltered[groupAxId]) {
2151+
axisIds.getFromId(gd, groupAxId)._constraintShrinkable = true;
2152+
}
2153+
}
2154+
}
2155+
}
2156+
}
2157+
2158+
var oldWidth = fullLayout.width,
2159+
oldHeight = fullLayout.height;
21262160

21272161
// calculate autosizing
2128-
if(gd.layout.autosize) Plots.plotAutoSize(gd, gd.layout, gd._fullLayout);
2162+
if(gd.layout.autosize) Plots.plotAutoSize(gd, gd.layout, fullLayout);
21292163

21302164
// avoid unnecessary redraws
21312165
var hasSizechanged = aobj.height || aobj.width ||
2132-
(gd._fullLayout.width !== oldWidth) ||
2133-
(gd._fullLayout.height !== oldHeight);
2166+
(fullLayout.width !== oldWidth) ||
2167+
(fullLayout.height !== oldHeight);
21342168

21352169
if(hasSizechanged) flags.docalc = true;
21362170

src/plots/cartesian/dragbox.js

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -567,15 +567,8 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
567567

568568
var doubleClickConfig = gd._context.doubleClick,
569569
axList = (xActive ? xa : []).concat(yActive ? ya : []),
570-
linkedAxList = (xActive || isSubplotConstrained ? xaLinked : [])
571-
.concat(yActive ? yaLinked : []),
572570
attrs = {};
573571

574-
if(isSubplotConstrained) {
575-
if(!xActive) linkedAxList = linkedAxList.concat(xa);
576-
else if(!yActive) linkedAxList = linkedAxList.concat(ya);
577-
}
578-
579572
var ax, i, rangeInitial;
580573

581574
// For reset+autosize mode:
@@ -602,14 +595,8 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
602595
}
603596

604597
if(doubleClickConfig === 'autosize') {
605-
// when we're autosizing one or a few axes, mark the other axes as
606-
// "shrinkable" so that we don't expand to cover whatever their
607-
// current ranges might be, but instead we just autosize to the
608-
// selected axes
609-
for(i = 0; i < linkedAxList.length; i++) {
610-
linkedAxList[i]._constraintShrinkable = true;
611-
}
612-
598+
// don't set the linked axes here, so relayout marks them as shrinkable
599+
// and we autosize just to the requested axis/axes
613600
for(i = 0; i < axList.length; i++) {
614601
ax = axList[i];
615602
if(!ax.fixedrange) attrs[ax._name + '.autorange'] = true;
@@ -618,7 +605,13 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
618605
else if(doubleClickConfig === 'reset') {
619606
// when we're resetting, reset all linked axes too, so we get back
620607
// to the fully-auto-with-constraints situation
621-
axList = axList.concat(linkedAxList);
608+
if(xActive || isSubplotConstrained) axList = axList.concat(xaLinked);
609+
if(yActive && !isSubplotConstrained) axList = axList.concat(yaLinked);
610+
611+
if(isSubplotConstrained) {
612+
if(!xActive) axList = axList.concat(xa);
613+
else if(!yActive) axList = axList.concat(ya);
614+
}
622615

623616
for(i = 0; i < axList.length; i++) {
624617
ax = axList[i];
@@ -645,13 +638,10 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
645638
var attrs = {};
646639
// revert to the previous axis settings, then apply the new ones
647640
// through relayout - this lets relayout manage undo/redo
648-
var axesToModify = [];
649-
if(zoommode === 'x' || zoommode === 'xy') {
650-
axesToModify = xa.concat(xaLinked);
651-
}
652-
if(zoommode === 'y' || zoommode === 'xy') {
653-
axesToModify = axesToModify.concat(ya, yaLinked);
654-
}
641+
var axesToModify;
642+
if(zoommode === 'xy') axesToModify = xa.concat(ya);
643+
else if(zoommode === 'x') axesToModify = xa;
644+
else if(zoommode === 'y') axesToModify = ya;
655645

656646
for(var i = 0; i < axesToModify.length; i++) {
657647
var axi = axesToModify[i];

0 commit comments

Comments
 (0)