diff --git a/src/plot_api/subroutines.js b/src/plot_api/subroutines.js index 70fde722d61..6dd3cfa8efa 100644 --- a/src/plot_api/subroutines.js +++ b/src/plot_api/subroutines.js @@ -462,21 +462,21 @@ exports.drawMainTitle = function(gd) { }); }; -// First, see if we need to do arraysToCalcdata -// call it regardless of what change we made, in case -// supplyDefaults brought in an array that was already -// in gd.data but not in gd._fullData previously exports.doTraceStyle = function(gd) { - var fullLayout = gd._fullLayout; + var calcdata = gd.calcdata; var editStyleCalls = []; var i; - for(i = 0; i < gd.calcdata.length; i++) { - var cd = gd.calcdata[i]; + for(i = 0; i < calcdata.length; i++) { + var cd = calcdata[i]; var cd0 = cd[0] || {}; var trace = cd0.trace || {}; var _module = trace._module || {}; + // See if we need to do arraysToCalcdata + // call it regardless of what change we made, in case + // supplyDefaults brought in an array that was already + // in gd.data but not in gd._fullData previously var arraysToCalcdata = _module.arraysToCalcdata; if(arraysToCalcdata) arraysToCalcdata(cd, trace); @@ -485,16 +485,12 @@ exports.doTraceStyle = function(gd) { } if(editStyleCalls.length) { - clearGlCanvases(gd); - - if(fullLayout._hasOnlyLargeSploms) { - fullLayout._splomGrid.draw(); - } - for(i = 0; i < editStyleCalls.length; i++) { var edit = editStyleCalls[i]; edit.fn(gd, edit.cd0); } + clearGlCanvases(gd); + exports.redrawReglTraces(gd); } Plots.style(gd); @@ -546,8 +542,9 @@ exports.doTicksRelayout = function(gd) { Axes.doTicks(gd, 'redraw'); if(gd._fullLayout._hasOnlyLargeSploms) { + Registry.subplotsRegistry.splom.updateGrid(gd); clearGlCanvases(gd); - Registry.subplotsRegistry.splom.plot(gd); + exports.redrawReglTraces(gd); } exports.drawMainTitle(gd); @@ -600,6 +597,8 @@ exports.drawData = function(gd) { basePlotModules[i].plot(gd); } + exports.redrawReglTraces(gd); + // styling separate from drawing Plots.style(gd); @@ -613,6 +612,61 @@ exports.drawData = function(gd) { return Plots.previousPromises(gd); }; +// Draw (or redraw) all traces in one go, +// useful during drag and selection where buffers of targeted traces are updated, +// but all traces need to be redrawn following clearGlCanvases. +// +// Note that _module.plot for regl trace does NOT draw things +// on the canvas, they only update the buffers. +// Drawing is perform here. +// +// TODO try adding per-subplot option using gl.SCISSOR_TEST for +// non-overlaying, disjoint subplots. +// +// TODO try to include parcoords in here. +exports.redrawReglTraces = function(gd) { + var fullLayout = gd._fullLayout; + + if(fullLayout._has('regl')) { + var fullData = gd._fullData; + var cartesianIds = []; + var polarIds = []; + var i, sp; + + if(fullLayout._hasOnlyLargeSploms) { + fullLayout._splomGrid.draw(); + } + + // N.B. + // - Loop over fullData (not _splomScenes) to preserve splom trace-to-trace ordering + // - Fill list if subplot ids (instead of fullLayout._subplots) to handle cases where all traces + // of a given module are `visible !== true` + for(i = 0; i < fullData.length; i++) { + var trace = fullData[i]; + + if(trace.visible === true) { + if(trace.type === 'splom') { + fullLayout._splomScenes[trace.uid].draw(); + } else if(trace.type === 'scattergl') { + Lib.pushUnique(cartesianIds, trace.xaxis + trace.yaxis); + } else if(trace.type === 'scatterpolargl') { + Lib.pushUnique(polarIds, trace.subplot); + } + } + } + + for(i = 0; i < cartesianIds.length; i++) { + sp = fullLayout._plots[cartesianIds[i]]; + if(sp._scene) sp._scene.draw(); + } + + for(i = 0; i < polarIds.length; i++) { + sp = fullLayout[polarIds[i]]._subplot; + if(sp._scene) sp._scene.draw(); + } + } +}; + exports.doAutoRangeAndConstraints = function(gd) { var axList = Axes.list(gd, '', true); diff --git a/src/plots/cartesian/dragbox.js b/src/plots/cartesian/dragbox.js index f9abcb1da6a..6f8d03c8cc2 100644 --- a/src/plots/cartesian/dragbox.js +++ b/src/plots/cartesian/dragbox.js @@ -16,13 +16,14 @@ var supportsPassive = require('has-passive-events'); var Registry = require('../../registry'); var Lib = require('../../lib'); var svgTextUtils = require('../../lib/svg_text_utils'); -var clearGlCanvases = require('../../lib/clear_gl_canvases'); var Color = require('../../components/color'); var Drawing = require('../../components/drawing'); var Fx = require('../../components/fx'); var setCursor = require('../../lib/setcursor'); var dragElement = require('../../components/dragelement'); var FROM_TL = require('../../constants/alignment').FROM_TL; +var clearGlCanvases = require('../../lib/clear_gl_canvases'); +var redrawReglTraces = require('../../plot_api/subroutines').redrawReglTraces; var Plots = require('../plots'); @@ -84,7 +85,7 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) { // do we need to edit x/y ranges? var editX, editY; // graph-wide optimization flags - var hasScatterGl, hasOnlyLargeSploms, hasSplom, hasSVG; + var hasScatterGl, hasSplom, hasSVG; // collected changes to be made to the plot by relayout at the end var updates; @@ -125,8 +126,7 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) { var fullLayout = gd._fullLayout; hasScatterGl = fullLayout._has('scattergl'); - hasOnlyLargeSploms = fullLayout._hasOnlyLargeSploms; - hasSplom = hasOnlyLargeSploms || fullLayout._has('splom'); + hasSplom = fullLayout._has('splom'); hasSVG = fullLayout._has('svg'); } @@ -744,33 +744,29 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) { var subplots = fullLayout._subplots.cartesian; var i, sp, xa, ya; - if(hasSplom || hasScatterGl) { - clearGlCanvases(gd); - } - if(hasSplom) { Registry.subplotsRegistry.splom.drag(gd); - if(hasOnlyLargeSploms) return; } if(hasScatterGl) { - // loop over all subplots (w/o exceptions) here, - // as we cleared the gl canvases above for(i = 0; i < subplots.length; i++) { sp = plotinfos[subplots[i]]; xa = sp.xaxis; ya = sp.yaxis; - var scene = sp._scene; - if(scene) { - // FIXME: possibly we could update axis internal _r and _rl here + if(sp._scene) { var xrng = Lib.simpleMap(xa.range, xa.r2l); var yrng = Lib.simpleMap(ya.range, ya.r2l); - scene.update({range: [xrng[0], yrng[0], xrng[1], yrng[1]]}); + sp._scene.update({range: [xrng[0], yrng[0], xrng[1], yrng[1]]}); } } } + if(hasSplom || hasScatterGl) { + clearGlCanvases(gd); + redrawReglTraces(gd); + } + if(hasSVG) { var xScaleFactor = viewBox[2] / xa0._length; var yScaleFactor = viewBox[3] / ya0._length; diff --git a/src/plots/cartesian/select.js b/src/plots/cartesian/select.js index 31200f8fb1f..35d39d285a6 100644 --- a/src/plots/cartesian/select.js +++ b/src/plots/cartesian/select.js @@ -19,7 +19,8 @@ var polygon = require('../../lib/polygon'); var throttle = require('../../lib/throttle'); var makeEventData = require('../../components/fx/helpers').makeEventData; var getFromId = require('./axis_ids').getFromId; -var sortModules = require('../sort_modules').sortModules; +var clearGlCanvases = require('../../lib/clear_gl_canvases'); +var redrawReglTraces = require('../../plot_api/subroutines').redrawReglTraces; var constants = require('./constants'); var MINSELECT = constants.MINSELECT; @@ -663,7 +664,7 @@ function isOnlyOnePointSelected(searchTraces) { } function updateSelectedState(gd, searchTraces, eventData) { - var i, j, searchInfo, trace; + var i, searchInfo, cd, trace; if(eventData) { var pts = eventData.points || []; @@ -696,43 +697,25 @@ function updateSelectedState(gd, searchTraces, eventData) { } } - // group searchInfo traces by trace modules - var lookup = {}; + var hasRegl = false; for(i = 0; i < searchTraces.length; i++) { searchInfo = searchTraces[i]; + cd = searchInfo.cd; + trace = cd[0].trace; - var name = searchInfo._module.name; - if(lookup[name]) { - lookup[name].push(searchInfo); - } else { - lookup[name] = [searchInfo]; + if(Registry.traceIs(trace, 'regl')) { + hasRegl = true; } + + var _module = searchInfo._module; + var fn = _module.styleOnSelect || _module.style; + if(fn) fn(gd, cd); } - var keys = Object.keys(lookup).sort(sortModules); - - for(i = 0; i < keys.length; i++) { - var items = lookup[keys[i]]; - var len = items.length; - var item0 = items[0]; - var trace0 = item0.cd[0].trace; - var _module = item0._module; - var styleSelection = _module.styleOnSelect || _module.style; - - if(Registry.traceIs(trace0, 'regl')) { - // plot regl traces per module - var cds = new Array(len); - for(j = 0; j < len; j++) { - cds[j] = items[j].cd; - } - styleSelection(gd, cds); - } else { - // plot svg trace per trace - for(j = 0; j < len; j++) { - styleSelection(gd, items[j].cd); - } - } + if(hasRegl) { + clearGlCanvases(gd); + redrawReglTraces(gd); } } diff --git a/src/plots/plots.js b/src/plots/plots.js index 8f172d14ba0..b0092864c61 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -20,7 +20,6 @@ var Color = require('../components/color'); var BADNUM = require('../constants/numerical').BADNUM; var axisIDs = require('../plots/cartesian/axis_ids'); -var sortBasePlotModules = require('./sort_modules').sortBasePlotModules; var animationAttrs = require('./animation_attributes'); var frameAttrs = require('./frame_attributes'); @@ -487,9 +486,6 @@ plots.supplyDefaults = function(gd, opts) { if(!skipUpdateCalc && oldCalcdata.length === newFullData.length) { plots.supplyDefaultsUpdateCalc(oldCalcdata, newFullData); } - - // sort base plot modules for consistent ordering - newFullLayout._basePlotModules.sort(sortBasePlotModules); }; plots.supplyDefaultsUpdateCalc = function(oldCalcdata, newFullData) { diff --git a/src/plots/polar/polar.js b/src/plots/polar/polar.js index 0fc1b6e3a77..97142b3a31d 100644 --- a/src/plots/polar/polar.js +++ b/src/plots/polar/polar.js @@ -28,6 +28,8 @@ var prepSelect = require('../cartesian/select').prepSelect; var selectOnClick = require('../cartesian/select').selectOnClick; var clearSelect = require('../cartesian/select').clearSelect; var setCursor = require('../../lib/setcursor'); +var clearGlCanvases = require('../../lib/clear_gl_canvases'); +var redrawReglTraces = require('../../plot_api/subroutines').redrawReglTraces; var MID_SHIFT = require('../../constants/alignment').MID_SHIFT; var constants = require('./constants'); @@ -1058,7 +1060,7 @@ proto.updateRadialDrag = function(fullLayout, polarLayout, rngIndex) { .attr('transform', strTranslate(cx, cy)) .selectAll('path').attr('transform', null); - if(_this._scene) _this._scene.clear(); + var hasRegl = false; for(var traceType in _this.traceHash) { var moduleCalcData = _this.traceHash[traceType]; @@ -1066,6 +1068,12 @@ proto.updateRadialDrag = function(fullLayout, polarLayout, rngIndex) { var _module = moduleCalcData[0][0].trace._module; var polarLayoutNow = gd._fullLayout[_this.id]; _module.plot(gd, _this, moduleCalcDataVisible, polarLayoutNow); + if(Registry.traceIs(traceType, 'gl') && moduleCalcDataVisible.length) hasRegl = true; + } + + if(hasRegl) { + clearGlCanvases(gd); + redrawReglTraces(gd); } } @@ -1185,7 +1193,7 @@ proto.updateAngularDrag = function(fullLayout) { scatterTraces.call(Drawing.hideOutsideRangePoints, _this); } - if(_this._scene) _this._scene.clear(); + var hasRegl = false; for(var traceType in _this.traceHash) { if(Registry.traceIs(traceType, 'gl')) { @@ -1193,8 +1201,14 @@ proto.updateAngularDrag = function(fullLayout) { var moduleCalcDataVisible = Lib.filterVisible(moduleCalcData); var _module = moduleCalcData[0][0].trace._module; _module.plot(gd, _this, moduleCalcDataVisible, polarLayoutNow); + if(moduleCalcDataVisible.length) hasRegl = true; } } + + if(hasRegl) { + clearGlCanvases(gd); + redrawReglTraces(gd); + } } function doneFn() { diff --git a/src/plots/sort_modules.js b/src/plots/sort_modules.js deleted file mode 100644 index 38090667d40..00000000000 --- a/src/plots/sort_modules.js +++ /dev/null @@ -1,25 +0,0 @@ -/** -* Copyright 2012-2018, Plotly, Inc. -* All rights reserved. -* -* This source code is licensed under the MIT license found in the -* LICENSE file in the root directory of this source tree. -*/ - -'use strict'; - -// always plot splom before cartesian (i.e. scattergl traces) -function sortModules(a, b) { - if(a === 'splom') return -1; - if(b === 'splom') return 1; - return 0; -} - -function sortBasePlotModules(a, b) { - return sortModules(a.name, b.name); -} - -module.exports = { - sortBasePlotModules: sortBasePlotModules, - sortModules: sortModules -}; diff --git a/src/traces/scattergl/index.js b/src/traces/scattergl/index.js index 4aa5bfb1abe..8b4d7dc4f7f 100644 --- a/src/traces/scattergl/index.js +++ b/src/traces/scattergl/index.js @@ -252,8 +252,6 @@ function sceneUpdate(gd, subplot) { scene.glText[i].update(opt); } } - - scene.draw(); }; // draw traces in proper order @@ -296,18 +294,6 @@ function sceneUpdate(gd, subplot) { scene.dirty = false; }; - scene.clear = function clear() { - var vp = getViewport(gd._fullLayout, subplot.xaxis, subplot.yaxis); - - if(scene.select2d) { - clearViewport(scene.select2d, vp); - } - - var anyComponent = scene.scatter2d || scene.line2d || - (scene.glText || [])[0] || scene.fill2d || scene.error2d; - if(anyComponent) clearViewport(anyComponent, vp); - }; - // remove scene resources scene.destroy = function destroy() { if(scene.fill2d) scene.fill2d.destroy(); @@ -359,14 +345,6 @@ function getViewport(fullLayout, xaxis, yaxis) { ]; } -function clearViewport(comp, vp) { - var gl = comp.regl._gl; - gl.enable(gl.SCISSOR_TEST); - gl.scissor(vp[0], vp[1], vp[2] - vp[0], vp[3] - vp[1]); - gl.clearColor(0, 0, 0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); -} - function plot(gd, subplot, cdata) { if(!cdata.length) return; @@ -640,8 +618,6 @@ function plot(gd, subplot, cdata) { if(scene.glText) { scene.glText.forEach(function(text) { text.update(vpRange0); }); } - - scene.draw(); } @@ -893,19 +869,6 @@ function selectPoints(searchInfo, selectionTester) { return selection; } -function styleOnSelect(gd, cds) { - var stash = cds[0][0].t; - var scene = stash._scene; - - // don't clear the subplot if there are splom traces - // on the graph - if(!gd._fullLayout._has('splom')) { - scene.clear(); - } - - scene.draw(); -} - function styleTextSelection(cd) { var cd0 = cd[0]; var stash = cd0.t; @@ -955,7 +918,6 @@ module.exports = { calc: calc, plot: plot, hoverPoints: hoverPoints, - styleOnSelect: styleOnSelect, selectPoints: selectPoints, sceneOptions: sceneOptions, diff --git a/src/traces/scatterpolargl/index.js b/src/traces/scatterpolargl/index.js index 70024feb649..f317682eb90 100644 --- a/src/traces/scatterpolargl/index.js +++ b/src/traces/scatterpolargl/index.js @@ -183,7 +183,6 @@ module.exports = { calc: calc, plot: plot, hoverPoints: hoverPoints, - styleOnSelect: ScatterGl.styleOnSelect, selectPoints: ScatterGl.selectPoints, meta: { diff --git a/src/traces/splom/base_plot.js b/src/traces/splom/base_plot.js index c143a5d551a..6e3b211fa05 100644 --- a/src/traces/splom/base_plot.js +++ b/src/traces/splom/base_plot.js @@ -28,7 +28,7 @@ function plot(gd) { if(!success) return; if(fullLayout._hasOnlyLargeSploms) { - drawGrid(gd); + updateGrid(gd); } _module.plot(gd, {}, splomCalcData); @@ -39,7 +39,7 @@ function drag(gd) { var fullLayout = gd._fullLayout; if(fullLayout._hasOnlyLargeSploms) { - drawGrid(gd); + updateGrid(gd); } for(var i = 0; i < cd.length; i++) { @@ -77,14 +77,12 @@ function dragOne(gd, trace, scene) { if(scene.selectBatch) { scene.matrix.update({ranges: ranges}, {ranges: ranges}); - scene.matrix.draw(scene.unselectBatch, scene.selectBatch); } else { scene.matrix.update({ranges: ranges}); - scene.matrix.draw(); } } -function drawGrid(gd) { +function updateGrid(gd) { var fullLayout = gd._fullLayout; var regl = fullLayout._glcanvas.data()[0].regl; var splomGrid = fullLayout._splomGrid; @@ -92,9 +90,7 @@ function drawGrid(gd) { if(!splomGrid) { splomGrid = fullLayout._splomGrid = createLine(regl); } - splomGrid.update(makeGridData(gd)); - splomGrid.draw(); } function makeGridData(gd) { @@ -238,6 +234,7 @@ module.exports = { drawFramework: Cartesian.drawFramework, plot: plot, drag: drag, + updateGrid: updateGrid, clean: clean, updateFx: updateFx, toSVG: Cartesian.toSVG diff --git a/src/traces/splom/index.js b/src/traces/splom/index.js index 17bc7b9f8d1..8e6e03e9091 100644 --- a/src/traces/splom/index.js +++ b/src/traces/splom/index.js @@ -139,11 +139,12 @@ function sceneUpdate(gd, trace) { scene = splomScenes[uid] = Lib.extendFlat({}, reset, first); scene.draw = function draw() { - // draw traces in selection mode - if(scene.matrix && scene.selectBatch) { - scene.matrix.draw(scene.unselectBatch, scene.selectBatch); - } else if(scene.matrix) { - scene.matrix.draw(); + if(scene.matrix && scene.matrix.draw) { + if(scene.selectBatch) { + scene.matrix.draw(scene.unselectBatch, scene.selectBatch); + } else { + scene.matrix.draw(); + } } scene.dirty = false; @@ -302,8 +303,6 @@ function plotOne(gd, cd0) { scene.matrix.update(opts, null); stash.xpx = stash.ypx = null; } - - scene.draw(); } function editStyle(gd, cd0) { @@ -319,8 +318,6 @@ function editStyle(gd, cd0) { // TODO this is too long for arrayOk attributes! scene.matrix.update(opts, null); - - scene.draw(); } function hoverPoints(pointData, xval, yval) { @@ -439,31 +436,6 @@ function selectPoints(searchInfo, selectionTester) { return selection; } -function styleOnSelect(gd, cds) { - var fullLayout = gd._fullLayout; - var cd0 = cds[0]; - var scene0 = fullLayout._splomScenes[cd0[0].trace.uid]; - scene0.matrix.regl.clear({color: true, depth: true}); - - if(fullLayout._splomGrid) { - fullLayout._splomGrid.draw(); - } - - for(var i = 0; i < cds.length; i++) { - var scene = fullLayout._splomScenes[cds[i][0].trace.uid]; - scene.draw(); - } - - // redraw all subplot with scattergl traces, - // as we cleared the whole canvas above - if(fullLayout._has('cartesian')) { - for(var k in fullLayout._plots) { - var sp = fullLayout._plots[k]; - if(sp._scene) sp._scene.draw(); - } - } -} - function getDimIndex(trace, ax) { var axId = ax._id; var axLetter = axId.charAt(0); @@ -492,7 +464,6 @@ module.exports = { plot: plot, hoverPoints: hoverPoints, selectPoints: selectPoints, - styleOnSelect: styleOnSelect, editStyle: editStyle, meta: { diff --git a/test/jasmine/tests/gl2d_click_test.js b/test/jasmine/tests/gl2d_click_test.js index c2b2121e386..34a826faca9 100644 --- a/test/jasmine/tests/gl2d_click_test.js +++ b/test/jasmine/tests/gl2d_click_test.js @@ -1135,4 +1135,47 @@ describe('@noCI Test gl2d lasso/select:', function() { .catch(failTest) .then(done); }); + + it('should work on overlaid subplots', function(done) { + gd = createGraphDiv(); + + var scene, scene2; + + Plotly.plot(gd, [{ + x: [1, 2, 3], + y: [40, 50, 60], + type: 'scattergl', + mode: 'markers' + }, { + x: [2, 3, 4], + y: [4, 5, 6], + yaxis: 'y2', + type: 'scattergl', + mode: 'markers' + }], { + xaxis: {domain: [0.2, 1]}, + yaxis2: {overlaying: 'y', side: 'left', position: 0}, + showlegend: false, + margin: {l: 0, t: 0, b: 0, r: 0}, + width: 400, + height: 400, + dragmode: 'select' + }) + .then(delay(100)) + .then(function() { + scene = gd._fullLayout._plots.xy._scene; + scene2 = gd._fullLayout._plots.xy2._scene; + + spyOn(scene.scatter2d, 'draw'); + spyOn(scene2.scatter2d, 'draw'); + }) + .then(function() { return select([[20, 20], [380, 250]]); }) + .then(function() { + expect(scene.scatter2d.draw).toHaveBeenCalledTimes(1); + expect(scene2.scatter2d.draw).toHaveBeenCalledTimes(1); + }) + .catch(failTest) + .then(done); + + }); }); diff --git a/test/jasmine/tests/gl2d_plot_interact_test.js b/test/jasmine/tests/gl2d_plot_interact_test.js index bb4e3a1dda5..aa01c2a671a 100644 --- a/test/jasmine/tests/gl2d_plot_interact_test.js +++ b/test/jasmine/tests/gl2d_plot_interact_test.js @@ -1182,7 +1182,10 @@ describe('Test scattergl autorange:', function() { describe('should return the approximative values for ~big~ data', function() { beforeEach(function() { - spyOn(ScatterGl, 'plot'); + // to avoid expansive draw calls (which could be problematic on CI) + spyOn(ScatterGl, 'plot').and.callFake(function(gd) { + gd._fullLayout._plots.xy._scene.scatter2d = {draw: function() {}}; + }); }); // threshold for 'fast' axis expansion routine diff --git a/test/jasmine/tests/plots_test.js b/test/jasmine/tests/plots_test.js index ede60e8b130..6e00acd23d7 100644 --- a/test/jasmine/tests/plots_test.js +++ b/test/jasmine/tests/plots_test.js @@ -153,26 +153,6 @@ describe('Test Plots', function() { testSanitizeMarginsHasBeenCalledOnlyOnce(gd); }); - - it('should sort base plot modules on fullLayout object', function() { - var gd = Lib.extendDeep({}, require('@mocks/plot_types.json')); - gd.data.unshift({type: 'scattergl'}); - gd.data.push({type: 'splom'}); - - supplyAllDefaults(gd); - var names = gd._fullLayout._basePlotModules.map(function(m) { - return m.name; - }); - - expect(names).toEqual([ - 'splom', - 'cartesian', - 'gl3d', - 'geo', - 'pie', - 'ternary' - ]); - }); }); describe('Plots.supplyLayoutGlobalDefaults should', function() { diff --git a/test/jasmine/tests/splom_test.js b/test/jasmine/tests/splom_test.js index 5760f4bb528..f7561562582 100644 --- a/test/jasmine/tests/splom_test.js +++ b/test/jasmine/tests/splom_test.js @@ -722,7 +722,7 @@ describe('Test splom interactions:', function() { .then(done); }); - it('@gl should clear graph and replot when canvas and WebGL context dimensions do not match', function(done) { + it('@noCI @gl should clear graph and replot when canvas and WebGL context dimensions do not match', function(done) { var fig = Lib.extendDeep({}, require('@mocks/splom_iris.json')); function assertDims(msg, w, h) { @@ -1298,23 +1298,26 @@ describe('Test splom select:', function() { var cnt = 0; var scatterGlCnt = 0; var splomCnt = 0; + var scatterglScene, splomScene; Plotly.newPlot(gd, fig).then(function() { - // 'scattergl' trace module - spyOn(gd._fullLayout._modules[0], 'styleOnSelect').and.callFake(function() { + var fullLayout = gd._fullLayout; + scatterglScene = fullLayout._plots.xy._scene; + splomScene = fullLayout._splomScenes[gd._fullData[1].uid]; + + spyOn(scatterglScene, 'draw').and.callFake(function() { cnt++; scatterGlCnt = cnt; }); - // 'splom' trace module - spyOn(gd._fullLayout._modules[1], 'styleOnSelect').and.callFake(function() { + spyOn(splomScene, 'draw').and.callFake(function() { cnt++; splomCnt = cnt; }); }) .then(function() { return _select([[20, 395], [195, 205]]); }) .then(function() { - expect(gd._fullLayout._modules[0].styleOnSelect).toHaveBeenCalledTimes(1); - expect(gd._fullLayout._modules[1].styleOnSelect).toHaveBeenCalledTimes(1); + expect(scatterglScene.draw).toHaveBeenCalledTimes(1); + expect(splomScene.draw).toHaveBeenCalledTimes(1); expect(cnt).toBe(2); expect(splomCnt).toBe(1, 'splom redraw before scattergl');