Skip to content

Commit 71d3151

Browse files
committed
first cut splom
1 parent a10e799 commit 71d3151

File tree

10 files changed

+396
-15
lines changed

10 files changed

+396
-15
lines changed

lib/index-gl2d.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var Plotly = require('./core');
1212

1313
Plotly.register([
1414
require('./scattergl'),
15+
require('./splom'),
1516
require('./pointcloud'),
1617
require('./heatmapgl'),
1718
require('./contourgl'),

lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Plotly.register([
3131
require('./choropleth'),
3232

3333
require('./scattergl'),
34+
require('./splom'),
35+
3436
require('./pointcloud'),
3537
require('./heatmapgl'),
3638
require('./parcoords'),

lib/splom.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright 2012-2018, 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+
'use strict';
10+
11+
module.exports = require('../src/traces/splom');

src/components/grid/index.js

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -165,15 +165,26 @@ var gridAttrs = {
165165
editType: 'plot'
166166
};
167167

168+
function getAxes(layout, grid, axLetter) {
169+
var gridVal = grid[axLetter + 'axes'];
170+
var splomVal = layout[{x: '_splomXaxes', y: '_splomYaxes'}[axLetter]] || [];
171+
172+
if(Array.isArray(gridVal)) return gridVal;
173+
if(splomVal.length) return splomVal;
174+
}
175+
168176
// the shape of the grid - this needs to be done BEFORE supplyDataDefaults
169177
// so that non-subplot traces can place themselves in the grid
170178
function sizeDefaults(layoutIn, layoutOut) {
171-
var gridIn = layoutIn.grid;
172-
if(!gridIn) return;
179+
var gridIn = layoutIn.grid || {};
180+
var xAxes = getAxes(layoutOut, gridIn, 'x');
181+
var yAxes = getAxes(layoutOut, gridIn, 'y');
182+
183+
if(!layoutIn.grid && !xAxes && !yAxes) return;
173184

174185
var hasSubplotGrid = Array.isArray(gridIn.subplots) && Array.isArray(gridIn.subplots[0]);
175-
var hasXaxes = Array.isArray(gridIn.xaxes);
176-
var hasYaxes = Array.isArray(gridIn.yaxes);
186+
var hasXaxes = Array.isArray(xAxes);
187+
var hasYaxes = Array.isArray(yAxes);
177188

178189
var dfltRows, dfltColumns;
179190

@@ -182,8 +193,8 @@ function sizeDefaults(layoutIn, layoutOut) {
182193
dfltColumns = gridIn.subplots[0].length;
183194
}
184195
else {
185-
if(hasYaxes) dfltRows = gridIn.yaxes.length;
186-
if(hasXaxes) dfltColumns = gridIn.xaxes.length;
196+
if(hasYaxes) dfltRows = yAxes.length;
197+
if(hasXaxes) dfltColumns = xAxes.length;
187198
}
188199

189200
var gridOut = layoutOut.grid = {};
@@ -236,7 +247,7 @@ function contentDefaults(layoutIn, layoutOut) {
236247
// make sure we got to the end of handleGridSizing
237248
if(!gridOut || !gridOut._domains) return;
238249

239-
var gridIn = layoutIn.grid;
250+
var gridIn = layoutIn.grid || {};
240251
var subplots = layoutOut._subplots;
241252
var hasSubplotGrid = gridOut._hasSubplotGrid;
242253
var rows = gridOut.rows;
@@ -282,8 +293,10 @@ function contentDefaults(layoutIn, layoutOut) {
282293
}
283294
}
284295
else {
285-
gridOut.xaxes = fillGridAxes(gridIn.xaxes, subplots.xaxis, columns, axisMap, 'x');
286-
gridOut.yaxes = fillGridAxes(gridIn.yaxes, subplots.yaxis, rows, axisMap, 'y');
296+
var xAxes = getAxes(layoutOut, gridIn, 'x');
297+
var yAxes = getAxes(layoutOut, gridIn, 'y');
298+
gridOut.xaxes = fillGridAxes(xAxes, subplots.xaxis, columns, axisMap, 'x');
299+
gridOut.yaxes = fillGridAxes(yAxes, subplots.yaxis, rows, axisMap, 'y');
287300
}
288301

289302
var anchors = gridOut._anchors = {};

src/plots/cartesian/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout)
226226

227227
var hadScatter, hasScatter, hadGl, hasGl, i, oldPlots, ids, subplotInfo, moduleName;
228228

229-
230229
for(i = 0; i < oldModules.length; i++) {
231230
moduleName = oldModules[i].name;
232231
if(moduleName === 'scatter') hadScatter = true;
@@ -272,8 +271,13 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout)
272271
}
273272
}
274273

274+
exports.cleanSubplots(newFullData, newFullLayout, oldFullData, oldFullLayout);
275+
};
276+
277+
exports.cleanSubplots = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {
275278
var oldSubplotList = oldFullLayout._subplots || {};
276279
var newSubplotList = newFullLayout._subplots || {xaxis: [], yaxis: []};
280+
var i;
277281

278282
// delete any titles we don't need anymore
279283
// check if axis list has changed, and if so clear old titles

src/plots/plots.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ plots.supplyDefaults = function(gd) {
289289

290290
var context = gd._context || {};
291291

292-
var i;
292+
var i, j;
293293

294294
// Create all the storage space for frames, but only if doesn't already exist
295295
if(!gd._transitionData) plots.createTransitionData(gd);
@@ -321,7 +321,6 @@ plots.supplyDefaults = function(gd) {
321321

322322
// first fill in what we can of layout without looking at data
323323
// because fullData needs a few things from layout
324-
325324
if(oldFullLayout._initialAutoSizeIsDone) {
326325

327326
// coerce the updated layout while preserving width and height
@@ -364,12 +363,28 @@ plots.supplyDefaults = function(gd) {
364363
// clear the lists of trace and baseplot modules, and subplots
365364
newFullLayout._modules = [];
366365
newFullLayout._basePlotModules = [];
367-
newFullLayout._subplots = emptySubplotLists();
366+
var subplots = newFullLayout._subplots = emptySubplotLists();
367+
var splomXaxes = newFullLayout._splomXaxes = [];
368+
var splomYaxes = newFullLayout._splomYaxes = [];
368369

369370
// then do the data
370371
newFullLayout._globalTransforms = (gd._context || {}).globalTransforms;
371372
plots.supplyDataDefaults(newData, newFullData, newLayout, newFullLayout);
372373

374+
// redo grid size defaults with info about splom x/y axes,
375+
// and fill in generated cartesian axes and subplots
376+
if(splomXaxes.length && splomYaxes.length) {
377+
Registry.getComponentMethod('grid', 'sizeDefaults')(newLayout, newFullLayout);
378+
379+
for(i = 0; i < splomXaxes.length; i++) {
380+
Lib.pushUnique(subplots.xaxis, splomXaxes[i]);
381+
for(j = 0; j < splomYaxes.length; j++) {
382+
if(i === 0) Lib.pushUnique(subplots.yaxis, splomYaxes[j]);
383+
Lib.pushUnique(subplots.cartesian, splomXaxes[i] + splomYaxes[j]);
384+
}
385+
}
386+
}
387+
373388
// attach helper method to check whether a plot type is present on graph
374389
newFullLayout._has = plots._hasPlotType.bind(newFullLayout);
375390

@@ -865,7 +880,8 @@ plots.supplyDataDefaults = function(dataIn, dataOut, layout, fullLayout) {
865880
var cnt = 0;
866881
var colorCnt = 0;
867882

868-
var i, fullTrace, trace;
883+
var fullTrace, trace;
884+
var i, j;
869885

870886
fullLayout._transformModules = [];
871887

@@ -904,7 +920,7 @@ plots.supplyDataDefaults = function(dataIn, dataOut, layout, fullLayout) {
904920
if(fullTrace.transforms && fullTrace.transforms.length) {
905921
var expandedTraces = applyTransforms(fullTrace, dataOut, layout, fullLayout);
906922

907-
for(var j = 0; j < expandedTraces.length; j++) {
923+
for(j = 0; j < expandedTraces.length; j++) {
908924
var expandedTrace = expandedTraces[j];
909925
var fullExpandedTrace = plots.supplyTraceDefaults(expandedTrace, cnt, fullLayout, i);
910926

@@ -1357,6 +1373,7 @@ plots.supplyLayoutModuleDefaults = function(layoutIn, layoutOut, fullData, trans
13571373
var basePlotModules = layoutOut._basePlotModules;
13581374
var component, i, _module;
13591375

1376+
13601377
var Cartesian = Registry.subplotsRegistry.cartesian;
13611378

13621379
// check if any components need to add more base plot modules

src/traces/splom/attributes.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/**
2+
* Copyright 2012-2018, 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+
'use strict';
10+
11+
var scatterGlAttrs = require('../scattergl/attributes');
12+
var cartesianIdRegex = require('../../plots/cartesian/constants').idRegex;
13+
14+
function makeAxesValObject(axLetter) {
15+
return {
16+
valType: 'info_array',
17+
freeLength: true,
18+
role: 'info',
19+
editType: 'calc',
20+
items: {
21+
valType: 'enumerated',
22+
values: [cartesianIdRegex[axLetter].toString(), ''],
23+
editType: 'plot'
24+
},
25+
description: [
26+
'..'
27+
].join(' ')
28+
};
29+
}
30+
31+
module.exports = {
32+
dimensions: {
33+
_isLinkedToArray: 'dimension',
34+
35+
visible: {
36+
valType: 'boolean',
37+
role: 'info',
38+
dflt: true,
39+
editType: 'calc',
40+
},
41+
label: {
42+
valType: 'string',
43+
role: 'info',
44+
editType: 'calc',
45+
description: ''
46+
},
47+
values: {
48+
valType: 'data_array',
49+
role: 'info',
50+
editType: 'calc+clearAxisTypes',
51+
description: [
52+
''
53+
].join(' ')
54+
},
55+
56+
// TODO should add an attribute to pin down x only vars and y only vars
57+
// like https://seaborn.pydata.org/generated/seaborn.pairplot.html
58+
// x_vars and y_vars
59+
60+
editType: 'calc+clearAxisTypes',
61+
description: [
62+
'..'
63+
].join(' ')
64+
},
65+
66+
mode: scatterGlAttrs.mode,
67+
text: scatterGlAttrs.text,
68+
69+
marker: scatterGlAttrs.marker,
70+
71+
line: scatterGlAttrs.line,
72+
connectgaps: scatterGlAttrs.connectgaps,
73+
74+
xdirection: {
75+
valType: 'enumerated',
76+
role: 'info',
77+
values: ['right', 'left'],
78+
dflt: 'right',
79+
description: ''
80+
},
81+
ydirection: {
82+
valType: 'enumerated',
83+
role: 'info',
84+
values: ['top', 'bottom'],
85+
dflt: 'bottom',
86+
description: ''
87+
},
88+
89+
xaxes: makeAxesValObject('x'),
90+
yaxes: makeAxesValObject('y'),
91+
92+
showdiagonal: {
93+
valType: 'boolean',
94+
role: 'info',
95+
dlft: true,
96+
editType: 'plot',
97+
description: ''
98+
},
99+
showupperhalf: {
100+
valType: 'boolean',
101+
role: 'info',
102+
dlft: true,
103+
editType: 'plot',
104+
description: ''
105+
},
106+
showlowerhalf: {
107+
valType: 'boolean',
108+
role: 'info',
109+
dlft: true,
110+
editType: 'plot',
111+
description: ''
112+
},
113+
114+
selected: scatterGlAttrs.selected,
115+
unselected: scatterGlAttrs.unselected,
116+
117+
opacity: scatterGlAttrs.opacity
118+
};

src/traces/splom/base_plot.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright 2012-2018, 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+
'use strict';
10+
11+
var Registry = require('../../registry');
12+
var getModuleCalcData = require('../../plots/get_data').getModuleCalcData;
13+
var Cartesian = require('../../plots/cartesian');
14+
15+
var SPLOM = 'splom';
16+
17+
function plot(gd) {
18+
var fullLayout = gd._fullLayout;
19+
var _module = Registry.getModule(SPLOM);
20+
var splomCalcData = getModuleCalcData(gd.calcdata, _module);
21+
22+
// clear gl frame, if any, since we preserve drawing buffer
23+
if(fullLayout._glcanvas && fullLayout._glcanvas.size()) {
24+
fullLayout._glcanvas.each(function(d) {
25+
if(d.regl) d.regl.clear({color: true});
26+
});
27+
}
28+
29+
for(var i = 0; i < splomCalcData.length; i++) {
30+
_module.plot(gd, {}, splomCalcData);
31+
}
32+
33+
}
34+
35+
function clean(newFullData, newFullLayout, oldFullData, oldFullLayout) {
36+
// TODO clear regl-splom instances
37+
38+
Cartesian.cleanSubplots(newFullData, newFullLayout, oldFullData, oldFullLayout);
39+
}
40+
41+
module.exports = {
42+
name: SPLOM,
43+
supplyLayoutDefaults: Cartesian.supplyLayoutDefaults,
44+
drawFramework: Cartesian.drawFramework,
45+
plot: plot,
46+
clean: clean,
47+
toSVG: Cartesian.toSVG
48+
};

0 commit comments

Comments
 (0)