Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ea883e6

Browse filesBrowse files
committed
cache bounding boxes by node contents instead of by data-bb attr
means we get a lot more caching, and a lot less DOM manipulation and getBoundingClientRect
1 parent b9c33c9 commit ea883e6
Copy full SHA for ea883e6

File tree

4 files changed

+34
-18
lines changed
Filter options

4 files changed

+34
-18
lines changed

‎src/components/drawing/index.js

Copy file name to clipboardExpand all lines: src/components/drawing/index.js
+34-12Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -610,19 +610,18 @@ drawing.makeTester = function() {
610610
// in a reference frame where it isn't translated and its anchor
611611
// point is at (0,0)
612612
// always returns a copy of the bbox, so the caller can modify it safely
613-
var savedBBoxes = [];
613+
var savedBBoxes = {};
614+
var savedBBoxesCount = 0;
614615
var maxSavedBBoxes = 10000;
615616

616617
drawing.bBox = function(node) {
617618
// cache elements we've already measured so we don't have to
618619
// remeasure the same thing many times
619-
var saveNum = node.attributes['data-bb'];
620-
if(saveNum && saveNum.value) {
621-
return Lib.extendFlat({}, savedBBoxes[saveNum.value]);
622-
}
620+
var hash = nodeHash(node);
621+
var out = savedBBoxes[hash];
622+
if(out) return Lib.extendFlat({}, out);
623623

624-
var tester3 = drawing.tester;
625-
var tester = tester3.node();
624+
var tester = drawing.tester.node();
626625

627626
// copy the node to test into the tester
628627
var testNode = node.cloneNode(true);
@@ -654,18 +653,41 @@ drawing.bBox = function(node) {
654653
// make sure we don't have too many saved boxes,
655654
// or a long session could overload on memory
656655
// by saving boxes for long-gone elements
657-
if(savedBBoxes.length >= maxSavedBBoxes) {
658-
d3.selectAll('[data-bb]').attr('data-bb', null);
659-
savedBBoxes = [];
656+
if(savedBBoxesCount >= maxSavedBBoxes) {
657+
savedBBoxes = {};
658+
maxSavedBBoxes = 0;
660659
}
661660

662661
// cache this bbox
663-
node.setAttribute('data-bb', savedBBoxes.length);
664-
savedBBoxes.push(bb);
662+
savedBBoxes[hash] = bb;
663+
savedBBoxesCount++;
665664

666665
return Lib.extendFlat({}, bb);
667666
};
668667

668+
// capture everything about a node (at least in our usage) that
669+
// impacts its bounding box, given that bBox clears x, y, and transform
670+
// TODO: is this really everything? Is it worth taking only parts of style,
671+
// so we can share across more changes (like colors)? I guess we can't strip
672+
// colors and stuff from inside innerHTML so maybe not worth bothering outside.
673+
// TODO # 2: this can be long, so could take a lot of memory, do we want to
674+
// hash it? But that can be slow...
675+
// extracting this string from a typical element takes ~3 microsec, where
676+
// doing a simple hash ala https://stackoverflow.com/questions/7616461
677+
// adds ~15 microsec (nearly all of this is spent in charCodeAt)
678+
// function hash(s) {
679+
// var h = 0;
680+
// for (var i = 0; i < s.length; i++) {
681+
// h = (((h << 5) - h) + s.charCodeAt(i)) | 0; // codePointAt?
682+
// }
683+
// return h;
684+
// }
685+
function nodeHash(node) {
686+
return node.innerHTML +
687+
node.getAttribute('text-anchor') +
688+
node.getAttribute('style');
689+
}
690+
669691
/*
670692
* make a robust clipPath url from a local id
671693
* note! We'd better not be exporting from a page

‎src/lib/svg_text_utils.js

Copy file name to clipboardExpand all lines: src/lib/svg_text_utils.js
-3Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@ exports.convertToTspans = function(_context, gd, _callback) {
9494
parent.selectAll('svg.' + svgClass).remove();
9595
parent.selectAll('g.' + svgClass + '-group').remove();
9696
_context.style({visibility: null});
97-
for(var up = _context.node(); up && up.removeAttribute; up = up.parentNode) {
98-
up.removeAttribute('data-bb');
99-
}
10097

10198
function showText() {
10299
if(!parent.empty()) {

‎src/traces/bar/plot.js

Copy file name to clipboardExpand all lines: src/traces/bar/plot.js
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) {
146146
.attr({
147147
'class': 'bartext',
148148
transform: '',
149-
'data-bb': '',
150149
'text-anchor': 'middle',
151150
x: 0,
152151
y: 0

‎src/traces/pie/plot.js

Copy file name to clipboardExpand all lines: src/traces/pie/plot.js
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ module.exports = function plot(gd, cdpie) {
251251
.attr({
252252
'class': 'slicetext',
253253
transform: '',
254-
'data-bb': '',
255254
'text-anchor': 'middle',
256255
x: 0,
257256
y: 0
@@ -274,7 +273,6 @@ module.exports = function plot(gd, cdpie) {
274273
sliceText.call(Drawing.font, trace.outsidetextfont);
275274
if(trace.outsidetextfont.family !== trace.insidetextfont.family ||
276275
trace.outsidetextfont.size !== trace.insidetextfont.size) {
277-
sliceText.attr({'data-bb': ''});
278276
textBB = Drawing.bBox(sliceText.node());
279277
}
280278
transform = transformOutsideText(textBB, pt);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.