From 5d6ce26d288941e5d5d8c03699b74ff1797191fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 5 Feb 2016 14:17:14 -0500 Subject: [PATCH 01/15] fix broken paths to gl3d images --- devtools/test_dashboard/test_gl3d.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devtools/test_dashboard/test_gl3d.js b/devtools/test_dashboard/test_gl3d.js index c4d26b11675..902cb8e0305 100644 --- a/devtools/test_dashboard/test_gl3d.js +++ b/devtools/test_dashboard/test_gl3d.js @@ -24,11 +24,11 @@ plots['projection-traces'] = require('@mocks/gl3d_projection-traces.json'); plots['opacity-scaling-spikes'] = require('@mocks/gl3d_opacity-scaling-spikes.json'); plots['text-weirdness'] = require('@mocks/gl3d_text-weirdness.json'); plots['wire-surface'] = require('@mocks/gl3d_wire-surface.json'); -plots['triangle-mesh3d'] = require('@mocks/gl3d_triangle.json'); +plots['triangle'] = require('@mocks/gl3d_triangle.json'); plots['snowden'] = require('@mocks/gl3d_snowden.json'); plots['bunny'] = require('@mocks/gl3d_bunny.json'); plots['ribbons'] = require('@mocks/gl3d_ribbons.json'); -plots['scatter-time'] = require('@mocks/gl3d_scatter-date.json'); +plots['scatter-date'] = require('@mocks/gl3d_scatter-date.json'); plots['cufflinks'] = require('@mocks/gl3d_cufflinks.json'); plots['chrisp-nan-1'] = require('@mocks/gl3d_chrisp-nan-1.json'); plots['marker-arrays'] = require('@mocks/gl3d_marker-arrays.json'); From 75f243cb09e321a276c10ee5a3cf12172c35ab43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 5 Feb 2016 17:27:32 -0500 Subject: [PATCH 02/15] pass graphDiv to scene constructor --- src/plots/gl3d/index.js | 3 ++- src/plots/gl3d/scene.js | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plots/gl3d/index.js b/src/plots/gl3d/index.js index beccb231bfc..bc6cff16ab9 100644 --- a/src/plots/gl3d/index.js +++ b/src/plots/gl3d/index.js @@ -51,8 +51,9 @@ exports.plot = function plotGl3d(gd) { // If Scene is not instantiated, create one! if(scene === undefined) { scene = new Scene({ - container: gd.querySelector('.gl-container'), id: sceneId, + graphDiv: gd, + container: gd.querySelector('.gl-container'), staticPlot: gd._context.staticPlot, plotGlPixelRatio: gd._context.plotGlPixelRatio }, diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index db742d5bb0b..97161eb380e 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -180,6 +180,8 @@ function Scene(options, fullLayout) { 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', From f0599577d545a628c3a902e002307adef9116339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 5 Feb 2016 17:28:14 -0500 Subject: [PATCH 03/15] format hover labels before filtering them --- src/plots/gl3d/scene.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 97161eb380e..55c8383dc5e 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -68,23 +68,28 @@ function render(scene) { if(lastPicked !== null) { var pdata = project(scene.glplot.cameraParams, selection.dataCoordinate), - hoverinfo = lastPicked.data.hoverinfo; + trace = lastPicked.data, + hoverinfo = trace.hoverinfo; + + var xVal = formatter('xaxis', selection.traceCoordinate[0]), + yVal = formatter('yaxis', selection.traceCoordinate[1]), + zVal = formatter('zaxis', selection.traceCoordinate[2]); if(hoverinfo !== 'all') { var hoverinfoParts = hoverinfo.split('+'); - if(hoverinfoParts.indexOf('x') === -1) selection.traceCoordinate[0] = undefined; - if(hoverinfoParts.indexOf('y') === -1) selection.traceCoordinate[1] = undefined; - if(hoverinfoParts.indexOf('z') === -1) selection.traceCoordinate[2] = undefined; + if(hoverinfoParts.indexOf('x') === -1) xVal = undefined; + if(hoverinfoParts.indexOf('y') === -1) yVal = undefined; + if(hoverinfoParts.indexOf('z') === -1) zVal = undefined; if(hoverinfoParts.indexOf('text') === -1) selection.textLabel = undefined; if(hoverinfoParts.indexOf('name') === -1) lastPicked.name = undefined; } Fx.loneHover({ - x: (0.5 + 0.5 * pdata[0]/pdata[3]) * width, - y: (0.5 - 0.5 * pdata[1]/pdata[3]) * height, - xLabel: formatter('xaxis', selection.traceCoordinate[0]), - yLabel: formatter('yaxis', selection.traceCoordinate[1]), - zLabel: formatter('zaxis', selection.traceCoordinate[2]), + x: (0.5 + 0.5 * pdata[0] / pdata[3]) * width, + y: (0.5 - 0.5 * pdata[1] / pdata[3]) * height, + xLabel: xVal, + yLabel: yVal, + zLabel: zVal, text: selection.textLabel, name: lastPicked.name, color: lastPicked.color From fdba7f1e54c78788deb364bc8660928394a5a53f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 5 Feb 2016 17:29:39 -0500 Subject: [PATCH 04/15] add hover+click event trigger in render loop: - makes use of (new) selection.buttons to determine if event is hover or click. --- src/plots/gl3d/scene.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 55c8383dc5e..c2c22678abe 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -66,6 +66,20 @@ function render(scene) { return Axes.tickText(axis, axis.c2l(val), 'hover').text; } + function makeEventData(xVal, yVal, zVal, trace, selection) { + return {points: [{ + x: xVal, + y: yVal, + z: zVal, + data: trace._input, + fullData: trace, + curveNumber: trace.index, + pointNumber: selection.data.index + }]}; + } + + var oldEventData; + if(lastPicked !== null) { var pdata = project(scene.glplot.cameraParams, selection.dataCoordinate), trace = lastPicked.data, @@ -96,8 +110,17 @@ function render(scene) { }, { container: svgContainer }); + + var eventType = (selection.buttons) ? 'plotly_click' : 'plotly_hover', + eventData = makeEventData(xVal, yVal, zVal, trace, selection); + + scene.graphDiv.emit(eventType, eventData); + oldEventData = eventData; + } + else { + Fx.loneUnhover(svgContainer); + scene.graphDiv.emit('plotly_unhover', oldEventData); } - else Fx.loneUnhover(svgContainer); } function initializeGLPlot(scene, fullLayout, canvas, gl) { From a2f61b7c3a78426ff024b5f16ea5373c6deea538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 5 Feb 2016 17:29:51 -0500 Subject: [PATCH 05/15] lint --- src/plots/gl3d/scene.js | 16 ++++++++-------- src/plots/plots.js | 7 +++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index c2c22678abe..6b7e76cb4c7 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -34,7 +34,7 @@ var STATIC_CANVAS, STATIC_CONTEXT; function render(scene) { - //Update size of svg container + // update size of svg container var svgContainer = scene.svgContainer; var clientRect = scene.container.getBoundingClientRect(); var width = clientRect.width, height = clientRect.height; @@ -45,7 +45,7 @@ function render(scene) { computeTickMarks(scene); scene.glplot.axes.update(scene.axesOptions); - //Check if pick has changed + // check if pick has changed var keys = Object.keys(scene.traces); var lastPicked = null; var selection = scene.glplot.selection; @@ -59,7 +59,6 @@ function render(scene) { } function formatter(axisName, val) { - if(val === undefined) return undefined; if(typeof val === 'string') return val; var axis = scene.fullSceneLayout[axisName]; @@ -136,9 +135,9 @@ function initializeGLPlot(scene, fullLayout, canvas, gl) { autoBounds: false }; - //For static plots, we reuse the WebGL context as WebKit doesn't collect them - //reliably - if (scene.staticMode) { + // for static plots, we reuse the WebGL context + // as WebKit doesn't collect them reliably + if(scene.staticMode) { if(!STATIC_CONTEXT) { STATIC_CANVAS = document.createElement('canvas'); try { @@ -204,13 +203,14 @@ function initializeGLPlot(scene, fullLayout, canvas, gl) { function Scene(options, fullLayout) { - //Create sub container for plot + // 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 + + // create SVG container for hover text var svgContainer = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg'); diff --git a/src/plots/plots.js b/src/plots/plots.js index 595296de3d7..8c74931ba98 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -470,11 +470,10 @@ plots.supplyDefaults = function(gd) { }; function cleanScenes(newFullLayout, oldFullLayout) { - var oldSceneKey, - oldSceneKeys = plots.getSubplotIds(oldFullLayout, 'gl3d'); + var oldSceneKeys = plots.getSubplotIds(oldFullLayout, 'gl3d'); - for (var i = 0; i < oldSceneKeys.length; i++) { - oldSceneKey = oldSceneKeys[i]; + for(var i = 0; i < oldSceneKeys.length; i++) { + var oldSceneKey = oldSceneKeys[i]; if(!newFullLayout[oldSceneKey] && !!oldFullLayout[oldSceneKey]._scene) { oldFullLayout[oldSceneKey]._scene.destroy(); } From 930b05a4ade68b309848d612eff2a1e9a9ec22b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 5 Feb 2016 17:30:22 -0500 Subject: [PATCH 06/15] add 'opts' argument to mouseEvent asset --- test/jasmine/assets/mouse_event.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/jasmine/assets/mouse_event.js b/test/jasmine/assets/mouse_event.js index 053e98a8a1b..3b5628ab6d3 100644 --- a/test/jasmine/assets/mouse_event.js +++ b/test/jasmine/assets/mouse_event.js @@ -1,11 +1,16 @@ -module.exports = function(type, x, y) { - var options = { +module.exports = function(type, x, y, opts) { + var fullOpts = { bubbles: true, clientX: x, clientY: y }; + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent + if(opts) { + if(opts.buttons) fullOpts.buttons = opts.buttons; + } + var el = document.elementFromPoint(x,y); - var ev = new window.MouseEvent(type, options); + var ev = new window.MouseEvent(type, fullOpts); el.dispatchEvent(ev); }; From f1c4b61441bfe20c0c13b14ecc45369aa57b527e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 5 Feb 2016 17:30:37 -0500 Subject: [PATCH 07/15] add gl3d hover and click tests --- test/jasmine/tests/gl_plot_interact_test.js | 87 +++++++++++++++++++-- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index 2f7bf0b04a5..c82ea178dcb 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -4,6 +4,7 @@ var Plotly = require('@lib/index'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); +var mouseEvent = require('../assets/mouse_event'); /* * WebGL interaction test cases fail on the CircleCI @@ -11,22 +12,98 @@ var destroyGraphDiv = require('../assets/destroy_graph_div'); * */ +var PLOT_DELAY = 100; +var MOUSE_DELAY = 20; -describe('Test plot structure', function() { + +describe('Test gl plot interactions', function() { 'use strict'; afterEach(destroyGraphDiv); describe('gl3d plots', function() { var mock = require('@mocks/gl3d_marker-arrays.json'); + var gd; + + function mouseEventScatter3d(type, opts) { + mouseEvent(type, 605, 271, opts); + } beforeEach(function(done) { - Plotly.plot(createGraphDiv(), mock.data, mock.layout).then(done); + gd = createGraphDiv(); + Plotly.plot(gd, mock.data, mock.layout).then(done); }); - it('has one *canvas* node', function() { - var nodes = d3.selectAll('canvas'); - expect(nodes[0].length).toEqual(1); + describe('scatter3d hover', function() { + var node, ptData; + + beforeEach(function(done) { + gd.on('plotly_hover', function(eventData) { + ptData = eventData.points[0]; + }); + + setTimeout(function() { + mouseEventScatter3d('mouseover'); + setTimeout(done, MOUSE_DELAY); + }, PLOT_DELAY); + }); + + it('should have', function() { + node = d3.selectAll('canvas'); + expect(node[0].length).toEqual(1, 'one canvas node'); + + node = d3.selectAll('g.hovertext'); + expect(node.size()).toEqual(1, 'one hover text group'); + + node = d3.selectAll('g.hovertext').selectAll('tspan')[0]; + expect(node[0].innerHTML).toEqual('x: 140.72', 'x val on hover'); + expect(node[1].innerHTML).toEqual('y: −96.97', 'y val on hover'); + expect(node[2].innerHTML).toEqual('z: −96.97', 'z val on hover'); + + expect(Object.keys(ptData)).toEqual([ + 'x', 'y', 'z', + 'data', 'fullData', 'curveNumber', 'pointNumber' + ], 'correct hover data fields'); + + expect(ptData.x).toBe('140.72', 'x val hover data'); + expect(ptData.y).toBe('−96.97', 'y val hover data'); + expect(ptData.z).toEqual('−96.97', 'z val hover data'); + expect(ptData.curveNumber).toEqual(0, 'curveNumber hover data'); + expect(ptData.pointNumber).toEqual(2, 'pointNumber hover data'); + }); + + }); + + describe('scatter3d click events', function() { + var ptData; + + beforeEach(function(done) { + gd.on('plotly_click', function(eventData) { + ptData = eventData.points[0]; + }); + + setTimeout(function() { + + // N.B. gl3d click events are 'mouseover' events + // with button 1 pressed + mouseEventScatter3d('mouseover', {buttons: 1}); + setTimeout(done, MOUSE_DELAY); + }, PLOT_DELAY); + }); + + it('should have', function() { + expect(Object.keys(ptData)).toEqual([ + 'x', 'y', 'z', + 'data', 'fullData', 'curveNumber', 'pointNumber' + ], 'correct hover data fields'); + + + expect(ptData.x).toBe('140.72', 'x val click data'); + expect(ptData.y).toBe('−96.97', 'y val click data'); + expect(ptData.z).toEqual('−96.97', 'z val click data'); + expect(ptData.curveNumber).toEqual(0, 'curveNumber click data'); + expect(ptData.pointNumber).toEqual(2, 'pointNumber click data'); + }); }); }); From b87dbd09491fd3e7670a1cf2ea1f2b6b10a9a6ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Mon, 8 Feb 2016 09:54:43 -0500 Subject: [PATCH 08/15] rm some logic noise --- test/jasmine/assets/mouse_event.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jasmine/assets/mouse_event.js b/test/jasmine/assets/mouse_event.js index 3b5628ab6d3..5c09af0de76 100644 --- a/test/jasmine/assets/mouse_event.js +++ b/test/jasmine/assets/mouse_event.js @@ -6,8 +6,8 @@ module.exports = function(type, x, y, opts) { }; // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent - if(opts) { - if(opts.buttons) fullOpts.buttons = opts.buttons; + if(opts && opts.buttons) { + fullOpts.buttons = opts.buttons; } var el = document.elementFromPoint(x,y); From 2849724968222b6678764c3dc4fe996b0d2815bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Mon, 8 Feb 2016 09:55:52 -0500 Subject: [PATCH 09/15] exclude gl_plot_interact_test from local test runs, - add instructions on how to manually test gl interaction specs --- test/jasmine/karma.conf.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/jasmine/karma.conf.js b/test/jasmine/karma.conf.js index 54eed46b6be..769f5e986c1 100644 --- a/test/jasmine/karma.conf.js +++ b/test/jasmine/karma.conf.js @@ -39,8 +39,20 @@ func.defaultConfig = { testFileGlob ], - // list of files to exclude + /* + * WebGL interaction test cases don't run consistently + * across machines. Before each release, please make sure + * to run these with: + * + * npm run test-jasmine -- gl_plot_interact_test.js + * + * Or manually check their specs. + * + */ exclude: [ + (testFileGlob === 'tests/gl_plot_interact_test.js') ? + '' : + 'tests/gl_plot_interact_test.js' ], // preprocess matching files before serving them to the browser From 2e63d1ec35c8f479486ad0e17c39b31e5c844531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 24 Feb 2016 15:30:19 -0500 Subject: [PATCH 10/15] enfore a stricter distance req for gl3d click events --- src/plots/gl3d/scene.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index cfd46590fc6..ce4880894c6 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -112,10 +112,15 @@ function render(scene) { }); } - var eventType = (selection.buttons) ? 'plotly_click' : 'plotly_hover', - eventData = makeEventData(xVal, yVal, zVal, trace, selection); + var eventData = makeEventData(xVal, yVal, zVal, trace, selection); + + if(selection.buttons && selection.distance < 5) { + scene.graphDiv.emit('plotly_click', eventData); + } + else { + scene.graphDiv.emit('plotly_hover', eventData); + } - scene.graphDiv.emit(eventType, eventData); oldEventData = eventData; } else { From 964a81d5a284f9f1d9474783d82bfcdb2ea53f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 24 Feb 2016 15:30:52 -0500 Subject: [PATCH 11/15] destroy scenes after every gl plot tests --- test/jasmine/tests/gl_plot_interact_test.js | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index 235667a20bb..c7cbc918075 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -23,11 +23,31 @@ var MOUSE_DELAY = 20; describe('Test gl plot interactions', function() { 'use strict'; + var gd; + beforeEach(function() { jasmine.addMatchers(customMatchers); }); - afterEach(destroyGraphDiv); + afterEach(function() { + var fullLayout = gd._fullLayout, + sceneIds; + + sceneIds = Plots.getSubplotIds(fullLayout, 'gl3d'); + sceneIds.forEach(function(id) { + fullLayout[id]._scene.destroy(); + }); + + sceneIds = Plots.getSubplotIds(fullLayout, 'gl2d'); + sceneIds.forEach(function(id) { + var scene2d = fullLayout._plots[id]._scene2d; + scene2d.stopped = true; + scene2d.destroy(); + }); + + destroyGraphDiv(); + }); + describe('gl3d plots', function() { var mock = require('@mocks/gl3d_marker-arrays.json'); From f6f2e51ce623df729105aadb92633bc0c8cab4b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 24 Feb 2016 15:34:27 -0500 Subject: [PATCH 12/15] robustify gl interaction tests: - add timeout before each test in Plotly.plot promise - centralized timeout values - refer to one gd for all tests in suite --- test/jasmine/tests/gl_plot_interact_test.js | 51 +++++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index c7cbc918075..8aa12b16ad1 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -16,8 +16,9 @@ var customMatchers = require('../assets/custom_matchers'); * */ -var PLOT_DELAY = 100; +var PLOT_DELAY = 200; var MOUSE_DELAY = 20; +var MODEBAR_DELAY = 500; describe('Test gl plot interactions', function() { @@ -48,10 +49,14 @@ describe('Test gl plot interactions', function() { destroyGraphDiv(); }); + function delay(done) { + setTimeout(function() { + done(); + }, PLOT_DELAY); + } describe('gl3d plots', function() { var mock = require('@mocks/gl3d_marker-arrays.json'); - var gd; function mouseEventScatter3d(type, opts) { mouseEvent(type, 605, 271, opts); @@ -59,10 +64,13 @@ describe('Test gl plot interactions', function() { beforeEach(function(done) { gd = createGraphDiv(); - Plotly.plot(gd, mock.data, mock.layout).then(done); + Plotly.plot(gd, mock.data, mock.layout).then(function() { + delay(done); + }); }); describe('scatter3d hover', function() { + var node, ptData; beforeEach(function(done) { @@ -70,10 +78,11 @@ describe('Test gl plot interactions', function() { ptData = eventData.points[0]; }); + mouseEventScatter3d('mouseover'); + setTimeout(function() { - mouseEventScatter3d('mouseover'); - setTimeout(done, MOUSE_DELAY); - }, PLOT_DELAY); + done(); + }, MOUSE_DELAY); }); it('should have', function() { @@ -110,13 +119,13 @@ describe('Test gl plot interactions', function() { ptData = eventData.points[0]; }); - setTimeout(function() { + // N.B. gl3d click events are 'mouseover' events + // with button 1 pressed + mouseEventScatter3d('mouseover', {buttons: 1}); - // N.B. gl3d click events are 'mouseover' events - // with button 1 pressed - mouseEventScatter3d('mouseover', {buttons: 1}); - setTimeout(done, MOUSE_DELAY); - }, PLOT_DELAY); + setTimeout(function() { + done(); + }, MOUSE_DELAY); }); it('should have', function() { @@ -139,7 +148,11 @@ describe('Test gl plot interactions', function() { var mock = require('@mocks/gl2d_10.json'); beforeEach(function(done) { - Plotly.plot(createGraphDiv(), mock.data, mock.layout).then(done); + gd = createGraphDiv(); + + Plotly.plot(gd, mock.data, mock.layout).then(function() { + delay(done); + }); }); it('has one *canvas* node', function() { @@ -149,7 +162,7 @@ describe('Test gl plot interactions', function() { }); describe('gl3d modebar click handlers', function() { - var gd, modeBar; + var modeBar; beforeEach(function(done) { var mockData = [{ @@ -166,7 +179,8 @@ describe('Test gl plot interactions', function() { gd = createGraphDiv(); Plotly.plot(gd, mockData, mockLayout).then(function() { modeBar = gd._fullLayout._modeBar; - done(); + + delay(done); }); }); @@ -249,9 +263,6 @@ describe('Test gl plot interactions', function() { }); describe('buttons resetCameraDefault3d and resetCameraLastSave3d', function() { - // changes in scene objects are not instantaneous - var DELAY = 500; - it('should update the scene camera', function(done) { var sceneLayout = gd._fullLayout.scene, sceneLayout2 = gd._fullLayout.scene2, @@ -286,8 +297,8 @@ describe('Test gl plot interactions', function() { .toBeCloseToArray([2.5, 2.5, 2.5], 4); done(); - }, DELAY); - }, DELAY); + }, MODEBAR_DELAY); + }, MODEBAR_DELAY); }); }); From eebe7d0dfeda28326f916178d6e0b92149727603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 24 Feb 2016 15:35:06 -0500 Subject: [PATCH 13/15] undo 'exclude gl interactions tests' --- test/jasmine/karma.conf.js | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/test/jasmine/karma.conf.js b/test/jasmine/karma.conf.js index 769f5e986c1..c51d51ceee0 100644 --- a/test/jasmine/karma.conf.js +++ b/test/jasmine/karma.conf.js @@ -39,21 +39,7 @@ func.defaultConfig = { testFileGlob ], - /* - * WebGL interaction test cases don't run consistently - * across machines. Before each release, please make sure - * to run these with: - * - * npm run test-jasmine -- gl_plot_interact_test.js - * - * Or manually check their specs. - * - */ - exclude: [ - (testFileGlob === 'tests/gl_plot_interact_test.js') ? - '' : - 'tests/gl_plot_interact_test.js' - ], + exclude: [], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor From 97a45429bab8a2a9f4f2a0ee26facf3829f68f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 24 Feb 2016 22:55:08 -0500 Subject: [PATCH 14/15] rm unnecessary function call --- src/plots/gl3d/scene.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index ce4880894c6..24bca5395f5 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -65,18 +65,6 @@ function render(scene) { return Axes.tickText(axis, axis.c2l(val), 'hover').text; } - function makeEventData(xVal, yVal, zVal, trace, selection) { - return {points: [{ - x: xVal, - y: yVal, - z: zVal, - data: trace._input, - fullData: trace, - curveNumber: trace.index, - pointNumber: selection.data.index - }]}; - } - var oldEventData; if(lastPicked !== null) { @@ -112,7 +100,17 @@ function render(scene) { }); } - var eventData = makeEventData(xVal, yVal, zVal, trace, selection); + var eventData = { + points: [{ + x: xVal, + y: yVal, + z: zVal, + data: trace._input, + fullData: trace, + curveNumber: trace.index, + pointNumber: selection.data.index + }] + }; if(selection.buttons && selection.distance < 5) { scene.graphDiv.emit('plotly_click', eventData); From fa126038594c6cbe02dc8813362f7ed802b4e20d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Thu, 25 Feb 2016 10:51:00 -0500 Subject: [PATCH 15/15] bump gl-plot3d dep --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b6060ebb3a0..fb9e9e298f0 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "gl-mat4": "^1.1.2", "gl-mesh3d": "^1.0.7", "gl-plot2d": "^1.1.6", - "gl-plot3d": "^1.3.0", + "gl-plot3d": "^1.5.0", "gl-scatter2d": "^1.0.5", "gl-scatter2d-fancy": "^1.1.1", "gl-scatter3d": "^1.0.4",