From 880b7e95ea5e6ed2f13f4f0852358a12a1983625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Mon, 23 Sep 2019 15:45:47 -0400 Subject: [PATCH 1/2] fix #4212 - create new pointData object instead extending original ... so that we don't mutate pointData.cd and propagate 'fake' `gd.calcdata[i][j]` to subsequent _module.hoverPoints calls. --- src/traces/scattergl/hover.js | 18 +++++++--------- src/traces/splom/hover.js | 4 +--- test/jasmine/tests/gl2d_click_test.js | 30 +++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/traces/scattergl/hover.js b/src/traces/scattergl/hover.js index adb37227089..cea3c770a4a 100644 --- a/src/traces/scattergl/hover.js +++ b/src/traces/scattergl/hover.js @@ -84,9 +84,7 @@ function hoverPoints(pointData, xval, yval, hovermode) { if(id === undefined) return [pointData]; - calcHover(pointData, x, y, trace); - - return [pointData]; + return [calcHover(pointData, x, y, trace)]; } function calcHover(pointData, x, y, trace) { @@ -163,7 +161,7 @@ function calcHover(pointData, x, y, trace) { var fakeCd = {}; fakeCd[pointData.index] = di; - Lib.extendFlat(pointData, { + var pointData2 = Lib.extendFlat({}, pointData, { color: getTraceColor(trace, di), x0: xp - rad, @@ -181,14 +179,14 @@ function calcHover(pointData, x, y, trace) { hovertemplate: di.ht }); - if(di.htx) pointData.text = di.htx; - else if(di.tx) pointData.text = di.tx; - else if(trace.text) pointData.text = trace.text; + if(di.htx) pointData2.text = di.htx; + else if(di.tx) pointData2.text = di.tx; + else if(trace.text) pointData2.text = trace.text; - Lib.fillText(di, trace, pointData); - Registry.getComponentMethod('errorbars', 'hoverInfo')(di, trace, pointData); + Lib.fillText(di, trace, pointData2); + Registry.getComponentMethod('errorbars', 'hoverInfo')(di, trace, pointData2); - return pointData; + return pointData2; } module.exports = { diff --git a/src/traces/splom/hover.js b/src/traces/splom/hover.js index f5e9d913588..c5766f2fc87 100644 --- a/src/traces/splom/hover.js +++ b/src/traces/splom/hover.js @@ -51,9 +51,7 @@ function hoverPoints(pointData, xval, yval) { if(id === undefined) return [pointData]; - calcHover(pointData, x, y, trace); - - return [pointData]; + return [calcHover(pointData, x, y, trace)]; } module.exports = { diff --git a/test/jasmine/tests/gl2d_click_test.js b/test/jasmine/tests/gl2d_click_test.js index 792436c0f26..20d3fa33b75 100644 --- a/test/jasmine/tests/gl2d_click_test.js +++ b/test/jasmine/tests/gl2d_click_test.js @@ -346,6 +346,36 @@ describe('Test hover and click interactions', function() { .then(done); }); + it('@gl should not error when scattergl trace has missing points', function(done) { + var _mock = { + data: [{ + type: 'scattergl', + mode: 'markers', + x: [1, 2, 3, 4], + y: [10, 15, null, 17], + }], + layout: { + width: 500, + height: 500 + } + }; + + Plotly.plot(gd, _mock) + .then(function() { + gd.on('plotly_hover', function() { + fail('should not trigger plotly_hover event'); + }); + }) + .then(function() { + var xp = 300; + var yp = 250; + var interval = setInterval(function() { hover(xp--, yp--); }, 10); + return delay(100)().then(function() { clearInterval(interval); }); + }) + .catch(failTest) + .then(done); + }); + it('@gl should show last point data for overlapped scattergl points with hovermode set to closest', function(done) { var _mock = Lib.extendDeep({}, mock1); _mock.data[0].hovertext = 'text'; From 5d9bd0ada0e3d195b2b966a63fe25a425646b26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Mon, 23 Sep 2019 15:47:18 -0400 Subject: [PATCH 2/2] :hocho: obsolete if-else clause - post #3578 all scattergl traces either set a `tree` or and `ids` array during the calc step. --- src/traces/scattergl/hover.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/traces/scattergl/hover.js b/src/traces/scattergl/hover.js index cea3c770a4a..c6735dfacdd 100644 --- a/src/traces/scattergl/hover.js +++ b/src/traces/scattergl/hover.js @@ -43,9 +43,9 @@ function hoverPoints(pointData, xval, yval, hovermode) { Math.max(xl, xr), Math.max(yl, yr) ); } - } else if(stash.ids) { + } else { ids = stash.ids; - } else return [pointData]; + } // pick the id closest to the point // note that point possibly may not be found