diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js index b3032744510..6739142c4e4 100644 --- a/src/components/fx/hover.js +++ b/src/components/fx/hover.js @@ -15,6 +15,7 @@ var Drawing = require('../drawing'); var Color = require('../color'); var dragElement = require('../dragelement'); var Axes = require('../../plots/cartesian/axes'); +var zindexSeparator = require('../../plots/cartesian/constants').zindexSeparator; var Registry = require('../../registry'); var helpers = require('./helpers'); @@ -261,6 +262,11 @@ exports.loneHover = function loneHover(hoverItems, opts) { function _hover(gd, evt, subplot, noHoverEvent, eventTarget) { if(!subplot) subplot = 'xy'; + if(typeof subplot === 'string') { + // drop zindex from subplot id + subplot = subplot.split(zindexSeparator)[0]; + } + // if the user passed in an array of subplots, // use those instead of finding overlayed plots var subplots = Array.isArray(subplot) ? subplot : [subplot]; diff --git a/src/plot_api/subroutines.js b/src/plot_api/subroutines.js index 487decf74f9..c25cb511053 100644 --- a/src/plot_api/subroutines.js +++ b/src/plot_api/subroutines.js @@ -24,6 +24,8 @@ var SVG_TEXT_ANCHOR_START = 'start'; var SVG_TEXT_ANCHOR_MIDDLE = 'middle'; var SVG_TEXT_ANCHOR_END = 'end'; +var zindexSeparator = require('../plots/cartesian/constants').zindexSeparator; + exports.layoutStyles = function(gd) { return Lib.syncOrAsync([Plots.doAutoMargin, lsInner], gd); }; @@ -135,7 +137,7 @@ function lsInner(gd) { var yDomain = plotinfo.yaxis.domain; var plotgroup = plotinfo.plotgroup; - if(overlappingDomain(xDomain, yDomain, lowerDomains)) { + if(overlappingDomain(xDomain, yDomain, lowerDomains) && subplot.indexOf(zindexSeparator) === -1) { var pgNode = plotgroup.node(); var plotgroupBg = plotinfo.bg = Lib.ensureSingle(plotgroup, 'rect', 'bg'); pgNode.insertBefore(plotgroupBg.node(), pgNode.childNodes[0]); diff --git a/src/plots/cartesian/constants.js b/src/plots/cartesian/constants.js index f741ecd5599..22d3070b03c 100644 --- a/src/plots/cartesian/constants.js +++ b/src/plots/cartesian/constants.js @@ -66,5 +66,7 @@ module.exports = { layerValue2layerClass: { 'above traces': 'above', 'below traces': 'below' - } + }, + + zindexSeparator: 'z', // used for zindex of cartesian subplots e.g. xy, xyz2, xyz3, etc. }; diff --git a/src/plots/cartesian/index.js b/src/plots/cartesian/index.js index 2a52d2628e0..3540c58d901 100644 --- a/src/plots/cartesian/index.js +++ b/src/plots/cartesian/index.js @@ -20,6 +20,8 @@ function ensureSingleAndAddDatum(parent, nodeType, className) { }); } +var zindexSeparator = constants.zindexSeparator; + exports.name = 'cartesian'; exports.attr = ['xaxis', 'yaxis']; @@ -141,77 +143,84 @@ exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) { for(i = 0; i < calcdata.length; i++) traces.push(i); } - // For each subplot - for(i = 0; i < subplots.length; i++) { - var subplot = subplots[i]; - var subplotInfo = fullLayout._plots[subplot]; - - // Get all calcdata (traces) for this subplot: - var cdSubplot = []; - var pcd; - - // For each trace - for(var j = 0; j < calcdata.length; j++) { - var cd = calcdata[j]; - var trace = cd[0].trace; - - // Skip trace if whitelist provided and it's not whitelisted: - // if (Array.isArray(traces) && traces.indexOf(i) === -1) continue; - if(trace.xaxis + trace.yaxis === subplot) { - // XXX: Should trace carpet dependencies. Only replot all carpet plots if the carpet - // axis has actually changed: - // - // If this trace is specifically requested, add it to the list: - if(traces.indexOf(trace.index) !== -1 || trace.carpet) { - // Okay, so example: traces 0, 1, and 2 have fill = tonext. You animate - // traces 0 and 2. Trace 1 also needs to be updated, otherwise its fill - // is outdated. So this retroactively adds the previous trace if the - // traces are interdependent. - if( - pcd && - pcd[0].trace.xaxis + pcd[0].trace.yaxis === subplot && - ['tonextx', 'tonexty', 'tonext'].indexOf(trace.fill) !== -1 && - cdSubplot.indexOf(pcd) === -1 - ) { - cdSubplot.push(pcd); + var zindices = fullLayout._zindices; + // Plot each zorder group in ascending order + for(var z = 0; z < zindices.length; z++) { + var zorder = zindices[z]; + + // For each subplot + for(i = 0; i < subplots.length; i++) { + var subplot = subplots[i]; + var subplotInfo = fullLayout._plots[subplot]; + + if(z > 0) { + var idWithZ = subplotInfo.id; + if(idWithZ.indexOf(zindexSeparator) !== -1) continue; + idWithZ += zindexSeparator + (z + 1); + subplotInfo = Lib.extendFlat({}, subplotInfo, { + id: idWithZ, + plot: fullLayout._cartesianlayer.selectAll('.subplot').select('.' + idWithZ) + }); + } + + // Get all calcdata (traces) for this subplot: + var cdSubplot = []; + var pcd; + + // For each trace + for(var j = 0; j < calcdata.length; j++) { + var cd = calcdata[j]; + var trace = cd[0].trace; + + if(zorder !== (trace.zorder || 0)) continue; + + // Skip trace if whitelist provided and it's not whitelisted: + // if (Array.isArray(traces) && traces.indexOf(i) === -1) continue; + if(trace.xaxis + trace.yaxis === subplot) { + // XXX: Should trace carpet dependencies. Only replot all carpet plots if the carpet + // axis has actually changed: + // + // If this trace is specifically requested, add it to the list: + if(traces.indexOf(trace.index) !== -1 || trace.carpet) { + // Okay, so example: traces 0, 1, and 2 have fill = tonext. You animate + // traces 0 and 2. Trace 1 also needs to be updated, otherwise its fill + // is outdated. So this retroactively adds the previous trace if the + // traces are interdependent. + if( + pcd && + pcd[0].trace.xaxis + pcd[0].trace.yaxis === subplot && + ['tonextx', 'tonexty', 'tonext'].indexOf(trace.fill) !== -1 && + cdSubplot.indexOf(pcd) === -1 + ) { + cdSubplot.push(pcd); + } + + cdSubplot.push(cd); } - cdSubplot.push(cd); + // Track the previous trace on this subplot for the retroactive-add step + // above: + pcd = cd; } - - // Track the previous trace on this subplot for the retroactive-add step - // above: - pcd = cd; } + // Plot the traces for this subplot + plotOne(gd, subplotInfo, cdSubplot, transitionOpts, makeOnCompleteCallback); } - // Plot the traces for this subplot - plotOne(gd, subplotInfo, cdSubplot, transitionOpts, makeOnCompleteCallback); } }; function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback) { var traceLayerClasses = constants.traceLayerClasses; var fullLayout = gd._fullLayout; + var zindices = fullLayout._zindices; + var modules = fullLayout._modules; var _module, cdModuleAndOthers, cdModule; - // Separate traces by zorder and plot each zorder group separately - // TODO: Performance - var traceZorderGroups = {}; - for(var t = 0; t < cdSubplot.length; t++) { - var trace = cdSubplot[t][0].trace; - var zi = trace.zorder || 0; - if(!traceZorderGroups[zi]) traceZorderGroups[zi] = []; - traceZorderGroups[zi].push(cdSubplot[t]); - } - var layerData = []; var zoomScaleQueryParts = []; // Plot each zorder group in ascending order - var zindices = Object.keys(traceZorderGroups) - .map(Number) - .sort(Lib.sorterAsc); for(var z = 0; z < zindices.length; z++) { var zorder = zindices[z]; // For each "module" (trace type) @@ -363,6 +372,10 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) for(i = 0; i < oldSubplotList.cartesian.length; i++) { var oldSubplotId = oldSubplotList.cartesian[i]; + + // skip zindex layes in this process + if(oldSubplotId.indexOf(zindexSeparator) !== -1) continue; + if(!newPlots[oldSubplotId]) { var selector = '.' + oldSubplotId + ',.' + oldSubplotId + '-x,.' + oldSubplotId + '-y'; oldFullLayout._cartesianlayer.selectAll(selector).remove(); @@ -374,11 +387,50 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) exports.drawFramework = function(gd) { var fullLayout = gd._fullLayout; - var subplotData = makeSubplotData(gd); + var calcdata = gd.calcdata; + var i; + + // Separate traces by zorder and plot each zorder group separately + var traceZorderGroups = {}; + for(i = 0; i < calcdata.length; i++) { + var cdi = calcdata[i][0]; + var trace = cdi.trace; + + var zi = trace.zorder || 0; + if(!traceZorderGroups[zi]) traceZorderGroups[zi] = []; + traceZorderGroups[zi].push(cdi); + } + + // Group by zorder group in ascending order + var zindices = Object.keys(traceZorderGroups) + .map(Number) + .sort(Lib.sorterAsc); + + if(!zindices.length) zindices = [0]; + + fullLayout._zindices = zindices; + + var initialSubplotData = makeSubplotData(gd); + + var len = initialSubplotData.length; + var subplotData = []; + for(i = 0; i < len; i++) { + subplotData[i] = initialSubplotData[i].slice(); + } + + for(var z = 1; z < zindices.length; z++) { + var newSubplotData = []; + for(i = 0; i < len; i++) { + newSubplotData[i] = initialSubplotData[i].slice(); + newSubplotData[i][0] += zindexSeparator + (z + 1); + } + subplotData = subplotData.concat(newSubplotData); + } var subplotLayers = fullLayout._cartesianlayer.selectAll('.subplot') .data(subplotData, String); + subplotLayers.enter().append('g') .attr('class', function(d) { return 'subplot ' + d[0]; }); @@ -389,15 +441,34 @@ exports.drawFramework = function(gd) { subplotLayers.each(function(d) { var id = d[0]; + var posZ = id.indexOf(zindexSeparator); + var hasZ = posZ !== -1; + var idWithoutZ = hasZ ? + id.slice(0, posZ) : + id; + var plotinfo = fullLayout._plots[id]; + if(!plotinfo) { + plotinfo = Lib.extendFlat({}, fullLayout._plots[idWithoutZ]); + + if(plotinfo) { + plotinfo.id = id; + fullLayout._plots[id] = plotinfo; + fullLayout._subplots.cartesian.push(id); + } + } - plotinfo.plotgroup = d3.select(this); - makeSubplotLayer(gd, plotinfo); + if(plotinfo) { + plotinfo.plotgroup = d3.select(this); + makeSubplotLayer(gd, plotinfo); - // make separate drag layers for each subplot, - // but append them to paper rather than the plot groups, - // so they end up on top of the rest - plotinfo.draglayer = ensureSingle(fullLayout._draggers, 'g', id); + if(!hasZ) { + // make separate drag layers for each subplot, + // but append them to paper rather than the plot groups, + // so they end up on top of the rest + plotinfo.draglayer = ensureSingle(fullLayout._draggers, 'g', id); + } + } }); }; @@ -409,6 +480,8 @@ exports.rangePlot = function(gd, plotinfo, cdSubplot) { function makeSubplotData(gd) { var fullLayout = gd._fullLayout; + var numZ = fullLayout._zindices.length; + var ids = fullLayout._subplots.cartesian; var len = ids.length; var i, j, id, plotinfo, xa, ya; @@ -449,7 +522,7 @@ function makeSubplotData(gd) { // put 'regular' subplot data before 'overlaying' var subplotIds = regulars.concat(overlays); - var subplotData = new Array(len); + var subplotData = []; for(i = 0; i < len; i++) { id = subplotIds[i]; @@ -457,13 +530,28 @@ function makeSubplotData(gd) { xa = plotinfo.xaxis; ya = plotinfo.yaxis; - // use info about axis layer and overlaying pattern - // to clean what need to be cleaned up in exit selection - var d = [id, xa.layer, ya.layer, xa.overlaying || '', ya.overlaying || '']; - for(j = 0; j < plotinfo.overlays.length; j++) { - d.push(plotinfo.overlays[j].id); + var d = []; + + for(var z = 1; z <= numZ; z++) { + var zStr = ''; + if(z > 1) zStr += zindexSeparator + z; + + // use info about axis layer and overlaying pattern + // to clean what need to be cleaned up in exit selection + d.push(id + zStr); + for(j = 0; j < plotinfo.overlays.length; j++) { + d.push(plotinfo.overlays[j].id + zStr); + } } - subplotData[i] = d; + + d = d.concat([ + xa.layer, + ya.layer, + xa.overlaying || '', + ya.overlaying || '' + ]); + + subplotData.push(d); } return subplotData; } @@ -471,6 +559,10 @@ function makeSubplotData(gd) { function makeSubplotLayer(gd, plotinfo) { var plotgroup = plotinfo.plotgroup; var id = plotinfo.id; + + var posZ = id.indexOf(zindexSeparator); + var hasZ = posZ !== -1; + var xLayer = constants.layerValue2layerClass[plotinfo.xaxis.layer]; var yLayer = constants.layerValue2layerClass[plotinfo.yaxis.layer]; var hasOnlyLargeSploms = gd._fullLayout._hasOnlyLargeSploms; @@ -487,42 +579,46 @@ function makeSubplotLayer(gd, plotinfo) { plotinfo.xaxislayer = ensureSingle(plotgroup, 'g', 'xaxislayer-above'); plotinfo.yaxislayer = ensureSingle(plotgroup, 'g', 'yaxislayer-above'); } else { - var backLayer = ensureSingle(plotgroup, 'g', 'layer-subplot'); - plotinfo.shapelayer = ensureSingle(backLayer, 'g', 'shapelayer'); - plotinfo.imagelayer = ensureSingle(backLayer, 'g', 'imagelayer'); - - plotinfo.minorGridlayer = ensureSingle(plotgroup, 'g', 'minor-gridlayer'); - plotinfo.gridlayer = ensureSingle(plotgroup, 'g', 'gridlayer'); - plotinfo.zerolinelayer = ensureSingle(plotgroup, 'g', 'zerolinelayer'); - - var betweenLayer = ensureSingle(plotgroup, 'g', 'layer-between'); - plotinfo.shapelayerBetween = ensureSingle(betweenLayer, 'g', 'shapelayer'); - plotinfo.imagelayerBetween = ensureSingle(betweenLayer, 'g', 'imagelayer'); - - ensureSingle(plotgroup, 'path', 'xlines-below'); - ensureSingle(plotgroup, 'path', 'ylines-below'); - plotinfo.overlinesBelow = ensureSingle(plotgroup, 'g', 'overlines-below'); - - ensureSingle(plotgroup, 'g', 'xaxislayer-below'); - ensureSingle(plotgroup, 'g', 'yaxislayer-below'); - plotinfo.overaxesBelow = ensureSingle(plotgroup, 'g', 'overaxes-below'); + if(!hasZ) { + var backLayer = ensureSingle(plotgroup, 'g', 'layer-subplot'); + plotinfo.shapelayer = ensureSingle(backLayer, 'g', 'shapelayer'); + plotinfo.imagelayer = ensureSingle(backLayer, 'g', 'imagelayer'); + + plotinfo.minorGridlayer = ensureSingle(plotgroup, 'g', 'minor-gridlayer'); + plotinfo.gridlayer = ensureSingle(plotgroup, 'g', 'gridlayer'); + plotinfo.zerolinelayer = ensureSingle(plotgroup, 'g', 'zerolinelayer'); + + var betweenLayer = ensureSingle(plotgroup, 'g', 'layer-between'); + plotinfo.shapelayerBetween = ensureSingle(betweenLayer, 'g', 'shapelayer'); + plotinfo.imagelayerBetween = ensureSingle(betweenLayer, 'g', 'imagelayer'); + + ensureSingle(plotgroup, 'path', 'xlines-below'); + ensureSingle(plotgroup, 'path', 'ylines-below'); + plotinfo.overlinesBelow = ensureSingle(plotgroup, 'g', 'overlines-below'); + + ensureSingle(plotgroup, 'g', 'xaxislayer-below'); + ensureSingle(plotgroup, 'g', 'yaxislayer-below'); + plotinfo.overaxesBelow = ensureSingle(plotgroup, 'g', 'overaxes-below'); + } - plotinfo.plot = ensureSingle(plotgroup, 'g', 'plot'); plotinfo.overplot = ensureSingle(plotgroup, 'g', 'overplot'); - - plotinfo.xlines = ensureSingle(plotgroup, 'path', 'xlines-above'); - plotinfo.ylines = ensureSingle(plotgroup, 'path', 'ylines-above'); - plotinfo.overlinesAbove = ensureSingle(plotgroup, 'g', 'overlines-above'); - - ensureSingle(plotgroup, 'g', 'xaxislayer-above'); - ensureSingle(plotgroup, 'g', 'yaxislayer-above'); - plotinfo.overaxesAbove = ensureSingle(plotgroup, 'g', 'overaxes-above'); - - // set refs to correct layers as determined by 'axis.layer' - plotinfo.xlines = plotgroup.select('.xlines-' + xLayer); - plotinfo.ylines = plotgroup.select('.ylines-' + yLayer); - plotinfo.xaxislayer = plotgroup.select('.xaxislayer-' + xLayer); - plotinfo.yaxislayer = plotgroup.select('.yaxislayer-' + yLayer); + plotinfo.plot = ensureSingle(plotinfo.overplot, 'g', id); + + if(!hasZ) { + plotinfo.xlines = ensureSingle(plotgroup, 'path', 'xlines-above'); + plotinfo.ylines = ensureSingle(plotgroup, 'path', 'ylines-above'); + plotinfo.overlinesAbove = ensureSingle(plotgroup, 'g', 'overlines-above'); + + ensureSingle(plotgroup, 'g', 'xaxislayer-above'); + ensureSingle(plotgroup, 'g', 'yaxislayer-above'); + plotinfo.overaxesAbove = ensureSingle(plotgroup, 'g', 'overaxes-above'); + + // set refs to correct layers as determined by 'axis.layer' + plotinfo.xlines = plotgroup.select('.xlines-' + xLayer); + plotinfo.ylines = plotgroup.select('.ylines-' + yLayer); + plotinfo.xaxislayer = plotgroup.select('.xaxislayer-' + xLayer); + plotinfo.yaxislayer = plotgroup.select('.yaxislayer-' + yLayer); + } } } else { var mainplotinfo = plotinfo.mainplotinfo; @@ -558,29 +654,31 @@ function makeSubplotLayer(gd, plotinfo) { plotinfo.yaxislayer = mainplotgroup.select('.overaxes-' + yLayer).select('.' + yId); } - // common attributes for all subplots, overlays or not + if(!hasZ) { + // common attributes for all subplots, overlays or not + + if(!hasOnlyLargeSploms) { + ensureSingleAndAddDatum(plotinfo.minorGridlayer, 'g', plotinfo.xaxis._id); + ensureSingleAndAddDatum(plotinfo.minorGridlayer, 'g', plotinfo.yaxis._id); + plotinfo.minorGridlayer.selectAll('g') + .map(function(d) { return d[0]; }) + .sort(axisIds.idSort); + + ensureSingleAndAddDatum(plotinfo.gridlayer, 'g', plotinfo.xaxis._id); + ensureSingleAndAddDatum(plotinfo.gridlayer, 'g', plotinfo.yaxis._id); + plotinfo.gridlayer.selectAll('g') + .map(function(d) { return d[0]; }) + .sort(axisIds.idSort); + } - if(!hasOnlyLargeSploms) { - ensureSingleAndAddDatum(plotinfo.minorGridlayer, 'g', plotinfo.xaxis._id); - ensureSingleAndAddDatum(plotinfo.minorGridlayer, 'g', plotinfo.yaxis._id); - plotinfo.minorGridlayer.selectAll('g') - .map(function(d) { return d[0]; }) - .sort(axisIds.idSort); + plotinfo.xlines + .style('fill', 'none') + .classed('crisp', true); - ensureSingleAndAddDatum(plotinfo.gridlayer, 'g', plotinfo.xaxis._id); - ensureSingleAndAddDatum(plotinfo.gridlayer, 'g', plotinfo.yaxis._id); - plotinfo.gridlayer.selectAll('g') - .map(function(d) { return d[0]; }) - .sort(axisIds.idSort); + plotinfo.ylines + .style('fill', 'none') + .classed('crisp', true); } - - plotinfo.xlines - .style('fill', 'none') - .classed('crisp', true); - - plotinfo.ylines - .style('fill', 'none') - .classed('crisp', true); } function purgeSubplotLayers(layers, fullLayout) { diff --git a/test/image/baselines/zz-zorder-overlayed-subplots.png b/test/image/baselines/zz-zorder-overlayed-subplots.png new file mode 100644 index 00000000000..bc6d9c1b15a Binary files /dev/null and b/test/image/baselines/zz-zorder-overlayed-subplots.png differ diff --git a/test/image/mocks/zz-zorder-overlayed-subplots.json b/test/image/mocks/zz-zorder-overlayed-subplots.json new file mode 100644 index 00000000000..35b4cc5fc5a --- /dev/null +++ b/test/image/mocks/zz-zorder-overlayed-subplots.json @@ -0,0 +1,100 @@ +{ + "data": [ + { + "line": { + "width": 15 + }, + "mode": "lines", + "x": [ + "A", + "B", + "C", + "D" + ], + "y": [ + 1, + 2, + 3, + 4 + ], + "zorder": 4 + }, + { + "line": { + "width": 15 + }, + "mode": "lines", + "x": [ + "A", + "B", + "C", + "D" + ], + "y": [ + 2, + 3, + 4, + 1 + ], + "yaxis": "y2", + "zorder": 3 + }, + { + "line": { + "width": 15 + }, + "mode": "lines", + "x": [ + "A", + "B", + "C", + "D" + ], + "y": [ + 3, + 4, + 1, + 2 + ], + "xaxis": "x2", + "zorder": 2 + }, + { + "line": { + "width": 15 + }, + "mode": "lines", + "x": [ + "A", + "B", + "C", + "D" + ], + "y": [ + 4, + 1, + 2, + 3 + ], + "xaxis": "x2", + "yaxis": "y2", + "zorder": 1 + } + ], + "layout": { + "showlegend": true, + "title": { + "text": "zorder overlayed subplots" + }, + "width": 600, + "height": 400, + "xaxis2": { + "overlaying": "x", + "side": "top" + }, + "yaxis2": { + "overlaying": "y", + "side": "right" + } + } +} diff --git a/test/jasmine/tests/animate_test.js b/test/jasmine/tests/animate_test.js index 1e7e01d199a..cba22278fcc 100644 --- a/test/jasmine/tests/animate_test.js +++ b/test/jasmine/tests/animate_test.js @@ -1008,7 +1008,7 @@ describe('animating scatter traces', function() { // assert what Cartesian.transitionAxes does function getSubplotTranslate() { - var sp = d3Select(gd).select('.subplot.xy > .plot'); + var sp = d3Select(gd).select('.subplot.xy > .overplot').select('.xy'); return sp.attr('transform') .split('translate(')[1].split(')')[0] .split(',') diff --git a/test/jasmine/tests/bar_test.js b/test/jasmine/tests/bar_test.js index 2d6a20d9bb6..4ddd88c65e8 100644 --- a/test/jasmine/tests/bar_test.js +++ b/test/jasmine/tests/bar_test.js @@ -2087,7 +2087,7 @@ describe('A bar plot', function() { } function _assert(layerClips, barDisplays, barTextDisplays, barClips) { - var subplotLayer = d3Select('.plot'); + var subplotLayer = d3Select('.overplot').select('.xy'); var barLayer = subplotLayer.select('.barlayer'); _assertClip(subplotLayer, layerClips[0], 1, 'subplot layer'); diff --git a/test/jasmine/tests/cartesian_interact_test.js b/test/jasmine/tests/cartesian_interact_test.js index c2b97c67071..5332f9237c9 100644 --- a/test/jasmine/tests/cartesian_interact_test.js +++ b/test/jasmine/tests/cartesian_interact_test.js @@ -1592,7 +1592,7 @@ describe('axis zoom/pan and main plot zoom', function() { [['yaxis'], [-0.318, 3.318]], [['xaxis2', 'yaxis2'], [-0.588, 8.824]] ]); - x2y2 = d3Select('.subplot.x2y2 .plot'); + x2y2 = d3Select('.subplot.x2y2 .overplot').select('.x2y2'); expect(x2y2.attr('transform')).toBe('translate(50,50)'); mx = gd._fullLayout.xaxis._m; my = gd._fullLayout.yaxis._m; diff --git a/test/jasmine/tests/cartesian_test.js b/test/jasmine/tests/cartesian_test.js index b31d331d998..a21349f9663 100644 --- a/test/jasmine/tests/cartesian_test.js +++ b/test/jasmine/tests/cartesian_test.js @@ -609,7 +609,7 @@ describe('subplot creation / deletion:', function() { var fig = Lib.extendDeep({}, require('../../image/mocks/overlaying-axis-lines.json')); function _assert(xyCnt, x2y2Cnt) { - expect(d3Select('.subplot.xy').select('.plot').selectAll('.trace').size()) + expect(d3Select('.subplot.xy').select('.overplot').select('.xy').selectAll('.trace').size()) .toBe(xyCnt, 'has correct xy subplot trace count'); expect(d3Select('.overplot').select('.x2y2').selectAll('.trace').size()) .toBe(x2y2Cnt, 'has correct x2y2 oveylaid subplot trace count'); @@ -759,7 +759,7 @@ describe('subplot creation / deletion:', function() { _assert('x2/y2 both overlays', { xtickParent: 'xaxislayer-above', x2tickParent: 'x2y2-x', - trace0Parent: 'plot', + trace0Parent: 'xy', trace1Parent: 'x2y2' }); }) @@ -770,8 +770,8 @@ describe('subplot creation / deletion:', function() { _assert('x2 free / y2 overlaid', { xtickParent: 'xaxislayer-above', x2tickParent: 'xaxislayer-above', - trace0Parent: 'plot', - trace1Parent: 'plot' + trace0Parent: 'xy', + trace1Parent: 'x2y2' }); }) .then(function() { @@ -781,7 +781,7 @@ describe('subplot creation / deletion:', function() { _assert('back to x2/y2 both overlays', { xtickParent: 'xaxislayer-above', x2tickParent: 'x2y2-x', - trace0Parent: 'plot', + trace0Parent: 'xy', trace1Parent: 'x2y2' }); }) diff --git a/test/jasmine/tests/click_test.js b/test/jasmine/tests/click_test.js index 1ce7cddb122..2312b7fee41 100644 --- a/test/jasmine/tests/click_test.js +++ b/test/jasmine/tests/click_test.js @@ -1182,14 +1182,14 @@ describe('dragbox', function() { var pos = getRectCenter(node); var fns = drag.makeFns({pos0: pos, dpos: [50, 0]}); - assertScale(d3Select('.plot').node(), 1, 1); + assertScale(d3Select('.overplot').select('.xy').node(), 1, 1); d3SelectAll('.point').each(function() { assertScale(this, 1, 1); }); fns.start().then(function() { - assertScale(d3Select('.plot').node(), 1.14, 1); + assertScale(d3Select('.overplot').select('.xy').node(), 1.14, 1); d3Select('.scatterlayer').selectAll('.point').each(function() { assertScale(this, 0.87, 1); diff --git a/test/jasmine/tests/scatter_test.js b/test/jasmine/tests/scatter_test.js index 4b191bc2fd2..f07536631ce 100644 --- a/test/jasmine/tests/scatter_test.js +++ b/test/jasmine/tests/scatter_test.js @@ -2053,7 +2053,7 @@ describe('Test scatter *clipnaxis*:', function() { } function _assert(layerClips, nodeDisplays, errorBarClips, lineClips) { - var subplotLayer = d3Select('.plot'); + var subplotLayer = d3Select('.overplot').select('.xy'); var scatterLayer = subplotLayer.select('.scatterlayer'); _assertClip(subplotLayer, layerClips[0], 1, 'subplot layer'); diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js index 4e18bde72ba..18622cbabce 100644 --- a/test/jasmine/tests/select_test.js +++ b/test/jasmine/tests/select_test.js @@ -3112,7 +3112,7 @@ describe('Test select box and lasso per trace:', function() { var assertSelectedPoints = makeAssertSelectedPoints(); function assertFillOpacity(exp, msg) { - var txtPts = d3Select(gd).select('g.plot').selectAll('text'); + var txtPts = d3Select(gd).select('g.overplot').select('.xy').selectAll('text'); expect(txtPts.size()).toBe(exp.length, '# of text nodes: ' + msg); diff --git a/test/jasmine/tests/splom_test.js b/test/jasmine/tests/splom_test.js index 1702d63e2f5..b85c14882bd 100644 --- a/test/jasmine/tests/splom_test.js +++ b/test/jasmine/tests/splom_test.js @@ -825,7 +825,7 @@ describe('Test splom interactions:', function() { .then(function() { _assert({ subplotCnt: 25, - innerSubplotNodeCnt: 19, + innerSubplotNodeCnt: 18, hasSplomGrid: false, bgCnt: 0 }); @@ -845,7 +845,7 @@ describe('Test splom interactions:', function() { // grid layer would be above xaxis layer, // if we didn't clear subplot children. expect(gridIndex).toBe(2, ' index'); - expect(xaxisIndex).toBe(16, ' index'); + expect(xaxisIndex).toBe(15, ' index'); return Plotly.restyle(gd, 'dimensions', [dimsLarge]); }) @@ -857,7 +857,7 @@ describe('Test splom interactions:', function() { // new subplots though have reduced number of children. innerSubplotNodeCnt: function(d) { var p = d.match(SUBPLOT_PATTERN); - return (p[1] > 5 || p[2] > 5) ? 4 : 19; + return (p[1] > 5 || p[2] > 5) ? 4 : 18; }, hasSplomGrid: true, bgCnt: 0 diff --git a/test/jasmine/tests/toimage_test.js b/test/jasmine/tests/toimage_test.js index da4ffd5aba6..366ae0d5884 100644 --- a/test/jasmine/tests/toimage_test.js +++ b/test/jasmine/tests/toimage_test.js @@ -240,7 +240,10 @@ describe('Plotly.toImage', function() { }) .then(function(svg) { var svgDOM = parser.parseFromString(svg, 'image/svg+xml'); - var gSubplot = svgDOM.getElementsByClassName('plot')[0]; + var gSubplot = svgDOM + .getElementsByClassName('overplot')[0] + .getElementsByClassName('xy')[0]; + var clipPath = gSubplot.getAttribute('clip-path'); var len = clipPath.length;