diff --git a/src/traces/scattergl/convert.js b/src/traces/scattergl/convert.js index 09daa559ac4..fcfa54eb6d4 100644 --- a/src/traces/scattergl/convert.js +++ b/src/traces/scattergl/convert.js @@ -104,6 +104,8 @@ function LineWithMarkers(scene, uid) { this.scatter._trace = this; this.fancyScatter = createFancyScatter(scene.glplot, this.scatterOptions); this.fancyScatter._trace = this; + + this.isVisible = false; } var proto = LineWithMarkers.prototype; @@ -232,12 +234,14 @@ function _convertColor(colors, opacities, count) { */ proto.update = function(options) { if(options.visible !== true) { + this.isVisible = false; this.hasLines = false; this.hasErrorX = false; this.hasErrorY = false; this.hasMarkers = false; } else { + this.isVisible = true; this.hasLines = subTypes.hasLines(options); this.hasErrorX = options.error_x.visible === true; this.hasErrorY = options.error_y.visible === true; @@ -250,7 +254,10 @@ proto.update = function(options) { this.bounds = [Infinity, Infinity, -Infinity, -Infinity]; this.connectgaps = !!options.connectgaps; - if(this.isFancy(options)) { + if(!this.isVisible) { + this.clear(); + } + else if(this.isFancy(options)) { this.updateFancy(options); } else { @@ -285,6 +292,22 @@ function allFastTypesLikely(a) { return true; } +proto.clear = function() { + this.lineOptions.positions = new Float64Array(0); + this.line.update(this.lineOptions); + + this.errorXOptions.positions = new Float64Array(0); + this.errorX.update(this.errorXOptions); + + this.errorYOptions.positions = new Float64Array(0); + this.errorY.update(this.errorYOptions); + + this.scatterOptions.positions = new Float64Array(0); + this.scatterOptions.glyphs = []; + this.scatter.update(this.scatterOptions); + this.fancyScatter.update(this.scatterOptions); +}; + proto.updateFast = function(options) { var x = this.xData = this.pickXData = options.x; var y = this.yData = this.pickYData = options.y; diff --git a/test/image/mocks/gl2d_scatter-marker-line-colorscales.json b/test/image/mocks/gl2d_scatter-marker-line-colorscales.json index fec83aa07ea..267977cd9a3 100644 --- a/test/image/mocks/gl2d_scatter-marker-line-colorscales.json +++ b/test/image/mocks/gl2d_scatter-marker-line-colorscales.json @@ -176,6 +176,34 @@ } }, "uid": "0a4533" + }, + { + "type": "scattergl", + "x": [], + "y": [] + }, + { + "type": "scattergl", + "y": [] + }, + { + "type": "scattergl", + "x": [] + }, + { + "type": "scattergl" + }, + { + "type": "scattergl", + "x": [1,2,3], + "y": [2,1,2], + "visible": false + }, + { + "type": "scattergl", + "x": [1,2,3], + "y": [2,1,2], + "visible": "legendonly" } ], "layout": { @@ -201,4 +229,4 @@ "autosize": true, "showlegend": false } -} \ No newline at end of file +} diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index 8cbd3b1b5a7..83abcf0c303 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -331,6 +331,39 @@ describe('Test gl plot interactions', function() { }, MODEBAR_DELAY); }); + + it('should be able to toggle visibility', function(done) { + var OBJECT_PER_TRACE = 5; + + var objects = function() { + return gd._fullLayout._plots.xy._scene2d.glplot.objects; + }; + + expect(objects().length).toEqual(OBJECT_PER_TRACE); + + Plotly.restyle(gd, 'visible', 'legendonly').then(function() { + expect(objects().length).toEqual(OBJECT_PER_TRACE); + expect(objects()[0].data.length).toEqual(0); + + return Plotly.restyle(gd, 'visible', true); + }) + .then(function() { + expect(objects().length).toEqual(OBJECT_PER_TRACE); + expect(objects()[0].data.length).not.toEqual(0); + + return Plotly.restyle(gd, 'visible', false); + }) + .then(function() { + expect(gd._fullLayout._plots.xy._scene2d).toBeUndefined(); + + return Plotly.restyle(gd, 'visible', true); + }) + .then(function() { + expect(objects().length).toEqual(OBJECT_PER_TRACE); + expect(objects()[0].data.length).not.toEqual(0); + }) + .then(done); + }); }); describe('gl3d event handlers', function() {