Skip to content

Commit 5949b8e

Browse files
committed
sort subplots
1 parent 7c8cfdf commit 5949b8e

File tree

2 files changed

+154
-79
lines changed

2 files changed

+154
-79
lines changed

src/plots/cartesian/index.js

+134-70
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ exports.finalizeSubplots = function(layoutIn, layoutOut) {
126126
*/
127127
exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
128128
var fullLayout = gd._fullLayout;
129-
var subplots = fullLayout._subplots.cartesian;
130129
var calcdata = gd.calcdata;
131130
var i;
132131

@@ -141,55 +140,75 @@ exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
141140
for(i = 0; i < calcdata.length; i++) traces.push(i);
142141
}
143142

144-
// For each subplot
145-
for(i = 0; i < subplots.length; i++) {
146-
var subplot = subplots[i];
147-
var subplotInfo = fullLayout._plots[subplot];
148-
149-
// Get all calcdata (traces) for this subplot:
150-
var cdSubplot = [];
151-
var pcd;
152-
153-
// For each trace
154-
for(var j = 0; j < calcdata.length; j++) {
155-
var cd = calcdata[j];
156-
var trace = cd[0].trace;
157-
158-
// Skip trace if whitelist provided and it's not whitelisted:
159-
// if (Array.isArray(traces) && traces.indexOf(i) === -1) continue;
160-
if(trace.xaxis + trace.yaxis === subplot) {
161-
// XXX: Should trace carpet dependencies. Only replot all carpet plots if the carpet
162-
// axis has actually changed:
163-
//
164-
// If this trace is specifically requested, add it to the list:
165-
if(traces.indexOf(trace.index) !== -1 || trace.carpet) {
166-
// Okay, so example: traces 0, 1, and 2 have fill = tonext. You animate
167-
// traces 0 and 2. Trace 1 also needs to be updated, otherwise its fill
168-
// is outdated. So this retroactively adds the previous trace if the
169-
// traces are interdependent.
170-
if(
171-
pcd &&
172-
pcd[0].trace.xaxis + pcd[0].trace.yaxis === subplot &&
173-
['tonextx', 'tonexty', 'tonext'].indexOf(trace.fill) !== -1 &&
174-
cdSubplot.indexOf(pcd) === -1
175-
) {
176-
cdSubplot.push(pcd);
143+
var trace;
144+
var subplot;
145+
var subplotZindexGroups = {};
146+
for(var t = 0; t < calcdata.length; t++) {
147+
trace = calcdata[t][0].trace;
148+
var zi = trace.zindex || 0;
149+
subplot = trace.xaxis + trace.yaxis;
150+
if(!subplotZindexGroups[zi]) subplotZindexGroups[zi] = {};
151+
if(!subplotZindexGroups[zi][subplot]) subplotZindexGroups[zi][subplot] = [];
152+
subplotZindexGroups[zi][subplot].push(calcdata[t]);
153+
}
154+
var zindices = Object.keys(subplotZindexGroups)
155+
.map(Number)
156+
.sort(Lib.sorterAsc);
157+
158+
var subplots;
159+
var zindex;
160+
var subplotLayerData = {};
161+
for(i = 0; i < zindices.length; i++) {
162+
zindex = zindices[i];
163+
subplots = Object.keys(subplotZindexGroups[zindex]);
164+
165+
// For each subplot
166+
for(var j = 0; j < subplots.length; j++) {
167+
subplot = subplots[j];
168+
var subplotInfo = fullLayout._plots[subplot];
169+
170+
// Get all calcdata (traces) for this subplot:
171+
var cdSubplot = [];
172+
var pcd;
173+
// For each trace
174+
for(var k = 0; k < subplotZindexGroups[zindex][subplot].length; k++) {
175+
var cd = subplotZindexGroups[zindex][subplot][k];
176+
trace = cd[0].trace;
177+
// Skip trace if whitelist provided and it's not whitelisted:
178+
// if (Array.isArray(traces) && traces.indexOf(i) === -1) continue;
179+
if(trace.xaxis + trace.yaxis === subplot) {
180+
// XXX: Should trace carpet dependencies. Only replot all carpet plots if the carpet
181+
// axis has actually changed:
182+
//
183+
// If this trace is specifically requested, add it to the list:
184+
if(traces.indexOf(trace.index) !== -1 || trace.carpet) {
185+
// Okay, so example: traces 0, 1, and 2 have fill = tonext. You animate
186+
// traces 0 and 2. Trace 1 also needs to be updated, otherwise its fill
187+
// is outdated. So this retroactively adds the previous trace if the
188+
// traces are interdependent.
189+
if(
190+
pcd &&
191+
pcd[0].trace.xaxis + pcd[0].trace.yaxis === subplot &&
192+
['tonextx', 'tonexty', 'tonext'].indexOf(trace.fill) !== -1 &&
193+
cdSubplot.indexOf(pcd) === -1
194+
) {
195+
cdSubplot.push(pcd);
196+
}
197+
cdSubplot.push(cd);
177198
}
178199

179-
cdSubplot.push(cd);
200+
// Track the previous trace on this subplot for the retroactive-add step
201+
// above:
202+
pcd = cd;
180203
}
181-
182-
// Track the previous trace on this subplot for the retroactive-add step
183-
// above:
184-
pcd = cd;
185204
}
205+
if(!subplotLayerData[subplot]) subplotLayerData[subplot] = [];
206+
subplotLayerData[subplot] = plotOne(gd, subplotInfo, cdSubplot, transitionOpts, makeOnCompleteCallback, subplotLayerData[subplot]);
186207
}
187-
// Plot the traces for this subplot
188-
plotOne(gd, subplotInfo, cdSubplot, transitionOpts, makeOnCompleteCallback);
189208
}
190209
};
191210

192-
function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback) {
211+
function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback, layerData) {
193212
var traceLayerClasses = constants.traceLayerClasses;
194213
var fullLayout = gd._fullLayout;
195214
var modules = fullLayout._modules;
@@ -205,7 +224,6 @@ function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback
205224
traceZorderGroups[zi].push(cdSubplot[t]);
206225
}
207226

208-
var layerData = [];
209227
var zoomScaleQueryParts = [];
210228

211229
// Plot each zorder group in ascending order
@@ -222,7 +240,8 @@ function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback
222240

223241
if(categories.svg) {
224242
var classBaseName = (_module.layerName || name + 'layer');
225-
var className = classBaseName + (z ? Number(z) + 1 : '');
243+
//var className = classBaseName + (z ? Number(z) + 1 : '');
244+
var className = classBaseName + '_' + zorder;
226245
var plotMethod = _module.plot;
227246

228247
// plot all visible traces of this type on this subplot at once
@@ -235,7 +254,7 @@ function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback
235254
if(cdModule.length) {
236255
layerData.push({
237256
i: traceLayerClasses.indexOf(classBaseName),
238-
zorder: z,
257+
zorder: zorder,
239258
className: className,
240259
plotMethod: plotMethod,
241260
cdModule: cdModule
@@ -307,6 +326,7 @@ function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback
307326
plotinfo.zoomScaleTxt = traces.selectAll('.textpoint');
308327
}
309328
}
329+
return layerData;
310330
}
311331

312332
exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {
@@ -378,15 +398,16 @@ exports.drawFramework = function(gd) {
378398

379399
var subplotLayers = fullLayout._cartesianlayer.selectAll('.subplot')
380400
.data(subplotData, String);
381-
401+
382402
subplotLayers.enter().append('g')
383403
.attr('class', function(d) { return 'subplot ' + d[0]; });
384404

385-
subplotLayers.order();
386-
387-
subplotLayers.exit()
388-
.call(purgeSubplotLayers, fullLayout);
405+
//subplotLayers.order();
389406

407+
//subplotLayers.exit()
408+
// .call(purgeSubplotLayers, fullLayout);
409+
console.log("Subplotlayers")
410+
console.log(subplotLayers)
390411
subplotLayers.each(function(d) {
391412
var id = d[0];
392413
var plotinfo = fullLayout._plots[id];
@@ -417,29 +438,67 @@ function makeSubplotData(gd) {
417438
var regulars = [];
418439
var overlays = [];
419440

420-
for(i = 0; i < len; i++) {
421-
id = ids[i];
422-
plotinfo = fullLayout._plots[id];
423-
xa = plotinfo.xaxis;
424-
ya = plotinfo.yaxis;
425-
426-
var xa2 = xa._mainAxis;
427-
var ya2 = ya._mainAxis;
428-
var mainplot = xa2._id + ya2._id;
429-
var mainplotinfo = fullLayout._plots[mainplot];
430-
plotinfo.overlays = [];
441+
var calcdata = gd.calcdata;
431442

432-
if(mainplot !== id && mainplotinfo) {
433-
plotinfo.mainplot = mainplot;
434-
plotinfo.mainplotinfo = mainplotinfo;
435-
overlays.push(id);
436-
} else {
437-
plotinfo.mainplot = undefined;
438-
plotinfo.mainplotinfo = undefined;
439-
regulars.push(id);
443+
var trace;
444+
var subplot;
445+
var subplotZindexGroups = {};
446+
for(var t = 0; t < calcdata.length; t++) {
447+
trace = calcdata[t][0].trace;
448+
var zi = trace.zindex || 0;
449+
subplot = trace.xaxis + trace.yaxis;
450+
if(!subplotZindexGroups[zi]) subplotZindexGroups[zi] = {};
451+
if(!subplotZindexGroups[zi][subplot]) subplotZindexGroups[zi][subplot] = [];
452+
subplotZindexGroups[zi][subplot].push(calcdata[t]);
453+
}
454+
var zindices = Object.keys(subplotZindexGroups)
455+
.map(Number)
456+
.sort(Lib.sorterAsc);
457+
458+
console.log(subplotZindexGroups)
459+
460+
for(i = 0; i < zindices.length; i++) {
461+
console.log(i)
462+
var zindex = subplotZindexGroups[zindices[i]];
463+
console.log(zindex)
464+
console.log()
465+
var ids = Object.keys(zindex);
466+
for(var j=0; j<ids.length; j++) {
467+
var id = ids[j];
468+
plotinfo = fullLayout._plots[id];
469+
//xa = plotinfo.xaxis;
470+
//ya = plotinfo.yaxis;
471+
472+
//var xa2 = xa._mainAxis;
473+
//var ya2 = ya._mainAxis;
474+
var mainplot = mainplot ? mainplot : id;//xa2._id + ya2._id;
475+
var mainplotinfo = fullLayout._plots[mainplot];
476+
plotinfo.overlays = [];
477+
478+
if(i!==0) {//if(mainplot !== id && mainplotinfo) {
479+
console.log("hererere")
480+
plotinfo.mainplot = mainplot;
481+
plotinfo.mainplotinfo = mainplotinfo;
482+
overlays.push(id);
483+
} else {
484+
plotinfo.mainplot = undefined;
485+
plotinfo.mainplotinfo = undefined;
486+
regulars.push(id);
487+
}
488+
console.log(".....")
440489
}
490+
491+
}
492+
console.log(plotinfo.mainplotinfo)
493+
console.log("----")
494+
console.log(regulars, overlays)
495+
function onlyUnique(value, index, array) {
496+
return array.indexOf(value) === index;
441497
}
442498

499+
regulars = regulars.filter(onlyUnique);
500+
overlays = overlays.filter(onlyUnique);
501+
console.log(regulars, overlays)
443502
// fill in list of overlaying subplots in 'main plot'
444503
for(i = 0; i < overlays.length; i++) {
445504
id = overlays[i];
@@ -454,6 +513,7 @@ function makeSubplotData(gd) {
454513
for(i = 0; i < len; i++) {
455514
id = subplotIds[i];
456515
plotinfo = fullLayout._plots[id];
516+
console.log(id, plotinfo)
457517
xa = plotinfo.xaxis;
458518
ya = plotinfo.yaxis;
459519

@@ -538,8 +598,12 @@ function makeSubplotLayer(gd, plotinfo) {
538598
plotinfo.minorGridlayer = mainplotinfo.minorGridlayer;
539599
plotinfo.gridlayer = mainplotinfo.gridlayer;
540600
plotinfo.zerolinelayer = mainplotinfo.zerolinelayer;
541-
601+
console.log(xId)
602+
console.log(mainplotinfo)
603+
console.log(mainplotinfo.overlinesBelow)
542604
ensureSingle(mainplotinfo.overlinesBelow, 'path', xId);
605+
console.log(yId)
606+
543607
ensureSingle(mainplotinfo.overlinesBelow, 'path', yId);
544608
ensureSingle(mainplotinfo.overaxesBelow, 'g', xId);
545609
ensureSingle(mainplotinfo.overaxesBelow, 'g', yId);

test/image/mocks/zindex_mult_axes.json renamed to test/image/mocks/zorder_mult_axes.json

+20-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"marker": {"size": 20},
99
"line": {"width": 6},
1010
"yaxis": "y",
11-
"zindex": 5
11+
"xaxis": "x",
12+
"zorder": 10
1213
},
1314
{
1415
"x": [2, 3, 4, 5, 6],
@@ -17,8 +18,9 @@
1718
"type": "scatter",
1819
"marker": {"size": 20},
1920
"line": {"width": 6},
20-
"yaxis": "y",
21-
"zindex": 1
21+
"yaxis": "y2",
22+
"xaxis": "x2",
23+
"zorder": 5
2224
},
2325
{
2426
"x": [3, 4, 5, 6, 7],
@@ -27,7 +29,9 @@
2729
"type": "scatter",
2830
"marker": {"size": 20},
2931
"line": {"width": 6},
30-
"yaxis": "y2"
32+
"yaxis": "y2",
33+
"xaxis": "x",
34+
"zorder": 7
3135
},
3236

3337
{
@@ -36,20 +40,27 @@
3640
"name": "bar",
3741
"type": "bar",
3842
"yaxis": "y2",
39-
"zindex": 20
43+
"xaxis": "x2",
44+
"zorder": 8
4045
}
4146
],
4247
"layout": {
4348
"xaxis": {
49+
"side": "top",
4450
"title": {
45-
"text": "zindex stacking"
51+
"text": "zorder stacking"
4652
}
53+
, "overlaying": "x2"
54+
},
55+
"x2axis": {
56+
"title":{"text":"x2"}
4757
},
4858
"yaxis": {
49-
"side": "right"
59+
"side": "right",
60+
"title":{"text":"y"}, "overlaying": "y2"
5061
},
5162
"y2axis": {
52-
"title":{"text":"y2"}, "overlaying": "y"
63+
"title":{"text":"y2"}
5364
}
5465
}
55-
}
66+
}

0 commit comments

Comments
 (0)