Skip to content

Commit 539ca22

Browse files
committed
Drawing.bBox "inTester" mode for quicker testing of dummy elements
1 parent 62156dd commit 539ca22

File tree

3 files changed

+56
-12
lines changed

3 files changed

+56
-12
lines changed

src/components/drawing/index.js

+31-10
Original file line numberDiff line numberDiff line change
@@ -604,15 +604,31 @@ drawing.makeTester = function() {
604604

605605
/*
606606
* use our offscreen tester to get a clientRect for an element,
607-
* in a reference frame where it isn't translated and its anchor
608-
* point is at (0,0)
607+
* in a reference frame where it isn't translated (or transformed) and
608+
* its anchor point is at (0,0)
609609
* always returns a copy of the bbox, so the caller can modify it safely
610+
*
611+
* @param {SVGElement} node: the element to measure. If possible this should be
612+
* a <text> or MathJax <g> element that's already passed through
613+
* `convertToTspans` because in that case we can cache the results, but it's
614+
* possible to pass in any svg element.
615+
*
616+
* @param {boolean} inTester: is this element already in `drawing.tester`?
617+
* If you are measuring a dummy element, rather than one you really intend
618+
* to use on the plot, making it in `drawing.tester` in the first place
619+
* allows us to test faster because it cuts out cloning and appending it.
620+
*
621+
* @param {string} hash: for internal use only, if we already know the cache key
622+
* for this element beforehand.
623+
*
624+
* @return {object}: a plain object containing the width, height, left, right,
625+
* top, and bottom of `node`
610626
*/
611627
drawing.savedBBoxes = {};
612628
var savedBBoxesCount = 0;
613629
var maxSavedBBoxes = 10000;
614630

615-
drawing.bBox = function(node, hash) {
631+
drawing.bBox = function(node, inTester, hash) {
616632
/*
617633
* Cache elements we've already measured so we don't have to
618634
* remeasure the same thing many times
@@ -645,7 +661,7 @@ drawing.bBox = function(node, hash) {
645661
if(!transform) {
646662
// in this case, just varying x and y, don't bother caching
647663
// the final bBox because the alteration is quick.
648-
var innerBB = drawing.bBox(innerNode, hash);
664+
var innerBB = drawing.bBox(innerNode, false, hash);
649665
if(x) {
650666
innerBB.left += x;
651667
innerBB.right += x;
@@ -672,12 +688,17 @@ drawing.bBox = function(node, hash) {
672688
if(out) return Lib.extendFlat({}, out);
673689
}
674690
}
691+
var testNode, tester;
692+
if(inTester) {
693+
testNode = node;
694+
}
695+
else {
696+
tester = drawing.tester.node();
675697

676-
var tester = drawing.tester.node();
677-
678-
// copy the node to test into the tester
679-
var testNode = node.cloneNode(true);
680-
tester.appendChild(testNode);
698+
// copy the node to test into the tester
699+
testNode = node.cloneNode(true);
700+
tester.appendChild(testNode);
701+
}
681702

682703
// standardize its position (and newline tspans if any)
683704
d3.select(testNode)
@@ -689,7 +710,7 @@ drawing.bBox = function(node, hash) {
689710
.node()
690711
.getBoundingClientRect();
691712

692-
tester.removeChild(testNode);
713+
if(!inTester) tester.removeChild(testNode);
693714

694715
var bb = {
695716
height: testRect.height,

src/traces/contour/plot.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ function makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours, perimeter) {
368368
};
369369
}
370370

371-
var dummyText = defs.append('text')
371+
var dummyText = Drawing.tester.append('text')
372372
.attr('data-notex', 1)
373373
.call(Drawing.font, contours.font);
374374

@@ -397,7 +397,7 @@ function makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours, perimeter) {
397397
var text = contourFormat(d.level);
398398
dummyText.text(text)
399399
.call(svgTextUtils.convertToTspans, gd);
400-
var bBox = Drawing.bBox(dummyText.node());
400+
var bBox = Drawing.bBox(dummyText.node(), true);
401401
var textWidth = bBox.width;
402402
var textHeight = bBox.height;
403403
var dy = (bBox.top + bBox.bottom) / 2;

test/jasmine/tests/drawing_test.js

+23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var d3 = require('d3');
22
var Plotly = require('@lib/index');
33
var Drawing = require('@src/components/drawing');
4+
var svgTextUtils = require('@src/lib/svg_text_utils');
45
var createGraphDiv = require('../assets/create_graph_div');
56
var destroyGraphDiv = require('../assets/destroy_graph_div');
67
var fail = require('../assets/fail_test');
@@ -422,6 +423,28 @@ describe('Drawing', function() {
422423
.catch(fail)
423424
.then(done);
424425
});
426+
427+
it('works with dummy nodes created in Drawing.tester', function() {
428+
var node = Drawing.tester.append('text')
429+
.text('bananas')
430+
.call(Drawing.font, '"Open Sans", verdana, arial, sans-serif', 19)
431+
.call(svgTextUtils.convertToTspans).node();
432+
433+
expect(node.parentNode).toBe(Drawing.tester.node());
434+
435+
assertBBox(Drawing.bBox(node), {
436+
height: 21,
437+
width: 80,
438+
left: 0,
439+
top: -17,
440+
right: 80,
441+
bottom: 4
442+
});
443+
444+
expect(node.parentNode).toBe(Drawing.tester.node());
445+
446+
node.parentNode.removeChild(node);
447+
});
425448
});
426449
});
427450

0 commit comments

Comments
 (0)