From c3312665d9bf1b6d73896c23326539d3f8e2a6ca Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 30 Jan 2018 18:54:42 -0500 Subject: [PATCH 1/9] Unify selection mode --- package.json | 3 +- src/plots/cartesian/select.js | 2 +- src/traces/scattergl/index.js | 138 ++++++++++++++++++++-------------- 3 files changed, 83 insertions(+), 60 deletions(-) diff --git a/package.json b/package.json index 5f6b9d8e5a2..f8a7be1bc79 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "3d-view": "^2.0.0", "@plotly/d3-sankey": "^0.5.0", "alpha-shape": "^1.0.0", + "array-range": "^1.0.1", "bubleify": "^1.0.0", "canvas-fit": "^1.5.0", "color-normalize": "^1.0.3", @@ -98,7 +99,7 @@ "regl": "^1.3.1", "regl-error2d": "^2.0.3", "regl-line2d": "^2.1.2", - "regl-scatter2d": "^2.1.12", + "regl-scatter2d": "^2.1.13", "right-now": "^1.0.0", "robust-orientation": "^1.1.3", "sane-topojson": "^2.0.0", diff --git a/src/plots/cartesian/select.js b/src/plots/cartesian/select.js index 92837250622..fe324c029a0 100644 --- a/src/plots/cartesian/select.js +++ b/src/plots/cartesian/select.js @@ -278,7 +278,7 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) { else { // TODO: remove in v2 - this was probably never intended to work as it does, // but in case anyone depends on it we don't want to break it now. - gd.emit('plotly_selected', undefined); + gd.emit('plotly_selected', {points: [], range: null}); } Fx.click(gd, evt); diff --git a/src/traces/scattergl/index.js b/src/traces/scattergl/index.js index f8d00352358..b2a61e9c1e5 100644 --- a/src/traces/scattergl/index.js +++ b/src/traces/scattergl/index.js @@ -28,6 +28,7 @@ var createError = require('regl-error2d'); var rgba = require('color-normalize'); var svgSdf = require('svg-path-sdf'); var createRegl = require('regl'); +var arrayRange = require('array-range'); var fillHoverText = require('../scatter/fill_hover_text'); var isNumeric = require('fast-isnumeric'); @@ -122,7 +123,6 @@ function calc(container, trace) { } } - calcColorscales(trace); var options = sceneOptions(container, subplot, trace, positions); @@ -599,6 +599,7 @@ function sceneUpdate(container, subplot) { scene.error2d.draw(i); scene.error2d.draw(i + scene.count); } + if(scene.scatter2d && !scene.selectBatch) { scene.scatter2d.draw(i); } @@ -740,8 +741,9 @@ function plot(container, subplot, cdata) { if(!cdata.length) return; var layout = container._fullLayout; - var stash = cdata[0][0].t; - var scene = stash.scene; + var scene = cdata[0][0].t.scene; + var i; + var dragmode = layout.dragmode; // we may have more subplots than initialized data due to Axes.getSubplots method if(!scene) return; @@ -782,6 +784,7 @@ function plot(container, subplot, cdata) { scene.fill2d = createLine(regl); } + // update main marker options if(scene.line2d) { scene.line2d.update(scene.lineOptions); } @@ -790,13 +793,7 @@ function plot(container, subplot, cdata) { scene.error2d.update(errorBatch); } if(scene.scatter2d) { - if(!scene.selectBatch) { - scene.scatter2d.update(scene.markerOptions); - } - else { - scene.scatter2d.update(scene.unselectedOptions); - scene.select2d.update(scene.selectedOptions); - } + scene.scatter2d.update(scene.markerOptions); } // fill requires linked traces, so we generate it's positions here if(scene.fill2d) { @@ -886,17 +883,77 @@ function plot(container, subplot, cdata) { scene.fill2d.update(scene.fillOptions); } - } - // make sure selection layer is initialized if we require selection - var dragmode = layout.dragmode; - if(dragmode === 'lasso' || dragmode === 'select') { - if(scene.select2d && scene.selectBatch) { - scene.scatter2d.update(scene.unselectedOptions); + // update selection + var hasSelectedPoints = false; + for(i = 0; i < cdata.length; i++) { + if(cdata[i][0].trace.selectedpoints) { + hasSelectedPoints = true; + break; + } + } + + if(scene.selectBatch || dragmode === 'lasso' || dragmode === 'select' || hasSelectedPoints) { + var newSelectBatch, newUnselectBatch; + + // create select2d + if(!scene.select2d) { + // create scatter instance by cloning scatter2d + scene.select2d = createScatter(layout._glcanvas.data()[1].regl, {clone: scene.scatter2d}); + } + + // regenerate scene batch, if traces number changed during selection + if(scene.selectBatch || hasSelectedPoints) { + if(!scene.selectBatch) scene.selectBatch = []; + if(!scene.unselectBatch) scene.unselectBatch = []; + + newSelectBatch = Array(scene.count); + newUnselectBatch = Array(scene.count); + + for(var j = 0; j < newSelectBatch.length; j++) { + var trace = cdata[j][0].trace; + var stash = cdata[j][0].t; + var id = stash.index; + + // form unselected batch + if(!scene.unselectBatch[id]) { + if(trace.selectedpoints) { + newSelectBatch[id] = trace.selectedpoints; + var selPts = trace.selectedpoints; + var selDict = {}; + for(i = 0; i < selPts.length; i++) { + selDict[selPts[i]] = true; + } + var unselPts = []; + for(i = 0; i < stash.count; i++) { + if(!selDict[i]) unselPts.push(i); + } + newUnselectBatch[id] = unselPts; + } + else { + newSelectBatch[id] = []; + newUnselectBatch[id] = arrayRange(stash.count); + } + } + else { + newSelectBatch[id] = scene.selectBatch[id]; + newUnselectBatch[id] = scene.unselectBatch[id]; + } + } + + scene.selectBatch = newSelectBatch; + scene.unselectBatch = newUnselectBatch; + + scene.scatter2d.update(scene.unselectedOptions); + } + + scene.select2d.update(scene.markerOptions); + scene.select2d.update(scene.selectedOptions); } } + // provide viewport and range var vpRange = cdata.map(function(cdscatter) { if(!cdscatter || !cdscatter[0] || !cdscatter[0].trace) return; @@ -925,41 +982,6 @@ function plot(container, subplot, cdata) { ]; if(trace.selectedpoints || dragmode === 'lasso' || dragmode === 'select') { - // create select2d - if(!scene.select2d && scene.scatter2d) { - var selectRegl = layout._glcanvas.data()[1].regl; - - // create scatter instance by cloning scatter2d - scene.select2d = createScatter(selectRegl, {clone: scene.scatter2d}); - scene.select2d.update(scene.selectedOptions); - - // create selection style once we have something selected - if(trace.selectedpoints && !scene.selectBatch) { - scene.selectBatch = Array(scene.count); - scene.unselectBatch = Array(scene.count); - scene.scatter2d.update(scene.unselectedOptions); - } - } - else { - // update selection positions, since they may have changed by panning or alike - scene.select2d.update(scene.selectedOptions); - } - - // form unselected batch - if(trace.selectedpoints && !scene.unselectBatch[stash.index]) { - scene.selectBatch[stash.index] = trace.selectedpoints; - var selPts = trace.selectedpoints; - var selDict = {}; - for(i = 0; i < selPts.length; i++) { - selDict[selPts[i]] = true; - } - var unselPts = []; - for(i = 0; i < stash.count; i++) { - if(!selDict[i]) unselPts.push(i); - } - scene.unselectBatch[stash.index] = unselPts; - } - // precalculate px coords since we are not going to pan during select var xpx = Array(stash.count), ypx = Array(stash.count); for(i = 0; i < stash.count; i++) { @@ -1193,18 +1215,18 @@ function selectPoints(searchInfo, polygon) { } } else { - unels = Array(stash.count); - for(i = 0; i < stash.count; i++) { - unels[i] = i; - } + unels = arrayRange(stash.count); } - // create selection style once we have something selected + // make sure selectBatch is created if(!scene.selectBatch) { - scene.selectBatch = Array(scene.count); - scene.unselectBatch = Array(scene.count); + scene.selectBatch = []; + scene.unselectBatch = []; + + // we should turn scatter2d into unselected once we have any points selected scene.scatter2d.update(scene.unselectedOptions); } + scene.selectBatch[stash.index] = els; scene.unselectBatch[stash.index] = unels; From c30e3f3dc3f22ce91d166f3c4b57d65bc8294846 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 31 Jan 2018 11:56:00 -0500 Subject: [PATCH 2/9] Decompatibilitize --- src/plots/cartesian/select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/cartesian/select.js b/src/plots/cartesian/select.js index fe324c029a0..92837250622 100644 --- a/src/plots/cartesian/select.js +++ b/src/plots/cartesian/select.js @@ -278,7 +278,7 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) { else { // TODO: remove in v2 - this was probably never intended to work as it does, // but in case anyone depends on it we don't want to break it now. - gd.emit('plotly_selected', {points: [], range: null}); + gd.emit('plotly_selected', undefined); } Fx.click(gd, evt); From a9d387aa14d3e2ade6768bcd2bbc20dcc22782b3 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 31 Jan 2018 12:16:24 -0500 Subject: [PATCH 3/9] Force plot opacity change --- src/traces/scattergl/attributes.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/traces/scattergl/attributes.js b/src/traces/scattergl/attributes.js index 0c69b843c0a..f358c70af0c 100644 --- a/src/traces/scattergl/attributes.js +++ b/src/traces/scattergl/attributes.js @@ -8,8 +8,9 @@ 'use strict'; +var plotAttrs = require('../../plots/attributes'); var scatterAttrs = require('../scatter/attributes'); -var colorAttributes = require('../../components/colorscale/color_attributes'); +var colorAttrs = require('../../components/colorscale/color_attributes'); var DASHES = require('../../constants/gl2d_dashes'); var extendFlat = require('../../lib/extend').extendFlat; @@ -56,7 +57,7 @@ var attrs = module.exports = overrideAll({ description: 'Sets the style of the lines.' } }, - marker: extendFlat({}, colorAttributes('marker'), { + marker: extendFlat({}, colorAttrs('marker'), { symbol: scatterMarkerAttrs.symbol, size: scatterMarkerAttrs.size, sizeref: scatterMarkerAttrs.sizeref, @@ -65,7 +66,7 @@ var attrs = module.exports = overrideAll({ opacity: scatterMarkerAttrs.opacity, showscale: scatterMarkerAttrs.showscale, colorbar: scatterMarkerAttrs.colorbar, - line: extendFlat({}, colorAttributes('marker.line'), { + line: extendFlat({}, colorAttrs('marker.line'), { width: scatterMarkerLineAttrs.width }) }), @@ -82,6 +83,10 @@ var attrs = module.exports = overrideAll({ marker: scatterAttrs.unselected.marker }, + opacity: extendFlat({}, plotAttrs.opacity, { + editType: 'calc' + }), + error_y: scatterAttrs.error_y, error_x: scatterAttrs.error_x }, 'calc', 'nested'); From 53c548fea8d3636577733496d3d67025612e5fb0 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 31 Jan 2018 13:13:10 -0500 Subject: [PATCH 4/9] Add opacity change test --- test/jasmine/tests/gl2d_plot_interact_test.js | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/test/jasmine/tests/gl2d_plot_interact_test.js b/test/jasmine/tests/gl2d_plot_interact_test.js index b2acdce3c53..c6209dd747a 100644 --- a/test/jasmine/tests/gl2d_plot_interact_test.js +++ b/test/jasmine/tests/gl2d_plot_interact_test.js @@ -4,6 +4,7 @@ var Plotly = require('@lib/index'); var Plots = require('@src/plots/plots'); var Lib = require('@src/lib'); var Drawing = require('@src/components/drawing'); +var ScatterGl = require('@src/traces/scattergl'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); @@ -14,6 +15,7 @@ var selectButton = require('../assets/modebar_button'); var delay = require('../assets/delay'); var readPixel = require('../assets/read_pixel'); + function countCanvases() { return d3.selectAll('canvas').size(); } @@ -406,7 +408,6 @@ describe('Test gl2d plots', function() { .then(done); }); - it('@noCI should display selection of big number of miscellaneous points', function(done) { var colorList = [ '#006385', '#F06E75', '#90ed7d', '#f7a35c', '#8085e9', @@ -645,4 +646,28 @@ describe('Test gl2d plots', function() { .catch(fail) .then(done); }); + + it('should restyle opacity', function(done) { + // #2299 + spyOn(ScatterGl, 'calc'); + + var dat = [{ + 'x': [1, 2, 3], + 'y': [1, 2, 3], + 'type': 'scattergl', + 'mode': 'markers' + }]; + + Plotly.plot(gd, dat, {width: 500, height: 500}) + .then(function() { + expect(ScatterGl.calc).toHaveBeenCalledTimes(1); + + return Plotly.restyle(gd, {'opacity': 0.1}); + }) + .then(function() { + expect(ScatterGl.calc).toHaveBeenCalledTimes(2); + }) + .catch(fail) + .then(done); + }); }); From 1da7796504f20b1784ee099967fb8080943b0136 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 31 Jan 2018 13:15:15 -0500 Subject: [PATCH 5/9] Add selected points test --- test/jasmine/tests/gl2d_plot_interact_test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/jasmine/tests/gl2d_plot_interact_test.js b/test/jasmine/tests/gl2d_plot_interact_test.js index c6209dd747a..b3f5c55286d 100644 --- a/test/jasmine/tests/gl2d_plot_interact_test.js +++ b/test/jasmine/tests/gl2d_plot_interact_test.js @@ -670,4 +670,8 @@ describe('Test gl2d plots', function() { .catch(fail) .then(done); }); + + fit('should update selected points', function(done) { + // #2298 + }); }); From 4e66ff5a88aaf5ddc3d10d505379667e198cee0e Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 31 Jan 2018 14:40:50 -0500 Subject: [PATCH 6/9] Add #2298 test --- test/jasmine/tests/gl2d_plot_interact_test.js | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/test/jasmine/tests/gl2d_plot_interact_test.js b/test/jasmine/tests/gl2d_plot_interact_test.js index b3f5c55286d..74dd210d66c 100644 --- a/test/jasmine/tests/gl2d_plot_interact_test.js +++ b/test/jasmine/tests/gl2d_plot_interact_test.js @@ -671,7 +671,50 @@ describe('Test gl2d plots', function() { .then(done); }); - fit('should update selected points', function(done) { + it('should update selected points', function(done) { // #2298 + var dat = [{ + 'x': [1], + 'y': [1], + 'type': 'scattergl', + 'mode': 'markers', + 'selectedpoints': [0] + }]; + + Plotly.plot(gd, dat, { + width: 500, + height: 500, + dragmode: 'select' + }) + .then(function() { + var scene = gd._fullLayout._plots.xy._scene; + + expect(scene.count).toBe(1); + expect(scene.selectBatch).toEqual([[0]]); + expect(scene.unselectBatch).toEqual([[]]); + spyOn(scene.scatter2d, 'draw'); + + var trace = { + x: [2], + y: [1], + type: 'scattergl', + mode: 'markers', + marker: {color: 'red'} + }; + + return Plotly.addTraces(gd, trace); + }) + .then(function() { + var scene = gd._fullLayout._plots.xy._scene; + + expect(scene.count).toBe(2); + expect(scene.selectBatch).toEqual([[0], []]); + expect(scene.unselectBatch).toEqual([[], [0]]); + expect(scene.markerOptions.length).toBe(2); + expect(scene.markerOptions[1].color).toEqual(new Uint8Array([255, 0, 0, 255])); + expect(scene.scatter2d.draw).toHaveBeenCalled(); + }) + .catch(fail) + .then(done); }); }); From ab5f6f0916e97648c998486bbf3a4ef4cf7fa3fe Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 1 Feb 2018 15:31:50 -0500 Subject: [PATCH 7/9] Make selection per-trace instead of per-plot --- src/traces/scattergl/index.js | 130 ++++++++++++++-------------------- 1 file changed, 55 insertions(+), 75 deletions(-) diff --git a/src/traces/scattergl/index.js b/src/traces/scattergl/index.js index b2a61e9c1e5..4692c377ba6 100644 --- a/src/traces/scattergl/index.js +++ b/src/traces/scattergl/index.js @@ -396,7 +396,9 @@ function sceneOptions(container, subplot, trace, positions) { function makeSelectedOptions(selected, markerOpts) { var options = {}; - if(selected.marker.symbol) { + if(!selected) return options; + + if(selected.marker && selected.marker.symbol) { options = makeMarkerOptions(extend({}, markerOpts, selected.marker)); } @@ -599,13 +601,15 @@ function sceneUpdate(container, subplot) { scene.error2d.draw(i); scene.error2d.draw(i + scene.count); } - - if(scene.scatter2d && !scene.selectBatch) { - scene.scatter2d.draw(i); + if(scene.scatter2d) { + // traces in no-selection mode + if(!scene.selectBatch || !scene.selectBatch[i]) { + scene.scatter2d.draw(i); + } } } - // persistent selection draw + // draw traces in selection mode if(scene.select2d && scene.selectBatch) { scene.select2d.draw(scene.selectBatch); scene.scatter2d.draw(scene.unselectBatch); @@ -742,7 +746,6 @@ function plot(container, subplot, cdata) { var layout = container._fullLayout; var scene = cdata[0][0].t.scene; - var i; var dragmode = layout.dragmode; // we may have more subplots than initialized data due to Axes.getSubplots method @@ -883,76 +886,9 @@ function plot(container, subplot, cdata) { scene.fill2d.update(scene.fillOptions); } - - - // update selection - var hasSelectedPoints = false; - for(i = 0; i < cdata.length; i++) { - if(cdata[i][0].trace.selectedpoints) { - hasSelectedPoints = true; - break; - } - } - - if(scene.selectBatch || dragmode === 'lasso' || dragmode === 'select' || hasSelectedPoints) { - var newSelectBatch, newUnselectBatch; - - // create select2d - if(!scene.select2d) { - // create scatter instance by cloning scatter2d - scene.select2d = createScatter(layout._glcanvas.data()[1].regl, {clone: scene.scatter2d}); - } - - // regenerate scene batch, if traces number changed during selection - if(scene.selectBatch || hasSelectedPoints) { - if(!scene.selectBatch) scene.selectBatch = []; - if(!scene.unselectBatch) scene.unselectBatch = []; - - newSelectBatch = Array(scene.count); - newUnselectBatch = Array(scene.count); - - for(var j = 0; j < newSelectBatch.length; j++) { - var trace = cdata[j][0].trace; - var stash = cdata[j][0].t; - var id = stash.index; - - // form unselected batch - if(!scene.unselectBatch[id]) { - if(trace.selectedpoints) { - newSelectBatch[id] = trace.selectedpoints; - var selPts = trace.selectedpoints; - var selDict = {}; - for(i = 0; i < selPts.length; i++) { - selDict[selPts[i]] = true; - } - var unselPts = []; - for(i = 0; i < stash.count; i++) { - if(!selDict[i]) unselPts.push(i); - } - newUnselectBatch[id] = unselPts; - } - else { - newSelectBatch[id] = []; - newUnselectBatch[id] = arrayRange(stash.count); - } - } - else { - newSelectBatch[id] = scene.selectBatch[id]; - newUnselectBatch[id] = scene.unselectBatch[id]; - } - } - - scene.selectBatch = newSelectBatch; - scene.unselectBatch = newUnselectBatch; - - scene.scatter2d.update(scene.unselectedOptions); - } - - scene.select2d.update(scene.markerOptions); - scene.select2d.update(scene.selectedOptions); - } } + var selectMode = dragmode === 'lasso' || dragmode === 'select'; // provide viewport and range var vpRange = cdata.map(function(cdscatter) { @@ -960,6 +896,7 @@ function plot(container, subplot, cdata) { var cd = cdscatter[0]; var trace = cd.trace; var stash = cd.t; + var id = stash.index; var x = stash.rawx, y = stash.rawy; @@ -981,7 +918,28 @@ function plot(container, subplot, cdata) { (height - vpSize.t) - (1 - yaxis.domain[1]) * vpSize.h ]; - if(trace.selectedpoints || dragmode === 'lasso' || dragmode === 'select') { + if(trace.selectedpoints || selectMode) { + if(!selectMode) selectMode = true; + + if(!scene.selectBatch) scene.selectBatch = []; + if(!scene.unselectBatch) scene.unselectBatch = []; + + // regenerate scene batch, if traces number changed during selection + if(trace.selectedpoints) { + scene.selectBatch[id] = trace.selectedpoints; + + var selPts = trace.selectedpoints; + var selDict = {}; + for(i = 0; i < selPts.length; i++) { + selDict[selPts[i]] = true; + } + var unselPts = []; + for(i = 0; i < stash.count; i++) { + if(!selDict[i]) unselPts.push(i); + } + scene.unselectBatch[id] = unselPts; + } + // precalculate px coords since we are not going to pan during select var xpx = Array(stash.count), ypx = Array(stash.count); for(i = 0; i < stash.count; i++) { @@ -1001,6 +959,21 @@ function plot(container, subplot, cdata) { } : null; }); + if(selectMode) { + // create select2d + if(!scene.select2d) { + // create scatter instance by cloning scatter2d + scene.select2d = createScatter(layout._glcanvas.data()[1].regl, {clone: scene.scatter2d}); + } + + // update only traces with selection + scene.scatter2d.update(scene.unselectedOptions.map(function(opts, i) { + return scene.selectBatch[i] ? opts : null; + })); + scene.select2d.update(scene.markerOptions); + scene.select2d.update(scene.selectedOptions); + } + // uploat viewport/range data to GPU if(scene.fill2d) { scene.fill2d.update(vpRange); @@ -1222,7 +1195,14 @@ function selectPoints(searchInfo, polygon) { if(!scene.selectBatch) { scene.selectBatch = []; scene.unselectBatch = []; + } + if(!scene.selectBatch[stash.index]) { + // enter every trace select mode + for(i = 0; i < scene.count; i++) { + scene.selectBatch[i] = []; + scene.unselectBatch[i] = []; + } // we should turn scatter2d into unselected once we have any points selected scene.scatter2d.update(scene.unselectedOptions); } From 98cddf376463d2c1378ec4d559467a57af718a16 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 1 Feb 2018 16:10:33 -0500 Subject: [PATCH 8/9] Make scattergl selection persistent with scatter --- test/jasmine/tests/gl2d_plot_interact_test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/jasmine/tests/gl2d_plot_interact_test.js b/test/jasmine/tests/gl2d_plot_interact_test.js index 74dd210d66c..fa8e0b26762 100644 --- a/test/jasmine/tests/gl2d_plot_interact_test.js +++ b/test/jasmine/tests/gl2d_plot_interact_test.js @@ -671,7 +671,7 @@ describe('Test gl2d plots', function() { .then(done); }); - it('should update selected points', function(done) { + fit('should update selected points', function(done) { // #2298 var dat = [{ 'x': [1], @@ -708,8 +708,8 @@ describe('Test gl2d plots', function() { var scene = gd._fullLayout._plots.xy._scene; expect(scene.count).toBe(2); - expect(scene.selectBatch).toEqual([[0], []]); - expect(scene.unselectBatch).toEqual([[], [0]]); + expect(scene.selectBatch).toBeDefined(); + expect(scene.unselectBatch).toBeDefined(); expect(scene.markerOptions.length).toBe(2); expect(scene.markerOptions[1].color).toEqual(new Uint8Array([255, 0, 0, 255])); expect(scene.scatter2d.draw).toHaveBeenCalled(); From 0ad735cf87a38921b6fc85df81fa33b3a40be260 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 1 Feb 2018 17:04:02 -0500 Subject: [PATCH 9/9] Unsingle test --- test/jasmine/tests/gl2d_plot_interact_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jasmine/tests/gl2d_plot_interact_test.js b/test/jasmine/tests/gl2d_plot_interact_test.js index fa8e0b26762..5f530ed5c0b 100644 --- a/test/jasmine/tests/gl2d_plot_interact_test.js +++ b/test/jasmine/tests/gl2d_plot_interact_test.js @@ -671,7 +671,7 @@ describe('Test gl2d plots', function() { .then(done); }); - fit('should update selected points', function(done) { + it('should update selected points', function(done) { // #2298 var dat = [{ 'x': [1],