diff --git a/src/plots/cartesian/index.js b/src/plots/cartesian/index.js index 883acb4d0d8..8d86648e4be 100644 --- a/src/plots/cartesian/index.js +++ b/src/plots/cartesian/index.js @@ -347,10 +347,10 @@ function makeSubplotLayer(plotinfo) { plotinfo.zerolinelayer = joinLayer(mainplotinfo.overzero, 'g', id); plotinfo.plot = joinLayer(mainplotinfo.overplot, 'g', id); - plotinfo.xlines = joinLayer(mainplotinfo.overlines, 'path', id); - plotinfo.ylines = joinLayer(mainplotinfo.overlines, 'path', id); - plotinfo.xaxislayer = joinLayer(mainplotinfo.overaxes, 'g', id); - plotinfo.yaxislayer = joinLayer(mainplotinfo.overaxes, 'g', id); + plotinfo.xlines = joinLayer(mainplotinfo.overlines, 'path', id + '-x'); + plotinfo.ylines = joinLayer(mainplotinfo.overlines, 'path', id + '-y'); + plotinfo.xaxislayer = joinLayer(mainplotinfo.overaxes, 'g', id + '-x'); + plotinfo.yaxislayer = joinLayer(mainplotinfo.overaxes, 'g', id + '-y'); } // common attributes for all subplots, overlays or not @@ -368,17 +368,39 @@ function makeSubplotLayer(plotinfo) { function purgeSubplotLayers(layers, fullLayout) { if(!layers) return; - layers.each(function(subplot) { - var plotgroup = d3.select(this), - clipId = 'clip' + fullLayout._uid + subplot + 'plot'; + var overlayIdsToRemove = {}; + + layers.each(function(subplotId) { + var plotgroup = d3.select(this); + var clipId = 'clip' + fullLayout._uid + subplotId + 'plot'; plotgroup.remove(); - fullLayout._draggers.selectAll('g.' + subplot).remove(); + fullLayout._draggers.selectAll('g.' + subplotId).remove(); fullLayout._defs.select('#' + clipId).remove(); + overlayIdsToRemove[subplotId] = true; + // do not remove individual axis s here // as other subplots may need them }); + + // must remove overlaid subplot trace layers 'manually' + + var subplots = fullLayout._plots; + var subplotIds = Object.keys(subplots); + + for(var i = 0; i < subplotIds.length; i++) { + var subplotInfo = subplots[subplotIds[i]]; + var overlays = subplotInfo.overlays || []; + + for(var j = 0; j < overlays.length; j++) { + var overlayInfo = overlays[j]; + + if(overlayIdsToRemove[overlayInfo.id]) { + overlayInfo.plot.selectAll('.trace').remove(); + } + } + } } function joinLayer(parent, nodeType, className) { diff --git a/test/image/baselines/overlaying-axis-lines.png b/test/image/baselines/overlaying-axis-lines.png new file mode 100644 index 00000000000..76c4532678e Binary files /dev/null and b/test/image/baselines/overlaying-axis-lines.png differ diff --git a/test/image/mocks/overlaying-axis-lines.json b/test/image/mocks/overlaying-axis-lines.json new file mode 100644 index 00000000000..b300149e02f --- /dev/null +++ b/test/image/mocks/overlaying-axis-lines.json @@ -0,0 +1,16 @@ +{ + "data": [{ + "y": [1, 2, 3] + }, { + "x": [4, 5, 6], + "y": [3, 1, 2], + "xaxis": "x2", + "yaxis": "y2" + }], + "layout": { + "xaxis": {"showline": true}, + "yaxis": {"showline": true}, + "xaxis2": {"showline": true, "overlaying": "x", "side": "top"}, + "yaxis2": {"showline": true, "overlaying": "y", "side": "right"} + } +} diff --git a/test/jasmine/tests/cartesian_test.js b/test/jasmine/tests/cartesian_test.js index f6e930affda..f700e378ed6 100644 --- a/test/jasmine/tests/cartesian_test.js +++ b/test/jasmine/tests/cartesian_test.js @@ -8,7 +8,6 @@ var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); var failTest = require('../assets/fail_test'); - describe('restyle', function() { describe('scatter traces', function() { var gd; @@ -375,4 +374,33 @@ describe('subplot creation / deletion:', function() { .catch(failTest) .then(done); }); + + it('should clear overlaid subplot trace layers on restyle', function(done) { + var fig = Lib.extendDeep({}, require('@mocks/overlaying-axis-lines.json')); + + function _assert(xyCnt, x2y2Cnt) { + expect(d3.select('.subplot.xy').select('.plot').selectAll('.trace').size()) + .toBe(xyCnt, 'has correct xy subplot trace count'); + expect(d3.select('.overplot').select('.x2y2').selectAll('.trace').size()) + .toBe(x2y2Cnt, 'has correct x2y2 oveylaid subplot trace count'); + } + + Plotly.plot(gd, fig).then(function() { + _assert(1, 1); + return Plotly.restyle(gd, 'visible', false, [1]); + }) + .then(function() { + _assert(1, 0); + return Plotly.restyle(gd, 'visible', true); + }) + .then(function() { + _assert(1, 1); + return Plotly.restyle(gd, 'visible', false); + }) + .then(function() { + _assert(0, 0); + }) + .catch(failTest) + .then(done); + }); });