Skip to content

Commit 6b4af04

Browse files
committed
handleSubplotDefaults (for gl3d, geo, and ternary... for now!)
1 parent 7e7e217 commit 6b4af04

File tree

3 files changed

+154
-119
lines changed

3 files changed

+154
-119
lines changed

src/plots/geo/layout/defaults.js

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
'use strict';
1111

12-
var Lib = require('../../../lib');
13-
var Plots = require('../../plots');
12+
var handleSubplotDefaults = require('../../subplot_defaults');
1413
var constants = require('../../../constants/geo_constants');
1514
var layoutAttributes = require('./layout_attributes');
1615
var supplyGeoAxisLayoutDefaults = require('./axis_defaults');
@@ -19,31 +18,12 @@ var supplyGeoAxisLayoutDefaults = require('./axis_defaults');
1918
module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
2019
if(!layoutOut._hasGeo) return;
2120

22-
var geos = Plots.findSubplotIds(fullData, 'geo'),
23-
geosLength = geos.length;
24-
25-
var geoLayoutIn, geoLayoutOut;
26-
27-
function coerce(attr, dflt) {
28-
return Lib.coerce(geoLayoutIn, geoLayoutOut, layoutAttributes, attr, dflt);
29-
}
30-
31-
for(var i = 0; i < geosLength; i++) {
32-
var geo = geos[i];
33-
34-
// geo traces get a layout geo for free!
35-
if(layoutIn[geo]) geoLayoutIn = layoutIn[geo];
36-
else geoLayoutIn = layoutIn[geo] = {};
37-
38-
geoLayoutIn = layoutIn[geo];
39-
geoLayoutOut = {};
40-
41-
coerce('domain.x');
42-
coerce('domain.y', [i / geosLength, (i + 1) / geosLength]);
43-
44-
handleGeoDefaults(geoLayoutIn, geoLayoutOut, coerce);
45-
layoutOut[geo] = geoLayoutOut;
46-
}
21+
handleSubplotDefaults(layoutIn, layoutOut, fullData, {
22+
type: 'geo',
23+
attributes: layoutAttributes,
24+
handleDefaults: handleGeoDefaults,
25+
partition: 'y'
26+
});
4727
};
4828

