Skip to content

Commit da63ed4

Browse files
committed
make heatmap/contour(carpet)/carpet plot method remove its own trace
... instead of relying on slow selectAll() during subroutines.drawData and Plots.cleanPlot. This can be a major perf improvement on graph with many DOM nodes (e.g. from many traces and/or many subplots)
1 parent 284c206 commit da63ed4

File tree

6 files changed

+58
-82
lines changed

6 files changed

+58
-82
lines changed

src/plot_api/subroutines.js

+3-24
Original file line numberDiff line numberDiff line change
@@ -488,34 +488,13 @@ exports.doCamera = function(gd) {
488488
exports.drawData = function(gd) {
489489
var fullLayout = gd._fullLayout;
490490
var calcdata = gd.calcdata;
491-
var rangesliderContainers = fullLayout._infolayer.selectAll('g.rangeslider-container');
492491
var i;
493492

494-
// in case of traces that were heatmaps or contour maps
495-
// previously, remove them and their colorbars explicitly
493+
// remove old colorbars explicitly
496494
for(i = 0; i < calcdata.length; i++) {
497495
var trace = calcdata[i][0].trace;
498-
var isVisible = (trace.visible === true);
499-
var uid = trace.uid;
500-
501-
if(!isVisible || !Registry.traceIs(trace, '2dMap')) {
502-
var query = (
503-
'.hm' + uid +
504-
',.contour' + uid +
505-
',#clip' + uid
506-
);
507-
508-
fullLayout._paper
509-
.selectAll(query)
510-
.remove();
511-
512-
rangesliderContainers
513-
.selectAll(query)
514-
.remove();
515-
}
516-
517-
if(!isVisible || !trace._module.colorbar) {
518-
fullLayout._infolayer.selectAll('.cb' + uid).remove();
496+
if(trace.visible !== true || !trace._module.colorbar) {
497+
fullLayout._infolayer.select('.cb' + trace.uid).remove();
519498
}
520499
}
521500

src/plots/plots.js

+4-21
Original file line numberDiff line numberDiff line change
@@ -672,8 +672,6 @@ plots.cleanPlot = function(newFullData, newFullLayout, oldFullData, oldFullLayou
672672
}
673673
}
674674

675-
var hasPaper = !!oldFullLayout._paper;
676-
var hasInfoLayer = !!oldFullLayout._infolayer;
677675
var hadGl = oldFullLayout._has && oldFullLayout._has('gl');
678676
var hasGl = newFullLayout._has && newFullLayout._has('gl');
679677

@@ -684,6 +682,8 @@ plots.cleanPlot = function(newFullData, newFullLayout, oldFullData, oldFullLayou
684682
}
685683
}
686684

685+
var hasInfoLayer = !!oldFullLayout._infolayer;
686+
687687
oldLoop:
688688
for(i = 0; i < oldFullData.length; i++) {
689689
var oldTrace = oldFullData[i],
@@ -695,26 +695,9 @@ plots.cleanPlot = function(newFullData, newFullLayout, oldFullData, oldFullLayou
695695
if(oldUid === newTrace.uid) continue oldLoop;
696696
}
697697

698-
var query = (
699-
'.hm' + oldUid +
700-
',.contour' + oldUid +
701-
',.carpet' + oldUid +
702-
',#clip' + oldUid +
703-
',.trace' + oldUid
704-
);
705-
706-
// clean old heatmap, contour traces and clip paths
707-
// that rely on uid identifiers
708-
if(hasPaper) {
709-
oldFullLayout._paper.selectAll(query).remove();
710-
}
711-
712-
// clean old colorbars and range slider plot
698+
// clean old colorbars
713699
if(hasInfoLayer) {
714-
oldFullLayout._infolayer.selectAll('.cb' + oldUid).remove();
715-
716-
oldFullLayout._infolayer.selectAll('g.rangeslider-container')
717-
.selectAll(query).remove();
700+
oldFullLayout._infolayer.select('.cb' + oldUid).remove();
718701
}
719702
}
720703

src/traces/carpet/plot.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,20 @@ var svgTextUtils = require('../../lib/svg_text_utils');
1818
var Lib = require('../../lib');
1919
var alignmentConstants = require('../../constants/alignment');
2020

21-
module.exports = function plot(gd, plotinfo, cdcarpet) {
22-
if(!cdcarpet.length) {
23-
plotinfo.plot.select('.carpetlayer')
24-
.selectAll('g.trace')
25-
.remove();
26-
}
21+
module.exports = function plot(gd, plotinfo, cdcarpet, carpetLayer) {
22+
var i;
23+
24+
carpetLayer.selectAll('g.trace').each(function() {
25+
var classString = d3.select(this).attr('class');
26+
var oldUid = classString.split('carpet')[1].split(/\s/)[0];
27+
for(i = 0; i < cdcarpet.length; i++) {
28+
if(oldUid === cdcarpet[i][0].trace.uid) return;
29+
}
30+
d3.select(this).remove();
31+
});
2732

28-
for(var i = 0; i < cdcarpet.length; i++) {
29-
plotOne(gd, plotinfo, cdcarpet[i]);
33+
for(i = 0; i < cdcarpet.length; i++) {
34+
plotOne(gd, plotinfo, cdcarpet[i], carpetLayer);
3035
}
3136
};
3237

src/traces/contour/plot.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,18 @@ var constants = require('./constants');
2727
var costConstants = constants.LABELOPTIMIZER;
2828

2929

30-
exports.plot = function plot(gd, plotinfo, cdcontours) {
31-
for(var i = 0; i < cdcontours.length; i++) {
32-
plotOne(gd, plotinfo, cdcontours[i]);
30+
exports.plot = function plot(gd, plotinfo, cdcontours, contourLayer) {
31+
var i;
32+
33+
contourLayer.selectAll('g.contour').each(function(d) {
34+
for(i = 0; i < cdcontours.length; i++) {
35+
if(d.trace.uid === cdcontours[i][0].trace.uid) return;
36+
}
37+
d3.select(this).remove();
38+
});
39+
40+
for(i = 0; i < cdcontours.length; i++) {
41+
plotOne(gd, plotinfo, cdcontours[i], contourLayer);
3342
}
3443
};
3544

src/traces/contourcarpet/plot.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,18 @@ var lookupCarpet = require('../carpet/lookup_carpetid');
2626
var closeBoundaries = require('../contour/close_boundaries');
2727

2828

29-
module.exports = function plot(gd, plotinfo, cdcontours) {
30-
for(var i = 0; i < cdcontours.length; i++) {
31-
plotOne(gd, plotinfo, cdcontours[i]);
29+
module.exports = function plot(gd, plotinfo, cdcontours, contourcarpetLayer) {
30+
var i;
31+
32+
contourcarpetLayer.selectAll('g.contour').each(function(d) {
33+
for(i = 0; i < cdcontours.length; i++) {
34+
if(d.trace.uid === cdcontours[i][0].trace.uid) return;
35+
}
36+
d3.select(this).remove();
37+
});
38+
39+
for(i = 0; i < cdcontours.length; i++) {
40+
plotOne(gd, plotinfo, cdcontours[i], contourcarpetLayer);
3241
}
3342
};
3443

@@ -46,7 +55,6 @@ function plotOne(gd, plotinfo, cd, contourcarpetLayer) {
4655
var uid = trace.uid;
4756
var xa = plotinfo.xaxis;
4857
var ya = plotinfo.yaxis;
49-
var fullLayout = gd._fullLayout;
5058
var id = 'contour' + uid;
5159
var pathinfo = emptyPathinfo(contours, plotinfo, cd[0]);
5260
var isConstraint = contours.type === 'constraint';
@@ -59,11 +67,6 @@ function plotOne(gd, plotinfo, cd, contourcarpetLayer) {
5967
return [xa.c2p(pt[0]), ya.c2p(pt[1])];
6068
}
6169

62-
if(trace.visible !== true) {
63-
fullLayout._infolayer.selectAll('.cb' + uid).remove();
64-
return;
65-
}
66-
6770
// Define the perimeter in a/b coordinates:
6871
var perimeter = [
6972
[a[0], b[b.length - 1]],

src/traces/heatmap/plot.js

+14-17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
'use strict';
1111

12+
var d3 = require('d3');
1213
var tinycolor = require('tinycolor2');
1314

1415
var Registry = require('../../registry');
@@ -18,32 +19,28 @@ var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
1819

1920
var maxRowLength = require('./max_row_length');
2021

22+
module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
23+
var i;
2124

22-
module.exports = function(gd, plotinfo, cdheatmaps) {
23-
for(var i = 0; i < cdheatmaps.length; i++) {
24-
plotOne(gd, plotinfo, cdheatmaps[i]);
25+
heatmapLayer.selectAll('.hm > image').each(function(d) {
26+
var oldTrace = d.trace || {};
27+
for(i = 0; i < cdheatmaps.length; i++) {
28+
if(oldTrace.uid === cdheatmaps[i][0].trace.uid) return;
29+
}
30+
d3.select(this.parentNode).remove();
31+
});
32+
33+
for(i = 0; i < cdheatmaps.length; i++) {
34+
plotOne(gd, plotinfo, cdheatmaps[i], heatmapLayer);
2535
}
2636
};
2737

2838
function plotOne(gd, plotinfo, cd, heatmapLayer) {
2939
var cd0 = cd[0];
3040
var trace = cd0.trace;
31-
var uid = trace.uid;
3241
var xa = plotinfo.xaxis;
3342
var ya = plotinfo.yaxis;
34-
var fullLayout = gd._fullLayout;
35-
var id = 'hm' + uid;
36-
37-
// in case this used to be a contour map
38-
fullLayout._paper.selectAll('.contour' + uid).remove();
39-
fullLayout._infolayer.selectAll('g.rangeslider-container')
40-
.selectAll('.contour' + uid).remove();
41-
42-
if(trace.visible !== true) {
43-
fullLayout._paper.selectAll('.' + id).remove();
44-
fullLayout._infolayer.selectAll('.cb' + uid).remove();
45-
return;
46-
}
43+
var id = 'hm' + trace.uid;
4744

4845
var z = cd0.z;
4946
var x = cd0.x;

0 commit comments

Comments
 (0)