@@ -392,15 +392,14 @@ drawing.singlePointStyle = function(d, sel, trace, markerScale, lineScale, gd) {
392
392
393
393
} ;
394
394
395
- drawing . pointStyle = function ( s , trace ) {
395
+ drawing . pointStyle = function ( s , trace , gd ) {
396
396
if ( ! s . size ( ) ) return ;
397
397
398
398
// allow array marker and marker line colors to be
399
399
// scaled by given max and min to colorscales
400
400
var marker = trace . marker ;
401
401
var markerScale = drawing . tryColorscale ( marker , '' ) ;
402
402
var lineScale = drawing . tryColorscale ( marker , 'line' ) ;
403
- var gd = Lib . getPlotDiv ( s . node ( ) ) ;
404
403
405
404
s . each ( function ( d ) {
406
405
drawing . singlePointStyle ( d , d3 . select ( this ) , trace , markerScale , lineScale , gd ) ;
@@ -423,7 +422,7 @@ drawing.tryColorscale = function(marker, prefix) {
423
422
// draw text at points
424
423
var TEXTOFFSETSIGN = { start : 1 , end : - 1 , middle : 0 , bottom : 1 , top : - 1 } ,
425
424
LINEEXPAND = 1.3 ;
426
- drawing . textPointStyle = function ( s , trace ) {
425
+ drawing . textPointStyle = function ( s , trace , gd ) {
427
426
s . each ( function ( d ) {
428
427
var p = d3 . select ( this ) ,
429
428
text = d . tx || trace . text ;
@@ -454,7 +453,7 @@ drawing.textPointStyle = function(s, trace) {
454
453
d . tc || trace . textfont . color )
455
454
. attr ( 'text-anchor' , h )
456
455
. text ( text )
457
- . call ( svgTextUtils . convertToTspans ) ;
456
+ . call ( svgTextUtils . convertToTspans , gd ) ;
458
457
var pgroup = d3 . select ( this . parentNode ) ,
459
458
tspans = p . selectAll ( 'tspan.line' ) ,
460
459
numLines = ( ( tspans [ 0 ] . length || 1 ) - 1 ) * LINEEXPAND + 1 ,
@@ -611,19 +610,18 @@ drawing.makeTester = function() {
611
610
// in a reference frame where it isn't translated and its anchor
612
611
// point is at (0,0)
613
612
// always returns a copy of the bbox, so the caller can modify it safely
614
- var savedBBoxes = [ ] ;
613
+ drawing . savedBBoxes = { } ;
614
+ var savedBBoxesCount = 0 ;
615
615
var maxSavedBBoxes = 10000 ;
616
616
617
617
drawing . bBox = function ( node ) {
618
618
// cache elements we've already measured so we don't have to
619
619
// remeasure the same thing many times
620
- var saveNum = node . attributes [ 'data-bb' ] ;
621
- if ( saveNum && saveNum . value ) {
622
- return Lib . extendFlat ( { } , savedBBoxes [ saveNum . value ] ) ;
623
- }
620
+ var hash = nodeHash ( node ) ;
621
+ var out = drawing . savedBBoxes [ hash ] ;
622
+ if ( out ) return Lib . extendFlat ( { } , out ) ;
624
623
625
- var tester3 = drawing . tester ;
626
- var tester = tester3 . node ( ) ;
624
+ var tester = drawing . tester . node ( ) ;
627
625
628
626
// copy the node to test into the tester
629
627
var testNode = node . cloneNode ( true ) ;
@@ -655,18 +653,41 @@ drawing.bBox = function(node) {
655
653
// make sure we don't have too many saved boxes,
656
654
// or a long session could overload on memory
657
655
// by saving boxes for long-gone elements
658
- if ( savedBBoxes . length >= maxSavedBBoxes ) {
659
- d3 . selectAll ( '[data-bb]' ) . attr ( 'data-bb' , null ) ;
660
- savedBBoxes = [ ] ;
656
+ if ( savedBBoxesCount >= maxSavedBBoxes ) {
657
+ drawing . savedBBoxes = { } ;
658
+ maxSavedBBoxes = 0 ;
661
659
}
662
660
663
661
// cache this bbox
664
- node . setAttribute ( 'data-bb' , savedBBoxes . length ) ;
665
- savedBBoxes . push ( bb ) ;
662
+ drawing . savedBBoxes [ hash ] = bb ;
663
+ savedBBoxesCount ++ ;
666
664
667
665
return Lib . extendFlat ( { } , bb ) ;
668
666
} ;
669
667
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
+
670
691
/*
671
692
* make a robust clipPath url from a local id
672
693
* note! We'd better not be exporting from a page
0 commit comments