4929
function handleGeoDefaults(geoLayoutIn, geoLayoutOut, coerce) {

src/plots/gl3d/layout/defaults.js

Lines changed: 74 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -9,112 +9,94 @@
99

1010
'use strict';
1111

12-
var Lib = require('../../../lib');
13-
var Plots = require('../../plots');
12+
var handleSubplotDefaults = require('../../subplot_defaults');
1413
var layoutAttributes = require('./layout_attributes');
1514
var supplyGl3dAxisLayoutDefaults = require('./axis_defaults');
1615

1716

1817
module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
1918
if(!layoutOut._hasGL3D) return;
2019

21-
var scenes = Plots.findSubplotIds(fullData, 'gl3d'),
22-
scenesLength = scenes.length;
23-
24-
var sceneLayoutIn, sceneLayoutOut;
25-
26-
function coerce(attr, dflt) {
27-
return Lib.coerce(sceneLayoutIn, sceneLayoutOut, layoutAttributes, attr, dflt);
28-
}
20+
var hasNon3D = (
21+
layoutOut._hasCartesian ||
22+
layoutOut._hasGeo ||
23+
layoutOut._hasGL2D ||
24+
layoutOut._hasPie ||
25+
layoutOut._hasTernary
26+
);
2927

3028
// some layout-wide attribute are used in all scenes
3129
// if 3D is the only visible plot type
3230
function getDfltFromLayout(attr) {
33-
var isOnlyGL3D = !(
34-
layoutOut._hasCartesian ||
35-
layoutOut._hasGeo ||
36-
layoutOut._hasGL2D ||
37-
layoutOut._hasPie
38-
);
31+
if(hasNon3D) return;
3932

4033
var isValid = layoutAttributes[attr].values.indexOf(layoutIn[attr]) !== -1;
34+
if(isValid) return layoutIn[attr];
35+
}
4136

42-
if(isOnlyGL3D && isValid) return layoutIn[attr];
37+
handleSubplotDefaults(layoutIn, layoutOut, fullData, {
38+
type: 'gl3d',
39+
attributes: layoutAttributes,
40+
handleDefaults: handleGl3dDefaults,
41+
font: layoutOut.font,
42+
fullData: fullData,
43+
getDfltFromLayout: getDfltFromLayout
44+
});
45+
};
46+
47+
function handleGl3dDefaults(sceneLayoutIn, sceneLayoutOut, coerce, opts) {
48+
/*
49+
* Scene numbering proceeds as follows
50+
* scene
51+
* scene2
52+
* scene3
53+
*
54+
* and d.scene will be undefined or some number or number string
55+
*
56+
* Also write back a blank scene object to user layout so that some
57+
* attributes like aspectratio can be written back dynamically.
58+
*/
59+
60+
coerce('bgcolor');
61+
62+
var cameraKeys = Object.keys(layoutAttributes.camera);
63+
64+
for(var j = 0; j < cameraKeys.length; j++) {
65+
coerce('camera.' + cameraKeys[j] + '.x');
66+
coerce('camera.' + cameraKeys[j] + '.y');
67+
coerce('camera.' + cameraKeys[j] + '.z');
4368
}
4469

45-
for(var i = 0; i < scenesLength; i++) {
46-
var scene = scenes[i];
47-
48-
/*
49-
* Scene numbering proceeds as follows
50-
* scene
51-
* scene2
52-
* scene3
53-
*
54-
* and d.scene will be undefined or some number or number string
55-
*
56-
* Also write back a blank scene object to user layout so that some
57-
* attributes like aspectratio can be written back dynamically.
58-
*/
59-
60-
// gl3d traces get a layout scene for free!
61-
if(layoutIn[scene]) sceneLayoutIn = layoutIn[scene];
62-
else layoutIn[scene] = sceneLayoutIn = {};
63-
64-
sceneLayoutOut = layoutOut[scene] || {};
65-
66-
coerce('bgcolor');
67-
68-
var cameraKeys = Object.keys(layoutAttributes.camera);
69-
70-
for(var j = 0; j < cameraKeys.length; j++) {
71-
coerce('camera.' + cameraKeys[j] + '.x');
72-
coerce('camera.' + cameraKeys[j] + '.y');
73-
coerce('camera.' + cameraKeys[j] + '.z');
74-
}
75-
76-
coerce('domain.x', [i / scenesLength, (i+1) / scenesLength]);
77-
coerce('domain.y');
78-
79-
/*
80-
* coerce to positive number (min 0) but also do not accept 0 (>0 not >=0)
81-
* note that 0's go false with the !! call
82-
*/
83-
var hasAspect = !!coerce('aspectratio.x') &&
84-
!!coerce('aspectratio.y') &&
85-
!!coerce('aspectratio.z');
86-
87-
var defaultAspectMode = hasAspect ? 'manual' : 'auto';
88-
var aspectMode = coerce('aspectmode', defaultAspectMode);
89-
90-
/*
91-
* We need aspectratio object in all the Layouts as it is dynamically set
92-
* in the calculation steps, ie, we cant set the correct data now, it happens later.
93-
* We must also account for the case the user sends bad ratio data with 'manual' set
94-
* for the mode. In this case we must force change it here as the default coerce
95-
* misses it above.
96-
*/
97-
if(!hasAspect) {
98-
sceneLayoutIn.aspectratio = sceneLayoutOut.aspectratio = {x: 1, y: 1, z: 1};
99-
100-
if(aspectMode === 'manual') sceneLayoutOut.aspectmode = 'auto';
101-
}
102-
103-
/*
104-
* scene arrangements need to be implemented: For now just splice
105-
* along the horizontal direction. ie.
106-
* x:[0,1] -> x:[0,0.5], x:[0.5,1] ->
107-
* x:[0, 0.333] x:[0.333,0.666] x:[0.666, 1]
108-
*/
109-
supplyGl3dAxisLayoutDefaults(sceneLayoutIn, sceneLayoutOut, {
110-
font: layoutOut.font,
111-
scene: scene,
112-
data: fullData
113-
});
114-
115-
coerce('dragmode', getDfltFromLayout('dragmode'));
116-
coerce('hovermode', getDfltFromLayout('hovermode'));
117-
118-
layoutOut[scene] = sceneLayoutOut;
70+
/*
71+
* coerce to positive number (min 0) but also do not accept 0 (>0 not >=0)
72+
* note that 0's go false with the !! call
73+
*/
74+
var hasAspect = !!coerce('aspectratio.x') &&
75+
!!coerce('aspectratio.y') &&
76+
!!coerce('aspectratio.z');
77+
78+
var defaultAspectMode = hasAspect ? 'manual' : 'auto';
79+
var aspectMode = coerce('aspectmode', defaultAspectMode);
80+
81+
/*
82+
* We need aspectratio object in all the Layouts as it is dynamically set
83+
* in the calculation steps, ie, we cant set the correct data now, it happens later.
84+
* We must also account for the case the user sends bad ratio data with 'manual' set
85+
* for the mode. In this case we must force change it here as the default coerce
86+
* misses it above.
87+
*/
88+
if(!hasAspect) {
89+
sceneLayoutIn.aspectratio = sceneLayoutOut.aspectratio = {x: 1, y: 1, z: 1};
90+
91+
if(aspectMode === 'manual') sceneLayoutOut.aspectmode = 'auto';
11992
}
120-
};
93+
94+
supplyGl3dAxisLayoutDefaults(sceneLayoutIn, sceneLayoutOut, {
95+
font: opts.font,
96+
scene: opts.id,
97+
data: opts.fullData
98+
});
99+
100+
coerce('dragmode', opts.getDfltFromLayout('dragmode'));
101+
coerce('hovermode', opts.getDfltFromLayout('hovermode'));
102+
}

