From 1081e6aed875c7cfe3a5240cb7f8c0648273a08a Mon Sep 17 00:00:00 2001 From: archmoj Date: Mon, 4 Nov 2019 15:53:06 -0500 Subject: [PATCH 01/11] no need to duplicate camera on gl-plot3d scene --- src/plots/gl3d/scene.js | 16 +++++++--------- test/jasmine/tests/gl3d_plot_interact_test.js | 18 +++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index d24abe7b41b..b03fe7451e3 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -293,7 +293,7 @@ function initializeGLPlot(scene, canvas, gl) { scene.glplot.canvas.addEventListener('wheel', function(e) { if(gd._context._scrollZoom.gl3d) { - if(scene.glplot.camera._ortho) { + if(scene.camera._ortho) { var s = (e.deltaX > e.deltaY) ? 1.1 : 1.0 / 1.1; var o = scene.glplot.getAspectratio(); scene.glplot.setAspectratio({ @@ -326,8 +326,6 @@ function initializeGLPlot(scene, canvas, gl) { }, false); } - scene.glplot.camera = scene.camera; - scene.glplot.oncontextloss = function() { scene.recoverContext(); }; @@ -779,7 +777,7 @@ proto.destroy = function() { this.camera.mouseListener.enabled = false; this.container.removeEventListener('wheel', this.camera.wheelListener); - this.camera = this.glplot.camera = null; + this.camera = null; this.glplot.dispose(); this.container.parentNode.removeChild(this.container); this.glplot = null; @@ -808,19 +806,19 @@ function getLayoutCamera(camera) { // get camera position in plotly coords from 'gl-plot3d' coords proto.getCamera = function() { - this.glplot.camera.view.recalcMatrix(this.camera.view.lastT()); - return getLayoutCamera(this.glplot.camera); + this.camera.view.recalcMatrix(this.camera.view.lastT()); + return getLayoutCamera(this.camera); }; // set gl-plot3d camera position and scene aspects with a set of plotly coords proto.setViewport = function(sceneLayout) { var cameraData = sceneLayout.camera; - this.glplot.camera.lookAt.apply(this, getCameraArrays(cameraData)); + this.camera.lookAt.apply(this, getCameraArrays(cameraData)); this.glplot.setAspectratio(sceneLayout.aspectratio); var newOrtho = (cameraData.projection.type === 'orthographic'); - var oldOrtho = this.glplot.camera._ortho; + var oldOrtho = this.camera._ortho; if(newOrtho !== oldOrtho) { this.glplot.redraw(); @@ -837,7 +835,7 @@ proto.setViewport = function(sceneLayout) { this.glplot.dispose(); initializeGLPlot(this); - this.glplot.camera._ortho = newOrtho; + this.camera._ortho = newOrtho; } }; diff --git a/test/jasmine/tests/gl3d_plot_interact_test.js b/test/jasmine/tests/gl3d_plot_interact_test.js index 91915c621f8..5f60b2e3130 100644 --- a/test/jasmine/tests/gl3d_plot_interact_test.js +++ b/test/jasmine/tests/gl3d_plot_interact_test.js @@ -93,7 +93,7 @@ describe('Test gl3d before/after plot', function() { }) .then(delay(20)) .then(function() { - var cameraBefore = gd._fullLayout.scene._scene.glplot.camera; + var cameraBefore = gd._fullLayout.scene._scene.camera; expect(cameraBefore.up[0]).toBeCloseTo(0, 2, 'cameraBefore.up[0]'); expect(cameraBefore.up[1]).toBeCloseTo(0, 2, 'cameraBefore.up[1]'); expect(cameraBefore.up[2]).toBeCloseTo(1, 2, 'cameraBefore.up[2]'); @@ -108,7 +108,7 @@ describe('Test gl3d before/after plot', function() { .then(_clickThere) .then(delay(20)) .then(function() { - var cameraAfter = gd._fullLayout.scene._scene.glplot.camera; + var cameraAfter = gd._fullLayout.scene._scene.camera; expect(cameraAfter.up[0]).toBeCloseTo(0, 2, 'cameraAfter.up[0]'); expect(cameraAfter.up[1]).toBeCloseTo(0, 2, 'cameraAfter.up[1]'); expect(cameraAfter.up[2]).toBeCloseTo(1, 2, 'cameraAfter.up[2]'); @@ -123,7 +123,7 @@ describe('Test gl3d before/after plot', function() { .then(_clickOtherplace) .then(delay(20)) .then(function() { - var cameraFinal = gd._fullLayout.scene._scene.glplot.camera; + var cameraFinal = gd._fullLayout.scene._scene.camera; expect(cameraFinal.up[0]).toBeCloseTo(0, 2, 'cameraFinal.up[0]'); expect(cameraFinal.up[1]).toBeCloseTo(0, 2, 'cameraFinal.up[1]'); expect(cameraFinal.up[2]).toBeCloseTo(1, 2, 'cameraFinal.up[2]'); @@ -300,7 +300,7 @@ describe('Test gl3d plots', function() { .then(delay(20)) .then(function() { expect(gd._fullLayout.scene.camera.projection.type === 'perspective').toBe(true); - expect(gd._fullLayout.scene._scene.glplot.camera._ortho === false).toBe(true); + expect(gd._fullLayout.scene._scene.camera._ortho === false).toBe(true); }) .then(done); }); @@ -326,7 +326,7 @@ describe('Test gl3d plots', function() { .then(delay(20)) .then(function() { expect(gd._fullLayout.scene.camera.projection.type === 'orthographic').toBe(true); - expect(gd._fullLayout.scene._scene.glplot.camera._ortho === true).toBe(true); + expect(gd._fullLayout.scene._scene.camera._ortho === true).toBe(true); }) .then(done); }); @@ -355,28 +355,28 @@ describe('Test gl3d plots', function() { }) .then(function() { expect(gd._fullLayout.scene.camera.projection.type === 'orthographic').toBe(true); - expect(gd._fullLayout.scene._scene.glplot.camera._ortho === true).toBe(true); + expect(gd._fullLayout.scene._scene.camera._ortho === true).toBe(true); }) .then(function() { return Plotly.relayout(gd, 'scene.camera.eye.z', 2); }) .then(function() { expect(gd._fullLayout.scene.camera.projection.type === 'orthographic').toBe(true); - expect(gd._fullLayout.scene._scene.glplot.camera._ortho === true).toBe(true); + expect(gd._fullLayout.scene._scene.camera._ortho === true).toBe(true); }) .then(function() { return Plotly.relayout(gd, 'scene.camera.projection.type', 'perspective'); }) .then(function() { expect(gd._fullLayout.scene.camera.projection.type === 'perspective').toBe(true); - expect(gd._fullLayout.scene._scene.glplot.camera._ortho === false).toBe(true); + expect(gd._fullLayout.scene._scene.camera._ortho === false).toBe(true); }) .then(function() { return Plotly.relayout(gd, 'scene.camera.eye.z', 3); }) .then(function() { expect(gd._fullLayout.scene.camera.projection.type === 'perspective').toBe(true); - expect(gd._fullLayout.scene._scene.glplot.camera._ortho === false).toBe(true); + expect(gd._fullLayout.scene._scene.camera._ortho === false).toBe(true); }) .then(done); }); From e1b1a3962deb8b67148e6c9408395f3883ed31f2 Mon Sep 17 00:00:00 2001 From: archmoj Date: Mon, 4 Nov 2019 11:47:31 -0500 Subject: [PATCH 02/11] avoid low level webgl calls from plotly.js gl3d scene - make use of new gl-plot3d setters - reduce passing arguments --- package-lock.json | 5 ++-- package.json | 2 +- src/plots/gl3d/scene.js | 58 ++++++++++++++++------------------------- 3 files changed, 25 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4bb153a5d5c..f559e9dfe33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4644,9 +4644,8 @@ } }, "gl-plot3d": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gl-plot3d/-/gl-plot3d-2.3.0.tgz", - "integrity": "sha512-qg269QiLpaw16d2D5Gz9fa8vsLcA8kbX/cv1u9S7BsH6jD9qGYxsY8iWJ8ea9/68WhPS5En2kUavkXINkmHsOQ==", + "version": "git://github.com/gl-vis/gl-plot3d.git#8f89fc2ce75dfa8dae8e88ae1bf2849a50e25255", + "from": "git://github.com/gl-vis/gl-plot3d.git#8f89fc2ce75dfa8dae8e88ae1bf2849a50e25255", "requires": { "3d-view": "^2.0.0", "a-big-triangle": "^1.0.3", diff --git a/package.json b/package.json index 2c3cf2e6388..b648704d03e 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "gl-mat4": "^1.2.0", "gl-mesh3d": "^2.1.1", "gl-plot2d": "^1.4.2", - "gl-plot3d": "^2.3.0", + "gl-plot3d": "git://github.com/gl-vis/gl-plot3d.git#8f89fc2ce75dfa8dae8e88ae1bf2849a50e25255", "gl-pointcloud2d": "^1.0.2", "gl-scatter3d": "^1.2.2", "gl-select-box": "^1.0.3", diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index b03fe7451e3..de1b5c5e80e 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -128,7 +128,7 @@ function render(scene) { } tx = vectorTx.join('
'); } else if(trace.type === 'isosurface' || trace.type === 'volume') { - labels.valueLabel = Axes.tickText(scene.mockAxis, scene.mockAxis.d2l(selection.traceCoordinate[3]), 'hover').text; + labels.valueLabel = Axes.tickText(scene._mockAxis, scene._mockAxis.d2l(selection.traceCoordinate[3]), 'hover').text; vectorTx.push('value: ' + labels.valueLabel); if(selection.textLabel) { vectorTx.push(selection.textLabel); @@ -197,10 +197,10 @@ function render(scene) { scene.drawAnnotations(scene); } -function tryCreatePlot(scene, cameraObject, pixelRatio, canvas, gl) { +function tryCreatePlot(scene) { var glplotOptions = { - canvas: canvas, - gl: gl, + canvas: scene.canvas, + gl: scene.gl, container: scene.container, axes: scene.axesOptions, spikes: scene.spikeOptions, @@ -208,8 +208,8 @@ function tryCreatePlot(scene, cameraObject, pixelRatio, canvas, gl) { snapToData: true, autoScale: true, autoBounds: false, - cameraObject: cameraObject, - pixelRatio: pixelRatio + cameraObject: scene.camera, + pixelRatio: scene.pixelRatio }; // for static plots, we reuse the WebGL context @@ -248,10 +248,10 @@ function tryCreatePlot(scene, cameraObject, pixelRatio, canvas, gl) { return failed < 2; } -function initializeGLPlot(scene, canvas, gl) { +function initializeGLPlot(scene) { scene.initializeGLCamera(); - var success = tryCreatePlot(scene, scene.camera, scene.pixelRatio, canvas, gl); + var success = tryCreatePlot(scene); /* * createPlot will throw when webgl is not enabled in the client. * Lets return an instance of the module with all functions noop'd. @@ -413,17 +413,15 @@ proto.initializeGLCamera = function() { proto.recoverContext = function() { var scene = this; - var gl = this.glplot.gl; - var canvas = this.glplot.canvas; - this.glplot.dispose(); + scene.glplot.dispose(); function tryRecover() { - if(gl.isContextLost()) { + if(scene.glplot.gl.isContextLost()) { requestAnimationFrame(tryRecover); return; } - if(!initializeGLPlot(scene, canvas, gl)) { + if(!initializeGLPlot(scene)) { Lib.error('Catastrophic and unrecoverable WebGL error. Context lost.'); return; } @@ -506,10 +504,7 @@ proto.plot = function(sceneData, fullLayout, layout) { var fullSceneLayout = fullLayout[this.id]; var sceneLayout = layout[this.id]; - if(fullSceneLayout.bgcolor) this.glplot.clearColor = str2RGBAarray(fullSceneLayout.bgcolor); - else this.glplot.clearColor = [0, 0, 0, 0]; - - this.glplot.snapToData = true; + this.glplot.setClearColor(str2RGBAarray(fullSceneLayout.bgcolor)); // Update layout this.fullLayout = fullLayout; @@ -688,8 +683,10 @@ proto.plot = function(sceneData, fullLayout, layout) { axisDataRange[i] = sceneBounds[1][i] - sceneBounds[0][i]; // Update plot bounds - this.glplot.bounds[0][i] = sceneBounds[0][i] * dataScale[i]; - this.glplot.bounds[1][i] = sceneBounds[1][i] * dataScale[i]; + this.glplot.setBounds(i, { + min: sceneBounds[0][i] * dataScale[i], + max: sceneBounds[1][i] * dataScale[i] + }); } var axesScaleRatio = [1, 1, 1]; @@ -821,21 +818,10 @@ proto.setViewport = function(sceneLayout) { var oldOrtho = this.camera._ortho; if(newOrtho !== oldOrtho) { - this.glplot.redraw(); - - var RGBA = this.glplot.clearColor; - this.glplot.gl.clearColor( - RGBA[0], RGBA[1], RGBA[2], RGBA[3] - ); - this.glplot.gl.clear( - this.glplot.gl.DEPTH_BUFFER_BIT | - this.glplot.gl.COLOR_BUFFER_BIT - ); - + this.glplot.redraw(); // TODO: figure out why we need to redraw here? + this.glplot.clearRGBA(); this.glplot.dispose(); - initializeGLPlot(this); - this.camera._ortho = newOrtho; } }; @@ -1046,17 +1032,17 @@ proto.setConvert = function() { }; proto.make4thDimension = function() { - var _this = this; - var gd = _this.graphDiv; + var scene = this; + var gd = scene.graphDiv; var fullLayout = gd._fullLayout; // mock axis for hover formatting - _this.mockAxis = { + scene._mockAxis = { type: 'linear', showexponent: 'all', exponentformat: 'B' }; - Axes.setConvert(_this.mockAxis, fullLayout); + Axes.setConvert(scene._mockAxis, fullLayout); }; module.exports = Scene; From 0d76fe25ead6c51b8acde37c9c3aaa854e8d9796 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 5 Nov 2019 12:35:14 -0500 Subject: [PATCH 03/11] Now with reduced arguments we can make initializeGLPlot and tryCreatePlot functions method of Scene object - i.e. to avoid passing extra this argument - also let's use scene. instead of this. in Scene methods --- src/plots/gl3d/scene.js | 326 +++++++++++++++++++++------------------- 1 file changed, 171 insertions(+), 155 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index de1b5c5e80e..003710ca24f 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -197,7 +197,64 @@ function render(scene) { scene.drawAnnotations(scene); } -function tryCreatePlot(scene) { +function Scene(options, fullLayout) { + // create sub container for plot + var sceneContainer = document.createElement('div'); + var plotContainer = options.container; + + // keep a ref to the graph div to fire hover+click events + this.graphDiv = options.graphDiv; + + // create SVG container for hover text + var svgContainer = document.createElementNS( + 'http://www.w3.org/2000/svg', + 'svg'); + svgContainer.style.position = 'absolute'; + svgContainer.style.top = svgContainer.style.left = '0px'; + svgContainer.style.width = svgContainer.style.height = '100%'; + svgContainer.style['z-index'] = 20; + svgContainer.style['pointer-events'] = 'none'; + sceneContainer.appendChild(svgContainer); + this.svgContainer = svgContainer; + + // Tag the container with the sceneID + sceneContainer.id = options.id; + sceneContainer.style.position = 'absolute'; + sceneContainer.style.top = sceneContainer.style.left = '0px'; + sceneContainer.style.width = sceneContainer.style.height = '100%'; + plotContainer.appendChild(sceneContainer); + + this.fullLayout = fullLayout; + this.id = options.id || 'scene'; + this.fullSceneLayout = fullLayout[this.id]; + + // Saved from last call to plot() + this.plotArgs = [ [], {}, {} ]; + + /* + * Move this to calc step? Why does it work here? + */ + this.axesOptions = createAxesOptions(fullLayout, fullLayout[this.id]); + this.spikeOptions = createSpikeOptions(fullLayout[this.id]); + this.container = sceneContainer; + this.staticMode = !!options.staticPlot; + this.pixelRatio = this.pixelRatio || options.plotGlPixelRatio || 2; + + // Coordinate rescaling + this.dataScale = [1, 1, 1]; + + this.contourLevels = [ [], [], [] ]; + + this.convertAnnotations = Registry.getComponentMethod('annotations3d', 'convert'); + this.drawAnnotations = Registry.getComponentMethod('annotations3d', 'draw'); + + this.initializeGLPlot(); +} + +var proto = Scene.prototype; + +proto.tryCreatePlot = function() { + var scene = this; var glplotOptions = { canvas: scene.canvas, gl: scene.gl, @@ -246,12 +303,30 @@ function tryCreatePlot(scene) { } return failed < 2; -} +}; + +proto.initializeGLCamera = function() { + var scene = this; + var cameraData = scene.fullSceneLayout.camera; + var isOrtho = (cameraData.projection.type === 'orthographic'); + + scene.camera = createCamera(scene.container, { + center: [cameraData.center.x, cameraData.center.y, cameraData.center.z], + eye: [cameraData.eye.x, cameraData.eye.y, cameraData.eye.z], + up: [cameraData.up.x, cameraData.up.y, cameraData.up.z], + _ortho: isOrtho, + zoomMin: 0.01, + zoomMax: 100, + mode: 'orbit' + }); +}; + +proto.initializeGLPlot = function() { + var scene = this; -function initializeGLPlot(scene) { scene.initializeGLCamera(); - var success = tryCreatePlot(scene); + var success = scene.tryCreatePlot(); /* * createPlot will throw when webgl is not enabled in the client. * Lets return an instance of the module with all functions noop'd. @@ -338,77 +413,6 @@ function initializeGLPlot(scene) { scene.make4thDimension(); return true; -} - -function Scene(options, fullLayout) { - // create sub container for plot - var sceneContainer = document.createElement('div'); - var plotContainer = options.container; - - // keep a ref to the graph div to fire hover+click events - this.graphDiv = options.graphDiv; - - // create SVG container for hover text - var svgContainer = document.createElementNS( - 'http://www.w3.org/2000/svg', - 'svg'); - svgContainer.style.position = 'absolute'; - svgContainer.style.top = svgContainer.style.left = '0px'; - svgContainer.style.width = svgContainer.style.height = '100%'; - svgContainer.style['z-index'] = 20; - svgContainer.style['pointer-events'] = 'none'; - sceneContainer.appendChild(svgContainer); - this.svgContainer = svgContainer; - - // Tag the container with the sceneID - sceneContainer.id = options.id; - sceneContainer.style.position = 'absolute'; - sceneContainer.style.top = sceneContainer.style.left = '0px'; - sceneContainer.style.width = sceneContainer.style.height = '100%'; - plotContainer.appendChild(sceneContainer); - - this.fullLayout = fullLayout; - this.id = options.id || 'scene'; - this.fullSceneLayout = fullLayout[this.id]; - - // Saved from last call to plot() - this.plotArgs = [ [], {}, {} ]; - - /* - * Move this to calc step? Why does it work here? - */ - this.axesOptions = createAxesOptions(fullLayout, fullLayout[this.id]); - this.spikeOptions = createSpikeOptions(fullLayout[this.id]); - this.container = sceneContainer; - this.staticMode = !!options.staticPlot; - this.pixelRatio = this.pixelRatio || options.plotGlPixelRatio || 2; - - // Coordinate rescaling - this.dataScale = [1, 1, 1]; - - this.contourLevels = [ [], [], [] ]; - - this.convertAnnotations = Registry.getComponentMethod('annotations3d', 'convert'); - this.drawAnnotations = Registry.getComponentMethod('annotations3d', 'draw'); - - initializeGLPlot(this); -} - -var proto = Scene.prototype; - -proto.initializeGLCamera = function() { - var cameraData = this.fullSceneLayout.camera; - var isOrtho = (cameraData.projection.type === 'orthographic'); - - this.camera = createCamera(this.container, { - center: [cameraData.center.x, cameraData.center.y, cameraData.center.z], - eye: [cameraData.eye.x, cameraData.eye.y, cameraData.eye.z], - up: [cameraData.up.x, cameraData.up.y, cameraData.up.z], - _ortho: isOrtho, - zoomMin: 0.01, - zoomMax: 100, - mode: 'orbit' - }); }; proto.recoverContext = function() { @@ -416,17 +420,18 @@ proto.recoverContext = function() { scene.glplot.dispose(); - function tryRecover() { + var tryRecover = function() { if(scene.glplot.gl.isContextLost()) { requestAnimationFrame(tryRecover); return; } - if(!initializeGLPlot(scene)) { + if(!scene.initializeGLPlot()) { Lib.error('Catastrophic and unrecoverable WebGL error. Context lost.'); return; } scene.plot.apply(scene, scene.plotArgs); - } + }; + requestAnimationFrame(tryRecover); }; @@ -494,36 +499,38 @@ function computeAnnotationBounds(scene, bounds) { } proto.plot = function(sceneData, fullLayout, layout) { + var scene = this; + // Save parameters - this.plotArgs = [sceneData, fullLayout, layout]; + scene.plotArgs = [sceneData, fullLayout, layout]; - if(this.glplot.contextLost) return; + if(scene.glplot.contextLost) return; var data, trace; var i, j, axis, axisType; - var fullSceneLayout = fullLayout[this.id]; - var sceneLayout = layout[this.id]; + var fullSceneLayout = fullLayout[scene.id]; + var sceneLayout = layout[scene.id]; - this.glplot.setClearColor(str2RGBAarray(fullSceneLayout.bgcolor)); + scene.glplot.setClearColor(str2RGBAarray(fullSceneLayout.bgcolor)); // Update layout - this.fullLayout = fullLayout; - this.fullSceneLayout = fullSceneLayout; + scene.fullLayout = fullLayout; + scene.fullSceneLayout = fullSceneLayout; - this.glplotLayout = fullSceneLayout; - this.axesOptions.merge(fullLayout, fullSceneLayout); - this.spikeOptions.merge(fullSceneLayout); + scene.glplotLayout = fullSceneLayout; + scene.axesOptions.merge(fullLayout, fullSceneLayout); + scene.spikeOptions.merge(fullSceneLayout); // Update camera and camera mode - this.setViewport(fullSceneLayout); - this.updateFx(fullSceneLayout.dragmode, fullSceneLayout.hovermode); - this.camera.enableWheel = this.graphDiv._context._scrollZoom.gl3d; + scene.setViewport(fullSceneLayout); + scene.updateFx(fullSceneLayout.dragmode, fullSceneLayout.hovermode); + scene.camera.enableWheel = scene.graphDiv._context._scrollZoom.gl3d; // Update scene - this.glplot.update({}); + scene.glplot.update({}); // Update axes functions BEFORE updating traces - this.setConvert(axis); + scene.setConvert(axis); // Convert scene data if(!sceneData) sceneData = []; @@ -553,10 +560,10 @@ proto.plot = function(sceneData, fullLayout, layout) { } // Save scale - this.dataScale = dataScale; + scene.dataScale = dataScale; // after computeTraceBounds where ax._categories are filled in - this.convertAnnotations(this); + scene.convertAnnotations(this); // Update traces for(i = 0; i < sceneData.length; ++i) { @@ -564,24 +571,24 @@ proto.plot = function(sceneData, fullLayout, layout) { if(data.visible !== true || data._length === 0) { continue; } - trace = this.traces[data.uid]; + trace = scene.traces[data.uid]; if(trace) { if(trace.data.type === data.type) { trace.update(data); } else { trace.dispose(); trace = data._module.plot(this, data); - this.traces[data.uid] = trace; + scene.traces[data.uid] = trace; } } else { trace = data._module.plot(this, data); - this.traces[data.uid] = trace; + scene.traces[data.uid] = trace; } trace.name = data.name; } // Remove empty traces - var traceIds = Object.keys(this.traces); + var traceIds = Object.keys(scene.traces); traceIdLoop: for(i = 0; i < traceIds.length; ++i) { @@ -591,13 +598,13 @@ proto.plot = function(sceneData, fullLayout, layout) { continue traceIdLoop; } } - trace = this.traces[traceIds[i]]; + trace = scene.traces[traceIds[i]]; trace.dispose(); - delete this.traces[traceIds[i]]; + delete scene.traces[traceIds[i]]; } // order object per trace index - this.glplot.objects.sort(function(a, b) { + scene.glplot.objects.sort(function(a, b) { return a._trace.data.index - b._trace.data.index; }); @@ -624,8 +631,8 @@ proto.plot = function(sceneData, fullLayout, layout) { sceneBounds[0][i] = Infinity; sceneBounds[1][i] = -Infinity; - var objects = this.glplot.objects; - var annotations = this.fullSceneLayout.annotations || []; + var objects = scene.glplot.objects; + var annotations = scene.fullSceneLayout.annotations || []; var axLetter = axis._name.charAt(0); for(j = 0; j < objects.length; j++) { @@ -683,7 +690,7 @@ proto.plot = function(sceneData, fullLayout, layout) { axisDataRange[i] = sceneBounds[1][i] - sceneBounds[0][i]; // Update plot bounds - this.glplot.setBounds(i, { + scene.glplot.setBounds(i, { min: sceneBounds[0][i] * dataScale[i], max: sceneBounds[1][i] * dataScale[i] }); @@ -741,11 +748,11 @@ proto.plot = function(sceneData, fullLayout, layout) { * Finally assign the computed aspecratio to the glplot module. This will have an effect * on the next render cycle. */ - this.glplot.setAspectratio(fullSceneLayout.aspectratio); + scene.glplot.setAspectratio(fullSceneLayout.aspectratio); // save 'initial' camera view settings for modebar button - if(!this.viewInitial.aspectratio) { - this.viewInitial.aspectratio = { + if(!scene.viewInitial.aspectratio) { + scene.viewInitial.aspectratio = { x: fullSceneLayout.aspectratio.x, y: fullSceneLayout.aspectratio.y, z: fullSceneLayout.aspectratio.z @@ -757,7 +764,7 @@ proto.plot = function(sceneData, fullLayout, layout) { var size = fullLayout._size || null; if(domain && size) { - var containerStyle = this.container.style; + var containerStyle = scene.container.style; containerStyle.position = 'absolute'; containerStyle.left = (size.l + domain.x[0] * size.w) + 'px'; containerStyle.top = (size.t + (1 - domain.y[1]) * size.h) + 'px'; @@ -766,18 +773,19 @@ proto.plot = function(sceneData, fullLayout, layout) { } // force redraw so that promise is returned when rendering is completed - this.glplot.redraw(); + scene.glplot.redraw(); }; proto.destroy = function() { - if(!this.glplot) return; - - this.camera.mouseListener.enabled = false; - this.container.removeEventListener('wheel', this.camera.wheelListener); - this.camera = null; - this.glplot.dispose(); - this.container.parentNode.removeChild(this.container); - this.glplot = null; + var scene = this; + + if(!scene.glplot) return; + scene.camera.mouseListener.enabled = false; + scene.container.removeEventListener('wheel', scene.camera.wheelListener); + scene.camera = null; + scene.glplot.dispose(); + scene.container.parentNode.removeChild(scene.container); + scene.glplot = null; }; // getCameraArrays :: plotly_coords -> gl-plot3d_coords @@ -803,31 +811,34 @@ function getLayoutCamera(camera) { // get camera position in plotly coords from 'gl-plot3d' coords proto.getCamera = function() { - this.camera.view.recalcMatrix(this.camera.view.lastT()); - return getLayoutCamera(this.camera); + var scene = this; + scene.camera.view.recalcMatrix(scene.camera.view.lastT()); + return getLayoutCamera(scene.camera); }; // set gl-plot3d camera position and scene aspects with a set of plotly coords proto.setViewport = function(sceneLayout) { + var scene = this; var cameraData = sceneLayout.camera; - this.camera.lookAt.apply(this, getCameraArrays(cameraData)); - this.glplot.setAspectratio(sceneLayout.aspectratio); + scene.camera.lookAt.apply(this, getCameraArrays(cameraData)); + scene.glplot.setAspectratio(sceneLayout.aspectratio); var newOrtho = (cameraData.projection.type === 'orthographic'); - var oldOrtho = this.camera._ortho; + var oldOrtho = scene.camera._ortho; if(newOrtho !== oldOrtho) { - this.glplot.redraw(); // TODO: figure out why we need to redraw here? - this.glplot.clearRGBA(); - this.glplot.dispose(); - initializeGLPlot(this); + scene.glplot.redraw(); // TODO: figure out why we need to redraw here? + scene.glplot.clearRGBA(); + scene.glplot.dispose(); + scene.initializeGLPlot(); } }; proto.isCameraChanged = function(layout) { - var cameraData = this.getCamera(); - var cameraNestedProp = Lib.nestedProperty(layout, this.id + '.camera'); + var scene = this; + var cameraData = scene.getCamera(); + var cameraNestedProp = Lib.nestedProperty(layout, scene.id + '.camera'); var cameraDataLastSave = cameraNestedProp.get(); function same(x, y, i, j) { @@ -860,8 +871,9 @@ proto.isCameraChanged = function(layout) { }; proto.isAspectChanged = function(layout) { - var aspectData = this.glplot.getAspectratio(); - var aspectNestedProp = Lib.nestedProperty(layout, this.id + '.aspectratio'); + var scene = this; + var aspectData = scene.glplot.getAspectratio(); + var aspectNestedProp = Lib.nestedProperty(layout, scene.id + '.aspectratio'); var aspectDataLastSave = aspectNestedProp.get(); return ( @@ -874,7 +886,8 @@ proto.isAspectChanged = function(layout) { // save camera to user layout (i.e. gd.layout) proto.saveLayout = function(layout) { - var fullLayout = this.fullLayout; + var scene = this; + var fullLayout = scene.fullLayout; var cameraData; var cameraNestedProp; @@ -884,42 +897,42 @@ proto.saveLayout = function(layout) { var aspectNestedProp; var aspectDataLastSave; - var cameraChanged = this.isCameraChanged(layout); - var aspectChanged = this.isAspectChanged(layout); + var cameraChanged = scene.isCameraChanged(layout); + var aspectChanged = scene.isAspectChanged(layout); var hasChanged = cameraChanged || aspectChanged; if(hasChanged) { var preGUI = {}; if(cameraChanged) { - cameraData = this.getCamera(); - cameraNestedProp = Lib.nestedProperty(layout, this.id + '.camera'); + cameraData = scene.getCamera(); + cameraNestedProp = Lib.nestedProperty(layout, scene.id + '.camera'); cameraDataLastSave = cameraNestedProp.get(); - preGUI[this.id + '.camera'] = cameraDataLastSave; + preGUI[scene.id + '.camera'] = cameraDataLastSave; } if(aspectChanged) { - aspectData = this.glplot.getAspectratio(); - aspectNestedProp = Lib.nestedProperty(layout, this.id + '.aspectratio'); + aspectData = scene.glplot.getAspectratio(); + aspectNestedProp = Lib.nestedProperty(layout, scene.id + '.aspectratio'); aspectDataLastSave = aspectNestedProp.get(); - preGUI[this.id + '.aspectratio'] = aspectDataLastSave; + preGUI[scene.id + '.aspectratio'] = aspectDataLastSave; } Registry.call('_storeDirectGUIEdit', layout, fullLayout._preGUI, preGUI); if(cameraChanged) { cameraNestedProp.set(cameraData); - var cameraFullNP = Lib.nestedProperty(fullLayout, this.id + '.camera'); + var cameraFullNP = Lib.nestedProperty(fullLayout, scene.id + '.camera'); cameraFullNP.set(cameraData); } if(aspectChanged) { aspectNestedProp.set(aspectData); - var aspectFullNP = Lib.nestedProperty(fullLayout, this.id + '.aspectratio'); + var aspectFullNP = Lib.nestedProperty(fullLayout, scene.id + '.aspectratio'); aspectFullNP.set(aspectData); - this.glplot.redraw(); + scene.glplot.redraw(); } } @@ -927,7 +940,8 @@ proto.saveLayout = function(layout) { }; proto.updateFx = function(dragmode, hovermode) { - var camera = this.camera; + var scene = this; + var camera = scene.camera; if(camera) { // rotate and orbital are synonymous if(dragmode === 'orbit') { @@ -941,15 +955,15 @@ proto.updateFx = function(dragmode, hovermode) { // The setter for camera.mode animates the transition to z-up, // but only if we *don't* explicitly set z-up earlier via the // relayout. So push `up` back to layout & fullLayout manually now. - var gd = this.graphDiv; + var gd = scene.graphDiv; var fullLayout = gd._fullLayout; - var fullCamera = this.fullSceneLayout.camera; + var fullCamera = scene.fullSceneLayout.camera; var x = fullCamera.up.x; var y = fullCamera.up.y; var z = fullCamera.up.z; // only push `up` back to (full)layout if it's going to change if(z / Math.sqrt(x * x + y * y + z * z) < 0.999) { - var attr = this.id + '.camera.up'; + var attr = scene.id + '.camera.up'; var zUp = {x: 0, y: 0, z: 1}; var edits = {}; edits[attr] = zUp; @@ -965,19 +979,20 @@ proto.updateFx = function(dragmode, hovermode) { } // to put dragmode and hovermode on the same grounds from relayout - this.fullSceneLayout.hovermode = hovermode; + scene.fullSceneLayout.hovermode = hovermode; }; proto.toImage = function(format) { - if(!format) format = 'png'; + var scene = this; - if(this.staticMode) this.container.appendChild(STATIC_CANVAS); + if(!format) format = 'png'; + if(scene.staticMode) scene.container.appendChild(STATIC_CANVAS); // Force redraw - this.glplot.redraw(); + scene.glplot.redraw(); // Grab context and yank out pixels - var gl = this.glplot.gl; + var gl = scene.glplot.gl; var w = gl.drawingBufferWidth; var h = gl.drawingBufferHeight; @@ -1018,15 +1033,16 @@ proto.toImage = function(format) { dataURL = canvas.toDataURL('image/png'); } - if(this.staticMode) this.container.removeChild(STATIC_CANVAS); + if(scene.staticMode) scene.container.removeChild(STATIC_CANVAS); return dataURL; }; proto.setConvert = function() { + var scene = this; for(var i = 0; i < 3; i++) { - var ax = this.fullSceneLayout[axisProperties[i]]; - Axes.setConvert(ax, this.fullLayout); + var ax = scene.fullSceneLayout[axisProperties[i]]; + Axes.setConvert(ax, scene.fullLayout); ax.setScale = Lib.noop; } }; From b8ca3917c14f3b4a2f8ef748660168d20f02519c Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 5 Nov 2019 13:05:54 -0500 Subject: [PATCH 04/11] make render another method of Scene object --- src/plots/gl3d/scene.js | 341 ++++++++++++++++++++-------------------- 1 file changed, 172 insertions(+), 169 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 003710ca24f..0ffcee0ade7 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -33,170 +33,6 @@ var computeTickMarks = require('./layout/tick_marks'); var STATIC_CANVAS, STATIC_CONTEXT; -function render(scene) { - var gd = scene.graphDiv; - var trace; - - // update size of svg container - var svgContainer = scene.svgContainer; - var clientRect = scene.container.getBoundingClientRect(); - var width = clientRect.width; - var height = clientRect.height; - svgContainer.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height); - svgContainer.setAttributeNS(null, 'width', width); - svgContainer.setAttributeNS(null, 'height', height); - - computeTickMarks(scene); - scene.glplot.axes.update(scene.axesOptions); - - // check if pick has changed - var keys = Object.keys(scene.traces); - var lastPicked = null; - var selection = scene.glplot.selection; - for(var i = 0; i < keys.length; ++i) { - trace = scene.traces[keys[i]]; - if(trace.data.hoverinfo !== 'skip' && trace.handlePick(selection)) { - lastPicked = trace; - } - - if(trace.setContourLevels) trace.setContourLevels(); - } - - function formatter(axisName, val) { - var axis = scene.fullSceneLayout[axisName]; - - return Axes.tickText(axis, axis.d2l(val), 'hover').text; - } - - var oldEventData; - - if(lastPicked !== null) { - var pdata = project(scene.glplot.cameraParams, selection.dataCoordinate); - trace = lastPicked.data; - var traceNow = gd._fullData[trace.index]; - var ptNumber = selection.index; - - var labels = { - xLabel: formatter('xaxis', selection.traceCoordinate[0]), - yLabel: formatter('yaxis', selection.traceCoordinate[1]), - zLabel: formatter('zaxis', selection.traceCoordinate[2]) - }; - - var hoverinfo = Fx.castHoverinfo(traceNow, scene.fullLayout, ptNumber); - var hoverinfoParts = (hoverinfo || '').split('+'); - var isHoverinfoAll = hoverinfo && hoverinfo === 'all'; - - if(!traceNow.hovertemplate && !isHoverinfoAll) { - if(hoverinfoParts.indexOf('x') === -1) labels.xLabel = undefined; - if(hoverinfoParts.indexOf('y') === -1) labels.yLabel = undefined; - if(hoverinfoParts.indexOf('z') === -1) labels.zLabel = undefined; - if(hoverinfoParts.indexOf('text') === -1) selection.textLabel = undefined; - if(hoverinfoParts.indexOf('name') === -1) lastPicked.name = undefined; - } - - var tx; - var vectorTx = []; - - if(trace.type === 'cone' || trace.type === 'streamtube') { - labels.uLabel = formatter('xaxis', selection.traceCoordinate[3]); - if(isHoverinfoAll || hoverinfoParts.indexOf('u') !== -1) { - vectorTx.push('u: ' + labels.uLabel); - } - - labels.vLabel = formatter('yaxis', selection.traceCoordinate[4]); - if(isHoverinfoAll || hoverinfoParts.indexOf('v') !== -1) { - vectorTx.push('v: ' + labels.vLabel); - } - - labels.wLabel = formatter('zaxis', selection.traceCoordinate[5]); - if(isHoverinfoAll || hoverinfoParts.indexOf('w') !== -1) { - vectorTx.push('w: ' + labels.wLabel); - } - - labels.normLabel = selection.traceCoordinate[6].toPrecision(3); - if(isHoverinfoAll || hoverinfoParts.indexOf('norm') !== -1) { - vectorTx.push('norm: ' + labels.normLabel); - } - if(trace.type === 'streamtube') { - labels.divergenceLabel = selection.traceCoordinate[7].toPrecision(3); - if(isHoverinfoAll || hoverinfoParts.indexOf('divergence') !== -1) { - vectorTx.push('divergence: ' + labels.divergenceLabel); - } - } - if(selection.textLabel) { - vectorTx.push(selection.textLabel); - } - tx = vectorTx.join('
'); - } else if(trace.type === 'isosurface' || trace.type === 'volume') { - labels.valueLabel = Axes.tickText(scene._mockAxis, scene._mockAxis.d2l(selection.traceCoordinate[3]), 'hover').text; - vectorTx.push('value: ' + labels.valueLabel); - if(selection.textLabel) { - vectorTx.push(selection.textLabel); - } - tx = vectorTx.join('
'); - } else { - tx = selection.textLabel; - } - - var pointData = { - x: selection.traceCoordinate[0], - y: selection.traceCoordinate[1], - z: selection.traceCoordinate[2], - data: traceNow._input, - fullData: traceNow, - curveNumber: traceNow.index, - pointNumber: ptNumber - }; - - Fx.appendArrayPointValue(pointData, traceNow, ptNumber); - - if(trace._module.eventData) { - pointData = traceNow._module.eventData(pointData, selection, traceNow, {}, ptNumber); - } - - var eventData = {points: [pointData]}; - - if(scene.fullSceneLayout.hovermode) { - Fx.loneHover({ - trace: traceNow, - x: (0.5 + 0.5 * pdata[0] / pdata[3]) * width, - y: (0.5 - 0.5 * pdata[1] / pdata[3]) * height, - xLabel: labels.xLabel, - yLabel: labels.yLabel, - zLabel: labels.zLabel, - text: tx, - name: lastPicked.name, - color: Fx.castHoverOption(traceNow, ptNumber, 'bgcolor') || lastPicked.color, - borderColor: Fx.castHoverOption(traceNow, ptNumber, 'bordercolor'), - fontFamily: Fx.castHoverOption(traceNow, ptNumber, 'font.family'), - fontSize: Fx.castHoverOption(traceNow, ptNumber, 'font.size'), - fontColor: Fx.castHoverOption(traceNow, ptNumber, 'font.color'), - nameLength: Fx.castHoverOption(traceNow, ptNumber, 'namelength'), - textAlign: Fx.castHoverOption(traceNow, ptNumber, 'align'), - hovertemplate: Lib.castOption(traceNow, ptNumber, 'hovertemplate'), - hovertemplateLabels: Lib.extendFlat({}, pointData, labels), - eventData: [pointData] - }, { - container: svgContainer, - gd: gd - }); - } - - if(selection.buttons && selection.distance < 5) { - gd.emit('plotly_click', eventData); - } else { - gd.emit('plotly_hover', eventData); - } - - oldEventData = eventData; - } else { - Fx.loneUnhover(svgContainer); - gd.emit('plotly_unhover', oldEventData); - } - - scene.drawAnnotations(scene); -} - function Scene(options, fullLayout) { // create sub container for plot var sceneContainer = document.createElement('div'); @@ -335,6 +171,11 @@ proto.initializeGLPlot = function() { */ if(!success) return showNoWebGlMsg(scene); + // List of scene objects + scene.traces = {}; + + scene.make4thDimension(); + var gd = scene.graphDiv; var layout = gd.layout; @@ -405,14 +246,176 @@ proto.initializeGLPlot = function() { scene.recoverContext(); }; - scene.glplot.onrender = render.bind(null, scene); + scene.glplot.onrender = function() { + scene.render(); + }; - // List of scene objects - scene.traces = {}; + return true; +}; - scene.make4thDimension(); +proto.render = function() { + var scene = this; + var gd = scene.graphDiv; + var trace; - return true; + // update size of svg container + var svgContainer = scene.svgContainer; + var clientRect = scene.container.getBoundingClientRect(); + var width = clientRect.width; + var height = clientRect.height; + svgContainer.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height); + svgContainer.setAttributeNS(null, 'width', width); + svgContainer.setAttributeNS(null, 'height', height); + + computeTickMarks(scene); + scene.glplot.axes.update(scene.axesOptions); + + // check if pick has changed + var keys = Object.keys(scene.traces); + var lastPicked = null; + var selection = scene.glplot.selection; + for(var i = 0; i < keys.length; ++i) { + trace = scene.traces[keys[i]]; + if(trace.data.hoverinfo !== 'skip' && trace.handlePick(selection)) { + lastPicked = trace; + } + + if(trace.setContourLevels) trace.setContourLevels(); + } + + function formatter(axisName, val) { + var axis = scene.fullSceneLayout[axisName]; + + return Axes.tickText(axis, axis.d2l(val), 'hover').text; + } + + var oldEventData; + + if(lastPicked !== null) { + var pdata = project(scene.glplot.cameraParams, selection.dataCoordinate); + trace = lastPicked.data; + var traceNow = gd._fullData[trace.index]; + var ptNumber = selection.index; + + var labels = { + xLabel: formatter('xaxis', selection.traceCoordinate[0]), + yLabel: formatter('yaxis', selection.traceCoordinate[1]), + zLabel: formatter('zaxis', selection.traceCoordinate[2]) + }; + + var hoverinfo = Fx.castHoverinfo(traceNow, scene.fullLayout, ptNumber); + var hoverinfoParts = (hoverinfo || '').split('+'); + var isHoverinfoAll = hoverinfo && hoverinfo === 'all'; + + if(!traceNow.hovertemplate && !isHoverinfoAll) { + if(hoverinfoParts.indexOf('x') === -1) labels.xLabel = undefined; + if(hoverinfoParts.indexOf('y') === -1) labels.yLabel = undefined; + if(hoverinfoParts.indexOf('z') === -1) labels.zLabel = undefined; + if(hoverinfoParts.indexOf('text') === -1) selection.textLabel = undefined; + if(hoverinfoParts.indexOf('name') === -1) lastPicked.name = undefined; + } + + var tx; + var vectorTx = []; + + if(trace.type === 'cone' || trace.type === 'streamtube') { + labels.uLabel = formatter('xaxis', selection.traceCoordinate[3]); + if(isHoverinfoAll || hoverinfoParts.indexOf('u') !== -1) { + vectorTx.push('u: ' + labels.uLabel); + } + + labels.vLabel = formatter('yaxis', selection.traceCoordinate[4]); + if(isHoverinfoAll || hoverinfoParts.indexOf('v') !== -1) { + vectorTx.push('v: ' + labels.vLabel); + } + + labels.wLabel = formatter('zaxis', selection.traceCoordinate[5]); + if(isHoverinfoAll || hoverinfoParts.indexOf('w') !== -1) { + vectorTx.push('w: ' + labels.wLabel); + } + + labels.normLabel = selection.traceCoordinate[6].toPrecision(3); + if(isHoverinfoAll || hoverinfoParts.indexOf('norm') !== -1) { + vectorTx.push('norm: ' + labels.normLabel); + } + if(trace.type === 'streamtube') { + labels.divergenceLabel = selection.traceCoordinate[7].toPrecision(3); + if(isHoverinfoAll || hoverinfoParts.indexOf('divergence') !== -1) { + vectorTx.push('divergence: ' + labels.divergenceLabel); + } + } + if(selection.textLabel) { + vectorTx.push(selection.textLabel); + } + tx = vectorTx.join('
'); + } else if(trace.type === 'isosurface' || trace.type === 'volume') { + labels.valueLabel = Axes.tickText(scene._mockAxis, scene._mockAxis.d2l(selection.traceCoordinate[3]), 'hover').text; + vectorTx.push('value: ' + labels.valueLabel); + if(selection.textLabel) { + vectorTx.push(selection.textLabel); + } + tx = vectorTx.join('
'); + } else { + tx = selection.textLabel; + } + + var pointData = { + x: selection.traceCoordinate[0], + y: selection.traceCoordinate[1], + z: selection.traceCoordinate[2], + data: traceNow._input, + fullData: traceNow, + curveNumber: traceNow.index, + pointNumber: ptNumber + }; + + Fx.appendArrayPointValue(pointData, traceNow, ptNumber); + + if(trace._module.eventData) { + pointData = traceNow._module.eventData(pointData, selection, traceNow, {}, ptNumber); + } + + var eventData = {points: [pointData]}; + + if(scene.fullSceneLayout.hovermode) { + Fx.loneHover({ + trace: traceNow, + x: (0.5 + 0.5 * pdata[0] / pdata[3]) * width, + y: (0.5 - 0.5 * pdata[1] / pdata[3]) * height, + xLabel: labels.xLabel, + yLabel: labels.yLabel, + zLabel: labels.zLabel, + text: tx, + name: lastPicked.name, + color: Fx.castHoverOption(traceNow, ptNumber, 'bgcolor') || lastPicked.color, + borderColor: Fx.castHoverOption(traceNow, ptNumber, 'bordercolor'), + fontFamily: Fx.castHoverOption(traceNow, ptNumber, 'font.family'), + fontSize: Fx.castHoverOption(traceNow, ptNumber, 'font.size'), + fontColor: Fx.castHoverOption(traceNow, ptNumber, 'font.color'), + nameLength: Fx.castHoverOption(traceNow, ptNumber, 'namelength'), + textAlign: Fx.castHoverOption(traceNow, ptNumber, 'align'), + hovertemplate: Lib.castOption(traceNow, ptNumber, 'hovertemplate'), + hovertemplateLabels: Lib.extendFlat({}, pointData, labels), + eventData: [pointData] + }, { + container: svgContainer, + gd: gd + }); + } + + if(selection.buttons && selection.distance < 5) { + gd.emit('plotly_click', eventData); + } else { + gd.emit('plotly_hover', eventData); + } + + oldEventData = eventData; + } else { + Fx.loneUnhover(svgContainer); + gd.emit('plotly_unhover', oldEventData); + } + + scene.drawAnnotations(scene); }; proto.recoverContext = function() { From 94ebb09a55f0e088b6095430b6e922e32d42eb2c Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 5 Nov 2019 13:46:13 -0500 Subject: [PATCH 05/11] remove unused parameter glplotLayout and glplot.update call --- src/plots/gl3d/scene.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 0ffcee0ade7..0e037023926 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -514,13 +514,10 @@ proto.plot = function(sceneData, fullLayout, layout) { var fullSceneLayout = fullLayout[scene.id]; var sceneLayout = layout[scene.id]; - scene.glplot.setClearColor(str2RGBAarray(fullSceneLayout.bgcolor)); - // Update layout scene.fullLayout = fullLayout; scene.fullSceneLayout = fullSceneLayout; - scene.glplotLayout = fullSceneLayout; scene.axesOptions.merge(fullLayout, fullSceneLayout); scene.spikeOptions.merge(fullSceneLayout); @@ -529,8 +526,8 @@ proto.plot = function(sceneData, fullLayout, layout) { scene.updateFx(fullSceneLayout.dragmode, fullSceneLayout.hovermode); scene.camera.enableWheel = scene.graphDiv._context._scrollZoom.gl3d; - // Update scene - scene.glplot.update({}); + // Update scene background + scene.glplot.setClearColor(str2RGBAarray(fullSceneLayout.bgcolor)); // Update axes functions BEFORE updating traces scene.setConvert(axis); From d8af1dc4452849300656f6a921232e2cea2fe472 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 5 Nov 2019 15:21:29 -0500 Subject: [PATCH 06/11] add glOptions so that it is contolled by plotly.js not gl-plot3d --- src/plots/gl3d/scene.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 0e037023926..d46b310d57d 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -15,6 +15,7 @@ var createPlot = glPlot3d.createScene; var getContext = require('webgl-context'); var passiveSupported = require('has-passive-events'); +var isMobile = require('is-mobile')({ tablet: true }); var Registry = require('../../registry'); var Lib = require('../../lib'); @@ -91,9 +92,14 @@ var proto = Scene.prototype; proto.tryCreatePlot = function() { var scene = this; - var glplotOptions = { + var opts = { canvas: scene.canvas, gl: scene.gl, + glOptions: { + preserveDrawingBuffer: isMobile, + premultipliedAlpha: true, + antialias: true + }, container: scene.container, axes: scene.axesOptions, spikes: scene.spikeOptions, @@ -120,19 +126,19 @@ proto.tryCreatePlot = function() { throw new Error('error creating static canvas/context for image server'); } } - glplotOptions.pixelRatio = scene.pixelRatio; - glplotOptions.gl = STATIC_CONTEXT; - glplotOptions.canvas = STATIC_CANVAS; + + opts.gl = STATIC_CONTEXT; + opts.canvas = STATIC_CANVAS; } var failed = 0; try { - scene.glplot = createPlot(glplotOptions); + scene.glplot = createPlot(opts); } catch(e) { failed++; try { // try second time to fix issue with Chrome 77 https://github.com/plotly/plotly.js/issues/4233 - scene.glplot = createPlot(glplotOptions); + scene.glplot = createPlot(opts); } catch(e) { failed++; } From 9066bd1cb3d0eb2812039e660c848689d39e629a Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 5 Nov 2019 15:37:37 -0500 Subject: [PATCH 07/11] fix issue 4236 - do not init dynamic gl with premultipliedAlpha --- src/plots/gl3d/scene.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index d46b310d57d..aa1df89fbab 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -97,7 +97,7 @@ proto.tryCreatePlot = function() { gl: scene.gl, glOptions: { preserveDrawingBuffer: isMobile, - premultipliedAlpha: true, + premultipliedAlpha: false, antialias: true }, container: scene.container, From fe17eb9761ef7a0955ca1217652a6419ee0725d1 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 5 Nov 2019 17:52:48 -0500 Subject: [PATCH 08/11] apply gl-plot3d changes --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f559e9dfe33..0026a1dc2ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4644,8 +4644,8 @@ } }, "gl-plot3d": { - "version": "git://github.com/gl-vis/gl-plot3d.git#8f89fc2ce75dfa8dae8e88ae1bf2849a50e25255", - "from": "git://github.com/gl-vis/gl-plot3d.git#8f89fc2ce75dfa8dae8e88ae1bf2849a50e25255", + "version": "git://github.com/gl-vis/gl-plot3d.git#e1858a63bb6617474145ee4ae37106eddf3b3fa3", + "from": "git://github.com/gl-vis/gl-plot3d.git#e1858a63bb6617474145ee4ae37106eddf3b3fa3", "requires": { "3d-view": "^2.0.0", "a-big-triangle": "^1.0.3", diff --git a/package.json b/package.json index b648704d03e..1ea5942d1c7 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "gl-mat4": "^1.2.0", "gl-mesh3d": "^2.1.1", "gl-plot2d": "^1.4.2", - "gl-plot3d": "git://github.com/gl-vis/gl-plot3d.git#8f89fc2ce75dfa8dae8e88ae1bf2849a50e25255", + "gl-plot3d": "git://github.com/gl-vis/gl-plot3d.git#e1858a63bb6617474145ee4ae37106eddf3b3fa3", "gl-pointcloud2d": "^1.0.2", "gl-scatter3d": "^1.2.2", "gl-select-box": "^1.0.3", From 5adf6b6c29006b0ba42aac7064551d62e0ea0aab Mon Sep 17 00:00:00 2001 From: archmoj Date: Mon, 13 Jan 2020 17:08:22 -0500 Subject: [PATCH 09/11] bump gl-plot3d at 2.4.0 --- package-lock.json | 5 +++-- package.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 77f21012d2d..86327c6ea82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4653,8 +4653,9 @@ } }, "gl-plot3d": { - "version": "git://github.com/gl-vis/gl-plot3d.git#e1858a63bb6617474145ee4ae37106eddf3b3fa3", - "from": "git://github.com/gl-vis/gl-plot3d.git#e1858a63bb6617474145ee4ae37106eddf3b3fa3", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/gl-plot3d/-/gl-plot3d-2.4.0.tgz", + "integrity": "sha512-ZPs7gvWaCqK99GXoB0XJTMTLpChB/CiDUt3MthIawVlFhknSJLNPAJSbUU3f4pWzKCbbGtVARQr/i6XdM3MnKA==", "requires": { "3d-view": "^2.0.0", "a-big-triangle": "^1.0.3", diff --git a/package.json b/package.json index e29997305c2..d7bd2c32860 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "gl-mat4": "^1.2.0", "gl-mesh3d": "^2.2.0", "gl-plot2d": "^1.4.2", - "gl-plot3d": "git://github.com/gl-vis/gl-plot3d.git#e1858a63bb6617474145ee4ae37106eddf3b3fa3", + "gl-plot3d": "^2.4.0", "gl-pointcloud2d": "^1.0.2", "gl-scatter3d": "^1.2.2", "gl-select-box": "^1.0.3", From ade22a674393762b8a7262c368acb5e0fae0661f Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 28 Jan 2020 15:40:10 -0500 Subject: [PATCH 10/11] set premultipliedAlpha to true as it was applied before --- src/plots/gl3d/scene.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 2054653e5ac..4f12b0dc4da 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -97,7 +97,7 @@ proto.tryCreatePlot = function() { gl: scene.gl, glOptions: { preserveDrawingBuffer: isMobile, - premultipliedAlpha: false, + premultipliedAlpha: true, antialias: true }, container: scene.container, From ff2ecc796dd0607b7a07baac8a20e6104adbfe31 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 28 Jan 2020 16:42:44 -0500 Subject: [PATCH 11/11] list is-mobile in package.json - it was already in package-lock --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index d7bd2c32860..52c6dc3fe7c 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "glslify": "^7.0.0", "has-hover": "^1.0.1", "has-passive-events": "^1.0.0", + "is-mobile": "^2.1.0", "mapbox-gl": "1.3.2", "matrix-camera-controller": "^2.1.3", "mouse-change": "^1.4.0",