Skip to content

Commit 6813865

Browse files
committed
mv handleConstraintDefaults into constraints.js file
1 parent 58bf5bb commit 6813865

File tree

3 files changed

+138
-155
lines changed

3 files changed

+138
-155
lines changed

src/plots/cartesian/constraint_defaults.js

-152
This file was deleted.

src/plots/cartesian/constraints.js

+137-2
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,153 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9-
109
'use strict';
1110

11+
var Lib = require('../../lib');
1212
var id2name = require('./axis_ids').id2name;
1313
var scaleZoom = require('./scale_zoom');
1414
var makePadFn = require('./autorange').makePadFn;
1515
var concatExtremes = require('./autorange').concatExtremes;
1616

1717
var ALMOST_EQUAL = require('../../constants/numerical').ALMOST_EQUAL;
18-
1918
var FROM_BL = require('../../constants/alignment').FROM_BL;
2019

20+
exports.handleConstraintDefaults = function(containerIn, containerOut, coerce, allAxisIds, layoutOut) {
21+
var constraintGroups = layoutOut._axisConstraintGroups;
22+
var thisID = containerOut._id;
23+
var letter = thisID.charAt(0);
24+
25+
if(containerOut.fixedrange) return;
26+
27+
// coerce the constraint mechanics even if this axis has no scaleanchor
28+
// because it may be the anchor of another axis.
29+
coerce('constrain');
30+
Lib.coerce(containerIn, containerOut, {
31+
constraintoward: {
32+
valType: 'enumerated',
33+
values: letter === 'x' ? ['left', 'center', 'right'] : ['bottom', 'middle', 'top'],
34+
dflt: letter === 'x' ? 'center' : 'middle'
35+
}
36+
}, 'constraintoward');
37+
38+
if(!containerIn.scaleanchor) return;
39+
40+
var constraintOpts = getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut);
41+
42+
var scaleanchor = Lib.coerce(containerIn, containerOut, {
43+
scaleanchor: {
44+
valType: 'enumerated',
45+
values: constraintOpts.linkableAxes
46+
}
47+
}, 'scaleanchor');
48+
49+
if(scaleanchor) {
50+
var scaleratio = coerce('scaleratio');
51+
// TODO: I suppose I could do attribute.min: Number.MIN_VALUE to avoid zero,
52+
// but that seems hacky. Better way to say "must be a positive number"?
53+
// Of course if you use several super-tiny values you could eventually
54+
// force a product of these to zero and all hell would break loose...
55+
// Likewise with super-huge values.
56+
if(!scaleratio) scaleratio = containerOut.scaleratio = 1;
57+
58+
updateConstraintGroups(constraintGroups, constraintOpts.thisGroup,
59+
thisID, scaleanchor, scaleratio);
60+
}
61+
else if(allAxisIds.indexOf(containerIn.scaleanchor) !== -1) {
62+
Lib.warn('ignored ' + containerOut._name + '.scaleanchor: "' +
63+
containerIn.scaleanchor + '" to avoid either an infinite loop ' +
64+
'and possibly inconsistent scaleratios, or because the target' +
65+
'axis has fixed range.');
66+
}
67+
};
68+
69+
function getConstraintOpts(constraintGroups, thisID, allAxisIds, layoutOut) {
70+
// If this axis is already part of a constraint group, we can't
71+
// scaleanchor any other axis in that group, or we'd make a loop.
72+
// Filter allAxisIds to enforce this, also matching axis types.
73+
74+
var thisType = layoutOut[id2name(thisID)].type;
75+
76+
var i, j, idj, axj;
77+
78+
var linkableAxes = [];
79+
for(j = 0; j < allAxisIds.length; j++) {
80+
idj = allAxisIds[j];
81+
if(idj === thisID) continue;
82+
83+
axj = layoutOut[id2name(idj)];
84+
if(axj.type === thisType && !axj.fixedrange) linkableAxes.push(idj);
85+
}
86+
87+
for(i = 0; i < constraintGroups.length; i++) {
88+
if(constraintGroups[i][thisID]) {
89+
var thisGroup = constraintGroups[i];
90+
91+
var linkableAxesNoLoops = [];
92+
for(j = 0; j < linkableAxes.length; j++) {
93+
idj = linkableAxes[j];
94+
if(!thisGroup[idj]) linkableAxesNoLoops.push(idj);
95+
}
96+
return {linkableAxes: linkableAxesNoLoops, thisGroup: thisGroup};
97+
}
98+
}
99+
100+
return {linkableAxes: linkableAxes, thisGroup: null};
101+
}
102+
103+
/*
104+
* Add this axis to the axis constraint groups, which is the collection
105+
* of axes that are all constrained together on scale.
106+
*
107+
* constraintGroups: a list of objects. each object is
108+
* {axis_id: scale_within_group}, where scale_within_group is
109+
* only important relative to the rest of the group, and defines
110+
* the relative scales between all axes in the group
111+
*
112+
* thisGroup: the group the current axis is already in
113+
* thisID: the id if the current axis
114+
* scaleanchor: the id of the axis to scale it with
115+
* scaleratio: the ratio of this axis to the scaleanchor axis
116+
*/
117+
function updateConstraintGroups(constraintGroups, thisGroup, thisID, scaleanchor, scaleratio) {
118+
var i, j, groupi, keyj, thisGroupIndex;
119+
120+
if(thisGroup === null) {
121+
thisGroup = {};
122+
thisGroup[thisID] = 1;
123+
thisGroupIndex = constraintGroups.length;
124+
constraintGroups.push(thisGroup);
125+
}
126+
else {
127+
thisGroupIndex = constraintGroups.indexOf(thisGroup);
128+
}
129+
130+
var thisGroupKeys = Object.keys(thisGroup);
131+
132+
// we know that this axis isn't in any other groups, but we don't know
133+
// about the scaleanchor axis. If it is, we need to merge the groups.
134+
for(i = 0; i < constraintGroups.length; i++) {
135+
groupi = constraintGroups[i];
136+
if(i !== thisGroupIndex && groupi[scaleanchor]) {
137+
var baseScale = groupi[scaleanchor];
138+
for(j = 0; j < thisGroupKeys.length; j++) {
139+
keyj = thisGroupKeys[j];
140+
groupi[keyj] = baseScale * scaleratio * thisGroup[keyj];
141+
}
142+
constraintGroups.splice(thisGroupIndex, 1);
143+
return;
144+
}
145+
}
146+
147+
// otherwise, we insert the new scaleanchor axis as the base scale (1)
148+
// in its group, and scale the rest of the group to it
149+
if(scaleratio !== 1) {
150+
for(j = 0; j < thisGroupKeys.length; j++) {
151+
thisGroup[thisGroupKeys[j]] *= scaleratio;
152+
}
153+
}
154+
thisGroup[scaleanchor] = 1;
155+
}
21156

22157
exports.enforce = function enforceAxisConstraints(gd) {
23158
var fullLayout = gd._fullLayout;

src/plots/cartesian/layout_defaults.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ var basePlotLayoutAttributes = require('../layout_attributes');
1717
var layoutAttributes = require('./layout_attributes');
1818
var handleTypeDefaults = require('./type_defaults');
1919
var handleAxisDefaults = require('./axis_defaults');
20-
var handleConstraintDefaults = require('./constraint_defaults');
20+
var handleConstraintDefaults = require('./constraints').handleConstraintDefaults;
2121
var handlePositionDefaults = require('./position_defaults');
2222

2323
var axisIds = require('./axis_ids');

0 commit comments

Comments
 (0)