Skip to content

Commit 4bcde5f

Browse files
authored
Merge pull request #2416 from plotly/hide-axes
Clean up removed axes and axis lines
2 parents 315272b + d6151fa commit 4bcde5f

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

src/plot_api/subroutines.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ exports.lsInner = function(gd) {
272272
* -----
273273
* x2
274274
*/
275+
var xPath = 'M0,0';
275276
if(shouldShowLinesOrTicks(xa, subplot)) {
276277
leftYLineWidth = findCounterAxisLineWidth(xa, 'left', ya, axList);
277278
xLinesXLeft = xa._offset - (leftYLineWidth ? (pad + leftYLineWidth) : 0);
@@ -288,17 +289,17 @@ exports.lsInner = function(gd) {
288289
xa._linepositions[subplot] = [xLinesYBottom, xLinesYTop];
289290
}
290291

291-
var xPath = mainPath(xa, xLinePath, xLinePathFree);
292+
xPath = mainPath(xa, xLinePath, xLinePathFree);
292293
if(extraSubplot && xa.showline && (xa.mirror === 'all' || xa.mirror === 'allticks')) {
293294
xPath += xLinePath(xLinesYBottom) + xLinePath(xLinesYTop);
294295
}
295296

296297
plotinfo.xlines
297-
.attr('d', xPath || 'M0,0')
298298
.style('stroke-width', xa._lw + 'px')
299299
.call(Color.stroke, xa.showline ?
300300
xa.linecolor : 'rgba(0,0,0,0)');
301301
}
302+
plotinfo.xlines.attr('d', xPath);
302303

303304
/*
304305
* y lines that meet x axes get longer only by margin.pad, because
@@ -311,6 +312,7 @@ exports.lsInner = function(gd) {
311312
* |
312313
* +-----
313314
*/
315+
var yPath = 'M0,0';
314316
if(shouldShowLinesOrTicks(ya, subplot)) {
315317
connectYBottom = findCounterAxisLineWidth(ya, 'bottom', xa, axList);
316318
yLinesYBottom = ya._offset + ya._length + (connectYBottom ? pad : 0);
@@ -324,17 +326,17 @@ exports.lsInner = function(gd) {
324326
ya._linepositions[subplot] = [yLinesXLeft, yLinesXRight];
325327
}
326328

327-
var yPath = mainPath(ya, yLinePath, yLinePathFree);
329+
yPath = mainPath(ya, yLinePath, yLinePathFree);
328330
if(extraSubplot && ya.showline && (ya.mirror === 'all' || ya.mirror === 'allticks')) {
329331
yPath += yLinePath(yLinesXLeft) + yLinePath(yLinesXRight);
330332
}
331333

332334
plotinfo.ylines
333-
.attr('d', yPath || 'M0,0')
334335
.style('stroke-width', ya._lw + 'px')
335336
.call(Color.stroke, ya.showline ?
336337
ya.linecolor : 'rgba(0,0,0,0)');
337338
}
339+
plotinfo.ylines.attr('d', yPath);
338340
});
339341

340342
Plotly.Axes.makeClipPaths(gd);

src/plots/cartesian/index.js

+17-3
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,17 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout)
306306
purgeSubplotLayers(oldFullLayout._cartesianlayer.selectAll('.subplot'), oldFullLayout);
307307
oldFullLayout._defs.selectAll('.axesclip').remove();
308308
}
309+
// otherwise look for subplots we need to remove
310+
else if(oldSubplotList.cartesian) {
311+
for(i = 0; i < oldSubplotList.cartesian.length; i++) {
312+
var oldSubplotId = oldSubplotList.cartesian[i];
313+
if(newSubplotList.cartesian.indexOf(oldSubplotId) === -1) {
314+
var selector = '.' + oldSubplotId + ',.' + oldSubplotId + '-x,.' + oldSubplotId + '-y';
315+
oldFullLayout._cartesianlayer.selectAll(selector).remove();
316+
removeSubplotExtras(oldSubplotId, oldFullLayout);
317+
}
318+
}
319+
}
309320
};
310321