src/plots/subplot_defaults.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* Copyright 2012-2016, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
var Lib = require('../lib');
13+
var Plots = require('./plots');
14+
15+
16+
/**
17+
* Find and supply defaults to all subplots of a given type
18+
* This handles subplots that are contained within one container - so
19+
* gl3d, geo, ternary... but not 2d axes which have separate x and y axes
20+
* finds subplots, coerces their `domain` attributes, then calls the
21+
* given handleDefaults function to fill in everything else.
22+
*
23+
* layoutIn: the complete user-supplied input layout
24+
* layoutOut: the complete finished layout
25+
* fullData: the finished data array, used only to find subplots
26+
* opts: {
27+
* type: subplot type string
28+
* attributes: subplot attributes object
29+
* partition: 'x' or 'y', which direction to divide domain space by default
30+
* (default 'x', ie side-by-side subplots)
31+
* TODO: this option is only here because 3D and geo made opposite
32+
* choices in this regard previously and I didn't want to change it.
33+
* Instead we should do:
34+
* - something consistent
35+
* - something more square (4 cuts 2x2, 5/6 cuts 2x3, etc.)
36+
* - something that includes all subplot types in one arrangement,
37+
* now that we can have them together!
38+
* handleDefaults: function of (subplotLayoutIn, subplotLayoutOut, coerce, opts)
39+
* this opts object is passed through to handleDefaults, so attach any
40+
* additional items needed by this function here as well
41+
* }
42+
*/
43+
module.exports = function handleSubplotDefaults(layoutIn, layoutOut, fullData, opts) {
44+
var subplotType = opts.type,
45+
subplotAttributes = opts.attributes,
46+
handleDefaults = opts.handleDefaults,
47+
partition = opts.partition || 'x';
48+
49+
var ids = Plots.findSubplotIds(fullData, subplotType),
50+
idsLength = ids.length;
51+
52+
var subplotLayoutIn, subplotLayoutOut;
53+
54+
function coerce(attr, dflt) {
55+
return Lib.coerce(subplotLayoutIn, subplotLayoutOut, subplotAttributes, attr, dflt);
56+
}
57+
58+
for(var i = 0; i < idsLength; i++) {
59+
var id = ids[i];
60+
61+
// ternary traces get a layout ternary for free!
62+
if(layoutIn[id]) subplotLayoutIn = layoutIn[id];
63+
else subplotLayoutIn = layoutIn[id] = {};
64+
65+
layoutOut[id] = subplotLayoutOut = {};
66+
67+
coerce('domain.' + partition, [i / idsLength, (i + 1) / idsLength]);
68+
coerce('domain.' + {x: 'y', y: 'x'}[partition]);
69+
70+
opts.id = id;
71+
handleDefaults(subplotLayoutIn, subplotLayoutOut, coerce, opts);
72+
}
73+
};

0 commit comments

Comments
 (0)