Skip to content

Commit 1903061

Browse files
committed
Merge pull request #491 from plotly/has-plot-type
Replace _has<PlotType> variables with '_has()' fullLayout method
2 parents 5790ac4 + 5e6759b commit 1903061

29 files changed

+325
-262
lines changed

src/components/modebar/buttons.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ function handleCartesian(gd, ev) {
256256

257257
Plotly.relayout(gd, aobj).then(function() {
258258
if(astr === 'dragmode') {
259-
if(fullLayout._hasCartesian) {
259+
if(fullLayout._has('cartesian')) {
260260
setCursor(
261261
fullLayout._paper.select('.nsewdrag'),
262262
DRAGCURSORS[val]
@@ -502,7 +502,7 @@ function toggleHover(gd) {
502502
var fullLayout = gd._fullLayout;
503503

504504
var onHoverVal;
505-
if(fullLayout._hasCartesian) {
505+
if(fullLayout._has('cartesian')) {
506506
onHoverVal = fullLayout._isHoriz ? 'y' : 'x';
507507
}
508508
else onHoverVal = 'closest';

src/components/modebar/manage.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ function getButtonGroups(gd, buttonsToRemove, buttonsToAdd) {
7373
var fullLayout = gd._fullLayout,
7474
fullData = gd._fullData;
7575

76-
var hasCartesian = !!fullLayout._hasCartesian,
77-
hasGL3D = !!fullLayout._hasGL3D,
78-
hasGeo = !!fullLayout._hasGeo,
79-
hasPie = !!fullLayout._hasPie,
80-
hasGL2D = !!fullLayout._hasGL2D,
81-
hasTernary = !!fullLayout._hasTernary;
76+
var hasCartesian = fullLayout._has('cartesian'),
77+
hasGL3D = fullLayout._has('gl3d'),
78+
hasGeo = fullLayout._has('geo'),
79+
hasPie = fullLayout._has('pie'),
80+
hasGL2D = fullLayout._has('gl2d'),
81+
hasTernary = fullLayout._has('ternary');
8282

8383
var groups = [];
8484

src/components/rangeslider/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function draw(gd) {
4141
var height = (fullLayout.height - fullLayout.margin.b - fullLayout.margin.t) * options.thickness,
4242
offsetShift = Math.floor(options.borderwidth / 2);
4343

44-
if(sliderContainer[0].length === 0 && !fullLayout._hasGL2D) createSlider(gd);
44+
if(sliderContainer[0].length === 0 && !fullLayout._has('gl2d')) createSlider(gd);
4545

4646
// Need to default to 0 for when making gl plots
4747
var bb = fullLayout.xaxis._boundingBox ?

src/lib/index.js

+17
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,23 @@ lib.noneOrAll = function(containerIn, containerOut, attrList) {
335335
}
336336
};
337337

338+
/**
339+
* Push array with unique items
340+
*
341+
* @param {array} array
342+
* array to be filled
343+
* @param {any} item
344+
* item to be or not to be inserted
345+
* @return {array}
346+
* ref to array (now possibly containing one more item)
347+
*
348+
*/
349+
lib.pushUnique = function(array, item) {
350+
if(item && array.indexOf(item) === -1) array.push(item);
351+
352+
return array;
353+
};
354+
338355
lib.mergeArray = function(traceAttr, cd, cdAttr) {
339356
if(Array.isArray(traceAttr)) {
340357
var imax = Math.min(traceAttr.length, cd.length);

src/plot_api/plot_api.js

+16-23
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ Plotly.plot = function(gd, data, layout, config) {
205205
if(!recalc) return;
206206

207207
var subplots = Plots.getSubplotIds(fullLayout, 'cartesian'),
208-
modules = gd._modules;
208+
modules = fullLayout._modules;
209209

210210
// position and range calculations for traces that
211211
// depend on each other ie bars (stacked or grouped)
@@ -250,11 +250,12 @@ Plotly.plot = function(gd, data, layout, config) {
250250

251251
// Now plot the data
252252
function drawData() {
253-
var calcdata = gd.calcdata;
253+
var calcdata = gd.calcdata,
254+
i;
254255

255256
// in case of traces that were heatmaps or contour maps
256257
// previously, remove them and their colorbars explicitly
257-
for(var i = 0; i < calcdata.length; i++) {
258+
for(i = 0; i < calcdata.length; i++) {
258259
var trace = calcdata[i][0].trace,
259260
isVisible = (trace.visible === true),
260261
uid = trace.uid;
@@ -272,18 +273,11 @@ Plotly.plot = function(gd, data, layout, config) {
272273
}
273274
}
274275

275-
var plotRegistry = Plots.subplotsRegistry;
276-
277-
if(fullLayout._hasGL3D) plotRegistry.gl3d.plot(gd);
278-
if(fullLayout._hasGeo) plotRegistry.geo.plot(gd);
279-
if(fullLayout._hasGL2D) plotRegistry.gl2d.plot(gd);
280-
if(fullLayout._hasCartesian || fullLayout._hasPie) {
281-
plotRegistry.cartesian.plot(gd);
276+
// loop over the base plot modules present on graph
277+
var basePlotModules = fullLayout._basePlotModules;
278+
for(i = 0; i < basePlotModules.length; i++) {
279+
basePlotModules[i].plot(gd);
282280
}
283-
if(fullLayout._hasTernary) plotRegistry.ternary.plot(gd);
284-
285-
// clean up old scenes that no longer have associated data
286-
// will this be a performance hit?
287281

288282
// styling separate from drawing
289283
Plots.style(gd);
@@ -1661,10 +1655,12 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
16611655
axlist,
16621656
flagAxForDelete = {};
16631657

1664-
// for now, if we detect gl or geo stuff, just re-do the plot
1665-
if(fullLayout._hasGL3D || fullLayout._hasGeo || fullLayout._hasGL2D) {
1666-
doplot = true;
1667-
}
1658+
// At the moment, only cartesian, pie and ternary plot types can afford
1659+
// to not go through a full replot
1660+
var doPlotWhiteList = ['cartesian', 'pie', 'ternary'];
1661+
fullLayout._basePlotModules.forEach(function(_module) {
1662+
if(doPlotWhiteList.indexOf(_module.name) === -1) doplot = true;
1663+
});
16681664

16691665
// make a new empty vals array for undoit
16701666
function a0() { return traces.map(function() { return undefined; }); }
@@ -2309,7 +2305,7 @@ Plotly.relayout = function relayout(gd, astr, val) {
23092305
if(p.parts[0].indexOf('scene') === 0) doplot = true;
23102306
else if(p.parts[0].indexOf('geo') === 0) doplot = true;
23112307
else if(p.parts[0].indexOf('ternary') === 0) doplot = true;
2312-
else if(fullLayout._hasGL2D &&
2308+
else if(fullLayout._has('gl2d') &&
23132309
(ai.indexOf('axis') !== -1 || p.parts[0] === 'plot_bgcolor')
23142310
) doplot = true;
23152311
else if(ai === 'hiddenlabels') docalc = true;
@@ -2582,9 +2578,6 @@ function makePlotFramework(gd) {
25822578
var gd3 = d3.select(gd),
25832579
fullLayout = gd._fullLayout;
25842580

2585-
// TODO - find a better place for 3D to initialize axes
2586-
if(fullLayout._hasGL3D) Plots.subplotsRegistry.gl3d.initAxes(gd);
2587-
25882581
// Plot container
25892582
fullLayout._container = gd3.selectAll('.plot-container').data([0]);
25902583
fullLayout._container.enter().insert('div', ':first-child')
@@ -2659,7 +2652,7 @@ function makePlotFramework(gd) {
26592652
makeSubplots(gd, subplots);
26602653
}
26612654

2662-
if(fullLayout._hasCartesian) makeCartesianPlotFramwork(gd, subplots);
2655+
if(fullLayout._has('cartesian')) makeCartesianPlotFramwork(gd, subplots);
26632656

26642657
// single ternary layer for the whole plot
26652658
fullLayout._ternarylayer = fullLayout._paper.append('g').classed('ternarylayer', true);

src/plot_api/plot_schema.js

+2
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ function handleSubplotObjs(layoutAttributes) {
286286
var subplotRegistry = subplotsRegistry[subplotType],
287287
isSubplotObj;
288288

289+
if(!subplotRegistry.attrRegex) return;
290+
289291
if(subplotType === 'cartesian' || subplotType === 'gl2d') {
290292
isSubplotObj = (
291293
subplotRegistry.attrRegex.x.test(k) ||

src/plots/cartesian/axes.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ axes.getFromTrace = axisIds.getFromTrace;
3939
// find the list of possible axes to reference with an xref or yref attribute
4040
// and coerce it to that list
4141
axes.coerceRef = function(containerIn, containerOut, gd, axLetter) {
42-
var axlist = gd._fullLayout._hasGL2D ? [] : axes.listIds(gd, axLetter),
42+
var axlist = gd._fullLayout._has('gl2d') ? [] : axes.listIds(gd, axLetter),
4343
refAttr = axLetter + 'ref',
4444
attrDef = {};
4545

@@ -1797,7 +1797,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
17971797
var alldone = axes.getSubplots(gd, ax).map(function(subplot) {
17981798
var plotinfo = fullLayout._plots[subplot];
17991799

1800-
if(!fullLayout._hasCartesian) return;
1800+
if(!fullLayout._has('cartesian')) return;
18011801

18021802
var container = plotinfo[axletter + 'axislayer'],
18031803

src/plots/cartesian/graph_interact.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fx.supplyLayoutDefaults = function(layoutIn, layoutOut, fullData) {
6060
coerce('dragmode');
6161

6262
var hovermodeDflt;
63-
if(layoutOut._hasCartesian) {
63+
if(layoutOut._has('cartesian')) {
6464
// flag for 'horizontal' plots:
6565
// determines the state of the mode bar 'compare' hovermode button
6666
var isHoriz = layoutOut._isHoriz = fx.isHoriz(fullData);
@@ -89,7 +89,7 @@ fx.isHoriz = function(fullData) {
8989
fx.init = function(gd) {
9090
var fullLayout = gd._fullLayout;
9191

92-
if(!fullLayout._hasCartesian || gd._context.staticPlot) return;
92+
if(!fullLayout._has('cartesian') || gd._context.staticPlot) return;
9393

9494
var subplots = Object.keys(fullLayout._plots || {}).sort(function(a,b) {
9595
// sort overlays last, then by x axis number, then y axis number
@@ -107,7 +107,7 @@ fx.init = function(gd) {
107107
subplots.forEach(function(subplot) {
108108
var plotinfo = fullLayout._plots[subplot];
109109

110-
if(!fullLayout._hasCartesian) return;
110+
if(!fullLayout._has('cartesian')) return;
111111

112112
var xa = plotinfo.x(),
113113
ya = plotinfo.y(),

src/plots/cartesian/index.js

+1-18
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ exports.plot = function(gd) {
3030
var fullLayout = gd._fullLayout,
3131
subplots = Plots.getSubplotIds(fullLayout, 'cartesian'),
3232
calcdata = gd.calcdata,
33-
modules = gd._modules;
33+
modules = fullLayout._modules;
3434

3535
function getCdSubplot(calcdata, subplot) {
3636
var cdSubplot = [];
@@ -78,28 +78,11 @@ exports.plot = function(gd) {
7878
// skip over non-cartesian trace modules
7979
if(_module.basePlotModule.name !== 'cartesian') continue;
8080

81-
// skip over pies, there are drawn below
82-
if(_module.name === 'pie') continue;
83-
8481
// plot all traces of this type on this subplot at once
8582
var cdModule = getCdModule(cdSubplot, _module);
8683
_module.plot(gd, subplotInfo, cdModule);
8784

8885
Lib.markTime('done ' + (cdModule[0] && cdModule[0][0].trace.type));
8986
}
9087
}
91-
92-
// now draw stuff not on subplots (ie, only pies at the moment)
93-
if(fullLayout._hasPie) {
94-
var Pie = Plots.getModule('pie');
95-
var cdPie = getCdModule(calcdata, Pie);
96-
97-
if(cdPie.length) Pie.plot(gd, cdPie);
98-
}
99-
};
100-
101-
exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {
102-
if(oldFullLayout._hasPie && !newFullLayout._hasPie) {
103-
oldFullLayout._pielayer.selectAll('g.trace').remove();
104-
}
10588
};

src/plots/cartesian/layout_defaults.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
7171
// if gl3d or geo is present on graph. This is retain backward compatible.
7272
//
7373
// TODO drop this in version 2.0
74-
var ignoreOrphan = (layoutOut._hasGL3D || layoutOut._hasGeo);
74+
var ignoreOrphan = (layoutOut._has('gl3d') || layoutOut._has('geo'));
7575

7676
if(!ignoreOrphan) {
7777
for(i = 0; i < layoutKeys.length; i++) {
@@ -95,7 +95,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
9595
// make sure that plots with orphan cartesian axes
9696
// are considered 'cartesian'
9797
if(xaListCartesian.length && yaListCartesian.length) {
98-
layoutOut._hasCartesian = true;
98+
Lib.pushUnique(layoutOut._basePlotModules, Plots.subplotsRegistry.cartesian);
9999
}
100100

101101
function axSort(a, b) {

src/plots/geo/layout/defaults.js

-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ var supplyGeoAxisLayoutDefaults = require('./axis_defaults');
1616

1717

1818
module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
19-
if(!layoutOut._hasGeo) return;
20-
2119
handleSubplotDefaults(layoutIn, layoutOut, fullData, {
2220
type: 'geo',
2321
attributes: layoutAttributes,

src/plots/gl3d/index.js

+12-16
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ exports.plot = function plotGl3d(gd) {
4646
for(var i = 0; i < sceneIds.length; i++) {
4747
var sceneId = sceneIds[i],
4848
fullSceneData = Plots.getSubplotData(fullData, 'gl3d', sceneId),
49-
scene = fullLayout[sceneId]._scene; // ref. to corresp. Scene instance
49+
sceneLayout = fullLayout[sceneId],
50+
scene = sceneLayout._scene;
5051

5152
// If Scene is not instantiated, create one!
5253
if(scene === undefined) {
54+
initAxes(gd, sceneLayout);
55+
5356
scene = new Scene({
5457
id: sceneId,
5558
graphDiv: gd,
@@ -60,10 +63,11 @@ exports.plot = function plotGl3d(gd) {
6063
fullLayout
6164
);
6265

63-
fullLayout[sceneId]._scene = scene; // set ref to Scene instance
66+
// set ref to Scene instance
67+
sceneLayout._scene = scene;
6468
}
6569

66-
scene.plot(fullSceneData, fullLayout, gd.layout); // takes care of business
70+
scene.plot(fullSceneData, fullLayout, gd.layout);
6771
}
6872
};
6973

@@ -91,18 +95,10 @@ exports.cleanId = function cleanId(id) {
9195

9296
exports.setConvert = require('./set_convert');
9397

94-
exports.initAxes = function(gd) {
95-
var fullLayout = gd._fullLayout;
96-
var sceneIds = Plots.getSubplotIds(fullLayout, 'gl3d');
97-
98-
for(var i = 0; i < sceneIds.length; ++i) {
99-
var sceneId = sceneIds[i];
100-
var sceneLayout = fullLayout[sceneId];
98+
function initAxes(gd, sceneLayout) {
99+
for(var j = 0; j < 3; ++j) {
100+
var axisName = axesNames[j];
101101

102-
for(var j = 0; j < 3; ++j) {
103-
var axisName = axesNames[j];
104-
var ax = sceneLayout[axisName];
105-
ax._gd = gd;
106-
}
102+
sceneLayout[axisName]._gd = gd;
107103
}
108-
};
104+
}

src/plots/gl3d/layout/defaults.js

+5-7
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@ var supplyGl3dAxisLayoutDefaults = require('./axis_defaults');
1717

1818

1919
module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
20-
if(!layoutOut._hasGL3D) return;
21-
2220
var hasNon3D = (
23-
layoutOut._hasCartesian ||
24-
layoutOut._hasGeo ||
25-
layoutOut._hasGL2D ||
26-
layoutOut._hasPie ||
27-
layoutOut._hasTernary
21+
layoutOut._has('cartesian') ||
22+
layoutOut._has('geo') ||
23+
layoutOut._has('gl2d') ||
24+
layoutOut._has('pie') ||
25+
layoutOut._has('ternary')
2826
);
2927

3028
// some layout-wide attribute are used in all scenes

src/plots/layout_attributes.js

+1-24
Original file line numberDiff line numberDiff line change
@@ -168,30 +168,7 @@ module.exports = {
168168
role: 'info',
169169
description: 'Determines whether or not a legend is drawn.'
170170
},
171-
_hasCartesian: {
172-
valType: 'boolean',
173-
dflt: false
174-
},
175-
_hasGL3D: {
176-
valType: 'boolean',
177-
dflt: false
178-
},
179-
_hasGeo: {
180-
valType: 'boolean',
181-
dflt: false
182-
},
183-
_hasPie: {
184-
valType: 'boolean',
185-
dflt: false
186-
},
187-
_hasGL2D: {
188-
valType: 'boolean',
189-
dflt: false
190-
},
191-
_hasTernary: {
192-
valType: 'boolean',
193-
dflt: false
194-
},
171+
195172
_composedModules: {
196173
'*': 'Fx'
197174
},

0 commit comments

Comments
 (0)