Skip to content

Commit 50ab638

Browse files
authored
Merge pull request #2487 from plotly/perf-drawFramwork-more
More optimization for cartesian subplots
2 parents 42ec6a0 + 4059764 commit 50ab638

File tree

3 files changed

+33
-48
lines changed

3 files changed

+33
-48
lines changed

src/plot_api/plot_api.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ exports.plot = function(gd, data, layout, config) {
347347

348348
// draw ticks, titles, and calculate axis scaling (._b, ._m)
349349
function drawAxes() {
350-
return Axes.doTicks(gd, 'redraw');
350+
return Axes.doTicks(gd, graphWasEmpty ? '' : 'redraw');
351351
}
352352

353353
// Now plot the data

src/plot_api/subroutines.js

+6-20
Original file line numberDiff line numberDiff line change
@@ -124,31 +124,17 @@ exports.lsInner = function(gd) {
124124

125125
var xDomain = plotinfo.xaxis.domain;
126126
var yDomain = plotinfo.yaxis.domain;
127-
var plotgroupBgData = [];
127+
var plotgroup = plotinfo.plotgroup;
128128

129129
if(overlappingDomain(xDomain, yDomain, lowerDomains)) {
130-
plotgroupBgData = [0];
131-
}
132-
else {
130+
var pgNode = plotgroup.node();
131+
var plotgroupBg = plotinfo.bg = Lib.ensureSingle(plotgroup, 'rect', 'bg');
132+
pgNode.insertBefore(plotgroupBg.node(), pgNode.childNodes[0]);
133+
} else {
134+
plotgroup.select('rect.bg').remove();
133135
lowerBackgroundIDs.push(subplot);
134136
lowerDomains.push([xDomain, yDomain]);
135137
}
136-
137-
// create the plot group backgrounds now, since
138-
// they're all independent selections
139-
var plotgroupBg = plotinfo.plotgroup.selectAll('.bg')
140-
.data(plotgroupBgData);
141-
142-
plotgroupBg.enter().append('rect')
143-
.classed('bg', true);
144-
145-
plotgroupBg.exit().remove();
146-
147-
plotgroupBg.each(function() {
148-
plotinfo.bg = plotgroupBg;
149-
var pgNode = plotinfo.plotgroup.node();
150-
pgNode.insertBefore(this, pgNode.childNodes[0]);
151-
});
152138
});
153139

154140
// now create all the lower-layer backgrounds at once now that

src/plots/cartesian/axes.js

