Skip to content

Commit

Permalink
Merge pull request #2474 from plotly/perf-drawFramwork
Browse files Browse the repository at this point in the history
Perf drawFramwork
  • Loading branch information
etpinard authored Mar 26, 2018
2 parents 7316d98 + 50ab638 commit 9a79056
Show file tree
Hide file tree
Showing 28 changed files with 444 additions and 560 deletions.
29 changes: 15 additions & 14 deletions src/components/colorbar/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,20 +245,21 @@ module.exports = function draw(gd, id) {
cbAxisOut.setScale();

// now draw the elements
var container = fullLayout._infolayer.selectAll('g.' + id).data([0]);
container.enter().append('g').classed(id, true)
.classed(cn.colorbar, true)
.each(function() {
var s = d3.select(this);
s.append('rect').classed(cn.cbbg, true);
s.append('g').classed(cn.cbfills, true);
s.append('g').classed(cn.cblines, true);
s.append('g').classed(cn.cbaxis, true).classed(cn.crisp, true);
s.append('g').classed(cn.cbtitleunshift, true)
.append('g').classed(cn.cbtitle, true);
s.append('rect').classed(cn.cboutline, true);
s.select('.cbtitle').datum(0);
});
var container = Lib.ensureSingle(fullLayout._infolayer, 'g', id, function(s) {
s.classed(cn.colorbar, true)
.each(function() {
var s = d3.select(this);
s.append('rect').classed(cn.cbbg, true);
s.append('g').classed(cn.cbfills, true);
s.append('g').classed(cn.cblines, true);
s.append('g').classed(cn.cbaxis, true).classed(cn.crisp, true);
s.append('g').classed(cn.cbtitleunshift, true)
.append('g').classed(cn.cbtitle, true);
s.append('rect').classed(cn.cboutline, true);
s.select('.cbtitle').datum(0);
});
});

container.attr('transform', 'translate(' + Math.round(gs.l) +
',' + Math.round(gs.t) + ')');
// TODO: this opposite transform is a hack until we make it
Expand Down
63 changes: 31 additions & 32 deletions src/components/drawing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,7 @@ drawing.gradient = function(sel, gd, gradientID, type, color1, color2) {
* The upside of this is arbitrary points can share gradient defs
*/
drawing.initGradients = function(gd) {
var gradientsGroup = gd._fullLayout._defs.selectAll('.gradients').data([0]);
gradientsGroup.enter().append('g').classed('gradients', true);

var gradientsGroup = Lib.ensureSingle(gd._fullLayout._defs, 'g', 'gradients');
gradientsGroup.selectAll('linearGradient,radialGradient').remove();
};

Expand Down Expand Up @@ -729,33 +727,28 @@ drawing.steps = function(shape) {
// off-screen svg render testing element, shared by the whole page
// uses the id 'js-plotly-tester' and stores it in drawing.tester
drawing.makeTester = function() {
var tester = d3.select('body')
.selectAll('#js-plotly-tester')
.data([0]);

tester.enter().append('svg')
.attr('id', 'js-plotly-tester')
.attr(xmlnsNamespaces.svgAttrs)
.style({
position: 'absolute',
left: '-10000px',
top: '-10000px',
width: '9000px',
height: '9000px',
'z-index': '1'
});
var tester = Lib.ensureSingleById(d3.select('body'), 'svg', 'js-plotly-tester', function(s) {
s.attr(xmlnsNamespaces.svgAttrs)
.style({
position: 'absolute',
left: '-10000px',
top: '-10000px',
width: '9000px',
height: '9000px',
'z-index': '1'
});
});

// browsers differ on how they describe the bounding rect of
// the svg if its contents spill over... so make a 1x1px
// reference point we can measure off of.
var testref = tester.selectAll('.js-reference-point').data([0]);
testref.enter().append('path')
.classed('js-reference-point', true)
.attr('d', 'M0,0H1V1H0Z')
.style({
'stroke-width': 0,
fill: 'black'
});
var testref = Lib.ensureSingle(tester, 'path', 'js-reference-point', function(s) {
s.attr('d', 'M0,0H1V1H0Z')
.style({
'stroke-width': 0,
fill: 'black'
});
});

drawing.tester = tester;
drawing.testref = testref;
Expand Down Expand Up @@ -917,15 +910,21 @@ drawing.setClipUrl = function(s, localId) {
return;
}

var url = '#' + localId,
base = d3.select('base');
if(drawing.baseUrl === undefined) {
var base = d3.select('base');

// add id to location href w/o hashes if any)
if(base.size() && base.attr('href')) {
url = window.location.href.split('#')[0] + url;
// Stash base url once and for all!
// We may have to stash this elsewhere when
// we'll try to support for child windows
// more info -> https://github.com/plotly/plotly.js/issues/702
if(base.size() && base.attr('href')) {
drawing.baseUrl = window.location.href.split('#')[0];
} else {
drawing.baseUrl = '';
}
}

s.attr('clip-path', 'url(' + url + ')');
s.attr('clip-path', 'url(' + drawing.baseUrl + '#' + localId + ')');
};

drawing.getTranslate = function(element) {
Expand Down
20 changes: 9 additions & 11 deletions src/components/fx/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -696,23 +696,21 @@ function createHoverText(hoverData, opts, gd) {
commonLabel.exit().remove();

commonLabel.each(function() {
var label = d3.select(this),
lpath = label.selectAll('path').data([0]),
ltext = label.selectAll('text').data([0]);

lpath.enter().append('path')
.style({'stroke-width': '1px'});
var label = d3.select(this);
var lpath = Lib.ensureSingle(label, 'path', '', function(s) {
s.style({'stroke-width': '1px'});
});
var ltext = Lib.ensureSingle(label, 'text', '', function(s) {
// prohibit tex interpretation until we can handle
// tex and regular text together
s.attr('data-notex', 1);
});

lpath.style({
fill: commonLabelOpts.bgcolor || Color.defaultLine,
stroke: commonLabelOpts.bordercolor || Color.background,
});

ltext.enter().append('text')
// prohibit tex interpretation until we can handle
// tex and regular text together
.attr('data-notex', 1);

ltext.text(t0)
.call(Drawing.font,
commonLabelOpts.font.family || fontFamily,
Expand Down
65 changes: 20 additions & 45 deletions src/components/legend/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,52 +53,35 @@ module.exports = function draw(gd) {
return;
}

var legend = fullLayout._infolayer.selectAll('g.legend')
.data([0]);

legend.enter().append('g')
.attr({
'class': 'legend',
'pointer-events': 'all'
});

var clipPath = fullLayout._topdefs.selectAll('#' + clipId)
.data([0]);

clipPath.enter().append('clipPath')
.attr('id', clipId)
.append('rect');
var firstRender = false;
var legend = Lib.ensureSingle(fullLayout._infolayer, 'g', 'legend', function(s) {
s.attr('pointer-events', 'all');
firstRender = true;
});

var bg = legend.selectAll('rect.bg')
.data([0]);
var clipPath = Lib.ensureSingleById(fullLayout._topdefs, 'clipPath', clipId, function(s) {
s.append('rect');
});

bg.enter().append('rect').attr({
'class': 'bg',
'shape-rendering': 'crispEdges'
var bg = Lib.ensureSingle(legend, 'rect', 'bg', function(s) {
s.attr('shape-rendering', 'crispEdges');
});

bg.call(Color.stroke, opts.bordercolor)
.call(Color.fill, opts.bgcolor)
.style('stroke-width', opts.borderwidth + 'px');

var scrollBox = legend.selectAll('g.scrollbox')
.data([0]);

scrollBox.enter().append('g')
.attr('class', 'scrollbox');
var scrollBox = Lib.ensureSingle(legend, 'g', 'scrollbox');

var scrollBar = legend.selectAll('rect.scrollbar')
.data([0]);

scrollBar.enter().append('rect')
.attr({
'class': 'scrollbar',
var scrollBar = Lib.ensureSingle(legend, 'rect', 'scrollbar', function(s) {
s.attr({
rx: 20,
ry: 3,
width: 0,
height: 0
})
.call(Color.fill, '#808BA4');
});

var groups = scrollBox.selectAll('g.groups')
.data(legendData);
Expand Down Expand Up @@ -129,7 +112,6 @@ module.exports = function draw(gd) {
.call(setupTraceToggle, gd);
});

var firstRender = legend.enter().size() !== 0;
if(firstRender) {
computeLegendDimensions(gd, groups, traces);
expandMargin(gd);
Expand Down Expand Up @@ -378,10 +360,7 @@ function drawTexts(g, gd) {
traceIndex = trace.index,
name = isPie ? legendItem.label : trace.name;

var text = g.selectAll('text.legendtext')
.data([0]);

text.enter().append('text').classed('legendtext', true);
var text = Lib.ensureSingle(g, 'text', 'legendtext');

text.attr('text-anchor', 'start')
.classed('user-select-none', true)
Expand Down Expand Up @@ -446,15 +425,11 @@ function setupTraceToggle(g, gd) {
var newMouseDownTime,
numClicks = 1;

var traceToggle = g.selectAll('rect')
.data([0]);

traceToggle.enter().append('rect')
.classed('legendtoggle', true)
.style('cursor', 'pointer')
.attr('pointer-events', 'all')
.call(Color.fill, 'rgba(0,0,0,0)');

var traceToggle = Lib.ensureSingle(g, 'rect', 'legendtoggle', function(s) {
s.style('cursor', 'pointer')
.attr('pointer-events', 'all')
.call(Color.fill, 'rgba(0,0,0,0)');
});

traceToggle.on('mousedown', function() {
newMouseDownTime = (new Date()).getTime();
Expand Down
7 changes: 1 addition & 6 deletions src/components/legend/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var d3 = require('d3');
Expand All @@ -19,15 +18,11 @@ var Color = require('../color');
var subTypes = require('../../traces/scatter/subtypes');
var stylePie = require('../../traces/pie/style_one');


module.exports = function style(s, gd) {
s.each(function(d) {
var traceGroup = d3.select(this);

var layers = traceGroup.selectAll('g.layers')
.data([0]);
layers.enter().append('g')
.classed('layers', true);
var layers = Lib.ensureSingle(traceGroup, 'g', 'layers');
layers.style('opacity', d[0].trace.opacity);

var fill = layers
Expand Down
23 changes: 8 additions & 15 deletions src/components/rangeselector/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var Registry = require('../../registry');
var Plots = require('../../plots/plots');
var Color = require('../color');
var Drawing = require('../drawing');
var Lib = require('../../lib');
var svgTextUtils = require('../../lib/svg_text_utils');
var axisIds = require('../../plots/cartesian/axis_ids');
var anchorUtils = require('../legend/anchor_utils');
Expand Down Expand Up @@ -121,13 +122,9 @@ function isActive(axisLayout, opts, update) {
}

function drawButtonRect(button, selectorLayout, d) {
var rect = button.selectAll('rect')
.data([0]);

rect.enter().append('rect')
.classed('selector-rect', true);

rect.attr('shape-rendering', 'crispEdges');
var rect = Lib.ensureSingle(button, 'rect', 'selector-rect', function(s) {
s.attr('shape-rendering', 'crispEdges');
});

rect.attr({
'rx': constants.rx,
Expand All @@ -150,14 +147,10 @@ function drawButtonText(button, selectorLayout, d, gd) {
svgTextUtils.convertToTspans(s, gd);
}

var text = button.selectAll('text')
.data([0]);

text.enter().append('text')
.classed('selector-text', true)
.classed('user-select-none', true);

text.attr('text-anchor', 'middle');
var text = Lib.ensureSingle(button, 'text', 'selector-text', function(s) {
s.classed('user-select-none', true)
.attr('text-anchor', 'middle');
});

text.call(Drawing.font, selectorLayout.font)
.text(getLabel(d))
Expand Down
Loading

0 comments on commit 9a79056

Please sign in to comment.