Skip to content

Commit 739f20f

Browse files
committed
sort gl3d primitive object on updates
- ensuring that visibility toggles don't reorder the traces
1 parent a9d3621 commit 739f20f

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

src/plots/gl3d/scene.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,11 @@ proto.plot = function(sceneData, fullLayout, layout) {
419419
delete this.traces[traceIds[i]];
420420
}
421421

422+
// order object per trace index
423+
this.glplot.objects.sort(function(a, b) {
424+
return a._trace.data.index - b._trace.data.index;
425+
});
426+
422427
// Update ranges (needs to be called *after* objects are added due to updates)
423428
var sceneBounds = [[0, 0, 0], [0, 0, 0]],
424429
axisDataRange = [],

src/traces/mesh3d/convert.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ function createMesh3DTrace(scene, data) {
152152
var gl = scene.glplot.gl;
153153
var mesh = createMesh({gl: gl});
154154
var result = new Mesh3DTrace(scene, mesh, data.uid);
155+
mesh._trace = result;
155156
result.update(data);
156157
scene.glplot.add(mesh);
157158
return result;

src/traces/scatter3d/convert.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ proto.update = function(data) {
314314
if(this.linePlot) this.linePlot.update(lineOptions);
315315
else {
316316
this.linePlot = createLinePlot(lineOptions);
317+
this.linePlot._trace = this;
317318
this.scene.glplot.add(this.linePlot);
318319
}
319320
} else if(this.linePlot) {
@@ -345,6 +346,7 @@ proto.update = function(data) {
345346
if(this.scatterPlot) this.scatterPlot.update(scatterOptions);
346347
else {
347348
this.scatterPlot = createScatterPlot(scatterOptions);
349+
this.scatterPlot._trace = this;
348350
this.scatterPlot.highlightScale = 1;
349351
this.scene.glplot.add(this.scatterPlot);
350352
}
@@ -375,6 +377,7 @@ proto.update = function(data) {
375377
if(this.textMarkers) this.textMarkers.update(textOptions);
376378
else {
377379
this.textMarkers = createScatterPlot(textOptions);
380+
this.textMarkers._trace = this;
378381
this.textMarkers.highlightScale = 1;
379382
this.scene.glplot.add(this.textMarkers);
380383
}
@@ -403,6 +406,7 @@ proto.update = function(data) {
403406
}
404407
} else if(options.errorBounds) {
405408
this.errorBars = createErrorBars(errorOptions);
409+
this.errorBars._trace = this;
406410
this.scene.glplot.add(this.errorBars);
407411
}
408412

@@ -419,6 +423,7 @@ proto.update = function(data) {
419423
} else {
420424
delaunayOptions.gl = gl;
421425
this.delaunayMesh = createMesh(delaunayOptions);
426+
this.delaunayMesh._trace = this;
422427
this.scene.glplot.add(this.delaunayMesh);
423428
}
424429
} else if(this.delaunayMesh) {

src/traces/surface/convert.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ function createSurfaceTrace(scene, data) {
368368
var gl = scene.glplot.gl;
369369
var surface = createSurface({ gl: gl });
370370
var result = new SurfaceTrace(scene, surface, data.uid);
371+
surface._trace = result;
371372
result.update(data);
372373
scene.glplot.add(surface);
373374
return result;

test/jasmine/tests/gl_plot_interact_test.js

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,23 +217,64 @@ describe('Test gl3d plots', function() {
217217

218218
it('should be able to toggle visibility', function(done) {
219219
var _mock = Lib.extendDeep({}, mock2);
220-
var objects;
220+
_mock.data[0].x = [0, 1, 3];
221+
_mock.data[0].y = [0, 1, 2];
222+
_mock.data.push({
223+
type: 'surface',
224+
z: [[1, 2, 3], [1, 2, 3], [2, 1, 2]]
225+
}, {
226+
type: 'mesh3d',
227+
x: [0, 1, 2, 0], y: [0, 0, 1, 2], z: [0, 2, 0, 1],
228+
i: [0, 0, 0, 1], j: [1, 2, 3, 2], k: [2, 3, 1, 3]
229+
});
230+
231+
// scatter3d traces are made of 5 gl-vis objects,
232+
// surface and mesh3d are made of 1 gl-vis object each.
233+
var order0 = [0, 0, 0, 0, 0, 1, 2];
234+
235+
function assertObjects(expected) {
236+
var objects = gd._fullLayout.scene._scene.glplot.objects;
237+
var actual = objects.map(function(o) {
238+
return o._trace.data.index;
239+
});
240+
241+
expect(actual).toEqual(expected);
242+
}
221243

222244
Plotly.plot(gd, _mock)
223245
.then(delay)
224246
.then(function() {
225-
objects = gd._fullLayout.scene._scene.glplot.objects;
226-
expect(objects.length).toEqual(5);
247+
assertObjects(order0);
227248

228249
return Plotly.restyle(gd, 'visible', 'legendonly');
229250
})
230251
.then(function() {
231-
expect(objects.length).toEqual(0);
252+
assertObjects([]);
232253

233254
return Plotly.restyle(gd, 'visible', true);
234255
})
235256
.then(function() {
236-
expect(objects.length).toEqual(5);
257+
assertObjects(order0);
258+
259+
return Plotly.restyle(gd, 'visible', false, [0]);
260+
})
261+
.then(function() {
262+
assertObjects([1, 2]);
263+
264+
return Plotly.restyle(gd, 'visible', true, [0]);
265+
})
266+
.then(function() {
267+
assertObjects(order0);
268+
269+
return Plotly.restyle(gd, 'visible', 'legendonly', [1]);
270+
})
271+
.then(function() {
272+
assertObjects([0, 0, 0, 0, 0, 2]);
273+
274+
return Plotly.restyle(gd, 'visible', true, [1]);
275+
})
276+
.then(function() {
277+
assertObjects(order0);
237278
})
238279
.then(done);
239280
});

0 commit comments

Comments
 (0)