diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index e950d614426..2dcbe192b0c 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -2539,7 +2539,7 @@ function getTraceIndexFromUid(uid, data, tracei) { if(data[i].uid === uid) return i; } // fall back on trace order, but only if user didn't provide a uid for that trace - return data[tracei].uid ? -1 : tracei; + return (!data[tracei] || data[tracei].uid) ? -1 : tracei; } function valsMatch(v1, v2) { diff --git a/test/jasmine/tests/plot_api_react_test.js b/test/jasmine/tests/plot_api_react_test.js index e882536194c..e5f39c25699 100644 --- a/test/jasmine/tests/plot_api_react_test.js +++ b/test/jasmine/tests/plot_api_react_test.js @@ -1078,6 +1078,64 @@ describe('Plotly.react and uirevision attributes', function() { .then(done); }); + describe('should handle case where traces are removed', function() { + var y0 = [1, 2, 1]; + var y1 = [2, 1, 2]; + + function mockLegendClick() { + return Registry.call('_guiRestyle', gd, 'visible', 'legendonly'); + } + + function _assert(msg, exp) { + return function() { + expect(gd._fullData.length).toBe(exp.length, msg + ' - # traces'); + exp.forEach(function(expi, i) { + expect(gd._fullData[i].visible).toBe(expi, msg + ' trace ' + i + ' visibility'); + }); + }; + } + + it('- case no uirevision no uid', function(done) { + Plotly.newPlot(gd, [{y: y0}, {y: y1}]) + .then(_assert('base', [true, true])) + .then(mockLegendClick) + .then(_react([{y: [1, 2, 1]}])) + .then(_assert('after react', [true])) + .catch(failTest) + .then(done); + }); + + it('- case no uirevision with uid', function(done) { + Plotly.newPlot(gd, [{y: y0, uid: 'a'}, {y: y1, uid: 'b'}]) + .then(_assert('base', [true, true])) + .then(mockLegendClick) + .then(_react([{y: [1, 2, 1], uid: 'a'}])) + .then(_assert('after react', [true])) + .catch(failTest) + .then(done); + }); + + it('- case with uirevision no uid', function(done) { + Plotly.newPlot(gd, [{y: y0}, {y: y1}], {uirevision: true}) + .then(_assert('base', [true, true])) + .then(mockLegendClick) + .then(_react({data: [{y: [1, 2, 1]}], layout: {uirevision: true}})) + .then(_assert('after react', ['legendonly'])) + .catch(failTest) + .then(done); + }); + + it('- case with uirevision with uid', function(done) { + Plotly.newPlot(gd, [{y: y0, uid: 'a'}, {y: y1, uid: 'b'}], {uirevision: true}) + .then(_assert('base', [true, true])) + .then(mockLegendClick) + .then(_react({data: [{y: [1, 2, 1], uid: 'a'}], layout: {uirevision: true}})) + .then(_assert('after react', ['legendonly'])) + .catch(failTest) + .then(done); + }); + }); + it('controls axis edits with axis.uirevision', function(done) { function fig(mainRev, xRev, yRev, x2Rev, y2Rev) { return {