+26-27
Original file line numberDiff line numberDiff line change
@@ -1539,10 +1539,8 @@ axes.doTicks = function(gd, axid, skipTitle) {
15391539
return function() {
15401540
if(!ax._id) return;
15411541
var axDone = axes.doTicks(gd, ax._id);
1542-
if(axid === 'redraw') {
1543-
ax._r = ax.range.slice();
1544-
ax._rl = Lib.simpleMap(ax._r, ax.r2l);
1545-
}
1542+
ax._r = ax.range.slice();
1543+
ax._rl = Lib.simpleMap(ax._r, ax.r2l);
15461544
return axDone;
15471545
};
15481546
}));
@@ -1552,21 +1550,22 @@ axes.doTicks = function(gd, axid, skipTitle) {
15521550
// set scaling to pixels
15531551
ax.setScale();
15541552

1555-
var axLetter = axid.charAt(0),
1556-
counterLetter = axes.counterLetter(axid),
1557-
vals = axes.calcTicks(ax),
1558-
datafn = function(d) { return [d.text, d.x, ax.mirror, d.font, d.fontSize, d.fontColor].join('_'); },
1559-
tcls = axid + 'tick',
1560-
gcls = axid + 'grid',
1561-
zcls = axid + 'zl',
1562-
pad = (ax.linewidth || 1) / 2,
1563-
labelStandoff = (ax.ticks === 'outside' ? ax.ticklen : 0),
1564-
labelShift = 0,
1565-
gridWidth = Drawing.crispRound(gd, ax.gridwidth, 1),
1566-
zeroLineWidth = Drawing.crispRound(gd, ax.zerolinewidth, gridWidth),
1567-
tickWidth = Drawing.crispRound(gd, ax.tickwidth, 1),
1568-
sides, transfn, tickpathfn, subplots,
1569-
i;
1553+
var axLetter = axid.charAt(0);
1554+
var counterLetter = axes.counterLetter(axid);
1555+
var vals = axes.calcTicks(ax);
1556+
var datafn = function(d) { return [d.text, d.x, ax.mirror, d.font, d.fontSize, d.fontColor].join('_'); };
1557+
var tcls = axid + 'tick';
1558+
var gcls = axid + 'grid';
1559+
var zcls = axid + 'zl';
1560+
var pad = (ax.linewidth || 1) / 2;
1561+
var labelStandoff = (ax.ticks === 'outside' ? ax.ticklen : 0);
1562+
var labelShift = 0;
1563+
var gridWidth = Drawing.crispRound(gd, ax.gridwidth, 1);
1564+
var zeroLineWidth = Drawing.crispRound(gd, ax.zerolinewidth, gridWidth);
1565+
var tickWidth = Drawing.crispRound(gd, ax.tickwidth, 1);
1566+
var sides, transfn, tickpathfn, subplots;
1567+
var tickLabels;
1568+
var i;
15701569

15711570
if(ax._counterangle && ax.ticks === 'outside') {
15721571
var caRad = ax._counterangle * Math.PI / 180;
@@ -1616,10 +1615,11 @@ axes.doTicks = function(gd, axid, skipTitle) {
16161615
Lib.warn('Unrecognized doTicks axis:', axid);
16171616
return;
16181617
}
1619-
var axside = ax.side || sides[0],
1618+
1619+
var axside = ax.side || sides[0];
16201620
// which direction do the side[0], side[1], and free ticks go?
16211621
// then we flip if outside XOR y axis
1622-
ticksign = [-1, 1, axside === sides[1] ? 1 : -1];
1622+
var ticksign = [-1, 1, axside === sides[1] ? 1 : -1];
16231623
if((ax.ticks !== 'inside') === (axLetter === 'x')) {
16241624
ticksign = ticksign.map(function(v) { return -v; });
16251625
}
@@ -1647,6 +1647,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
16471647
function drawTicks(container, tickpath) {
16481648
var ticks = container.selectAll('path.' + tcls)
16491649
.data(ax.ticks === 'inside' ? valsClipped : vals, datafn);
1650+
16501651
if(tickpath && ax.ticks) {
16511652
ticks.enter().append('path').classed(tcls, 1).classed('ticks', 1)
16521653
.classed('crisp', 1)
@@ -1662,7 +1663,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
16621663
function drawLabels(container, position) {
16631664
// tick labels - for now just the main labels.
16641665
// TODO: mirror labels, esp for subplots
1665-
var tickLabels = container.selectAll('g.' + tcls).data(vals, datafn);
1666+
tickLabels = container.selectAll('g.' + tcls).data(vals, datafn);
16661667

16671668
if(!isNumeric(position)) {
16681669
tickLabels.remove();
@@ -2013,14 +2014,12 @@ axes.doTicks = function(gd, axid, skipTitle) {
20132014
// now this only applies to regular cartesian axes; colorbars and
20142015
// others ALWAYS call doTicks with skipTitle=true so they can
20152016
// configure their own titles.
2016-
var ax = axisIds.getFromId(gd, axid);
20172017

20182018
// rangeslider takes over a bottom title so drop it here
20192019
if(ax.rangeslider && ax.rangeslider.visible && ax._boundingBox && ax.side === 'bottom') return;
20202020

2021-
var avoidSelection = d3.select(gd).selectAll('g.' + axid + 'tick');
20222021
var avoid = {
2023-
selection: avoidSelection,
2022+
selection: tickLabels,
20242023
side: ax.side
20252024
};
20262025
var axLetter = axid.charAt(0);
@@ -2030,8 +2029,8 @@ axes.doTicks = function(gd, axid, skipTitle) {
20302029

20312030
var transform, counterAxis, x, y;
20322031

2033-
if(avoidSelection.size()) {
2034-
var translation = Drawing.getTranslate(avoidSelection.node().parentNode);
2032+
if(tickLabels.size()) {
2033+
var translation = Drawing.getTranslate(tickLabels.node().parentNode);
20352034
avoid.offsetLeft = translation.x;
20362035
avoid.offsetTop = translation.y;
20372036
}

0 commit comments

Comments
 (0)