311322
exports.drawFramework = function(gd) {
@@ -484,11 +495,9 @@ function purgeSubplotLayers(layers, fullLayout) {
484495

485496
layers.each(function(subplotId) {
486497
var plotgroup = d3.select(this);
487-
var clipId = 'clip' + fullLayout._uid + subplotId + 'plot';
488498

489499
plotgroup.remove();
490-
fullLayout._draggers.selectAll('g.' + subplotId).remove();
491-
fullLayout._defs.select('#' + clipId).remove();
500+
removeSubplotExtras(subplotId, fullLayout);
492501

493502
overlayIdsToRemove[subplotId] = true;
494503

@@ -515,6 +524,11 @@ function purgeSubplotLayers(layers, fullLayout) {
515524
}
516525
}
517526

527+
function removeSubplotExtras(subplotId, fullLayout) {
528+
fullLayout._draggers.selectAll('g.' + subplotId).remove();
529+
fullLayout._defs.select('#clip' + fullLayout._uid + subplotId + 'plot').remove();
530+
}
531+
518532
function joinLayer(parent, nodeType, className, dataVal) {
519533
var layer = parent.selectAll('.' + className)
520534
.data([dataVal || 0]);

test/jasmine/tests/cartesian_test.js

+54
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,37 @@ describe('relayout', function() {
268268

269269
});
270270

271+
describe('axis line visibility', function() {
272+
var gd;
273+
274+
beforeEach(function() {
275+
gd = createGraphDiv();
276+
});
277+
278+
afterEach(destroyGraphDiv);
279+
280+
it('can show and hide axis lines', function(done) {
281+
Plotly.newPlot(gd, [{y: [1, 2]}], {width: 400, height: 400})
282+
.then(function() {
283+
expect(gd.querySelector('.xlines-above').attributes.d.value).toBe('M0,0');
284+
expect(gd.querySelector('.ylines-above').attributes.d.value).toBe('M0,0');
285+
286+
return Plotly.relayout(gd, {'xaxis.showline': true, 'yaxis.showline': true});
287+
})
288+
.then(function() {
289+
expect(gd.querySelector('.xlines-above').attributes.d.value).not.toBe('M0,0');
290+
expect(gd.querySelector('.ylines-above').attributes.d.value).not.toBe('M0,0');
291+
292+
return Plotly.relayout(gd, {'xaxis.showline': false, 'yaxis.showline': false});
293+
})
294+
.then(function() {
295+
expect(gd.querySelector('.xlines-above').attributes.d.value).toBe('M0,0');
296+
expect(gd.querySelector('.ylines-above').attributes.d.value).toBe('M0,0');
297+
})
298+
.catch(failTest)
299+
.then(done);
300+
});
301+
});
271302
});
272303

273304
describe('subplot creation / deletion:', function() {
@@ -314,6 +345,29 @@ describe('subplot creation / deletion:', function() {
314345
.then(done);
315346
});
316347

348+
it('should remove unused axes when deleting traces', function(done) {
349+
Plotly.newPlot(gd,
350+
[{y: [1, 2, 3]}, {y: [10, 30, 20], yaxis: 'y2'}],
351+
{yaxis2: {side: 'right', overlaying: 'y', title: 'Hi!'}}
352+
)
353+
.then(function() {
354+
expect(gd.querySelectorAll('.xy2,.xy2-x,.xy2-y').length).not.toBe(0);
355+
expect(gd.querySelectorAll('.y2title').length).toBe(1);
356+
expect(gd._fullLayout._subplots.cartesian).toEqual(['xy', 'xy2']);
357+
expect(gd._fullLayout._subplots.yaxis).toEqual(['y', 'y2']);
358+
359+
return Plotly.deleteTraces(gd, [1]);
360+
})
361+
.then(function() {
362+
expect(gd.querySelectorAll('.xy2,.xy2-x,.xy2-y').length).toBe(0);
363+
expect(gd.querySelectorAll('.y2title').length).toBe(0);
364+
expect(gd._fullLayout._subplots.cartesian).toEqual(['xy']);
365+
expect(gd._fullLayout._subplots.yaxis).toEqual(['y']);
366+
})
367+
.catch(failTest)
368+
.then(done);
369+
});
370+
317371
it('puts plot backgrounds behind everything except if they overlap', function(done) {
318372
function checkBGLayers(behindCount, x2y2Count) {
319373
expect(gd.querySelectorAll('.bglayer rect.bg').length).toBe(behindCount);

0 commit comments

Comments
 (0)