@@ -392,15 +392,14 @@ drawing.singlePointStyle = function(d, sel, trace, markerScale, lineScale, gd) {
392392
393393} ;
394394
395- drawing . pointStyle = function ( s , trace ) {
395+ drawing . pointStyle = function ( s , trace , gd ) {
396396 if ( ! s . size ( ) ) return ;
397397
398398 // allow array marker and marker line colors to be
399399 // scaled by given max and min to colorscales
400400 var marker = trace . marker ;
401401 var markerScale = drawing . tryColorscale ( marker , '' ) ;
402402 var lineScale = drawing . tryColorscale ( marker , 'line' ) ;
403- var gd = Lib . getPlotDiv ( s . node ( ) ) ;
404403
405404 s . each ( function ( d ) {
406405 drawing . singlePointStyle ( d , d3 . select ( this ) , trace , markerScale , lineScale , gd ) ;
@@ -423,7 +422,7 @@ drawing.tryColorscale = function(marker, prefix) {
423422// draw text at points
424423var TEXTOFFSETSIGN = { start : 1 , end : - 1 , middle : 0 , bottom : 1 , top : - 1 } ,
425424 LINEEXPAND = 1.3 ;
426- drawing . textPointStyle = function ( s , trace ) {
425+ drawing . textPointStyle = function ( s , trace , gd ) {
427426 s . each ( function ( d ) {
428427 var p = d3 . select ( this ) ,
429428 text = d . tx || trace . text ;
@@ -454,7 +453,7 @@ drawing.textPointStyle = function(s, trace) {
454453 d . tc || trace . textfont . color )
455454 . attr ( 'text-anchor' , h )
456455 . text ( text )
457- . call ( svgTextUtils . convertToTspans ) ;
456+ . call ( svgTextUtils . convertToTspans , gd ) ;
458457 var pgroup = d3 . select ( this . parentNode ) ,
459458 tspans = p . selectAll ( 'tspan.line' ) ,
460459 numLines = ( ( tspans [ 0 ] . length || 1 ) - 1 ) * LINEEXPAND + 1 ,
@@ -611,19 +610,18 @@ drawing.makeTester = function() {
611610// in a reference frame where it isn't translated and its anchor
612611// point is at (0,0)
613612// always returns a copy of the bbox, so the caller can modify it safely
614- var savedBBoxes = [ ] ;
613+ drawing . savedBBoxes = { } ;
614+ var savedBBoxesCount = 0 ;
615615var maxSavedBBoxes = 10000 ;
616616
617617drawing . bBox = function ( node ) {
618618 // cache elements we've already measured so we don't have to
619619 // 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 ) ;
624623
625- var tester3 = drawing . tester ;
626- var tester = tester3 . node ( ) ;
624+ var tester = drawing . tester . node ( ) ;
627625
628626 // copy the node to test into the tester
629627 var testNode = node . cloneNode ( true ) ;
@@ -655,18 +653,41 @@ drawing.bBox = function(node) {
655653 // make sure we don't have too many saved boxes,
656654 // or a long session could overload on memory
657655 // 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 ;
661659 }
662660
663661 // cache this bbox
664- node . setAttribute ( 'data-bb' , savedBBoxes . length ) ;
665- savedBBoxes . push ( bb ) ;
662+ drawing . savedBBoxes [ hash ] = bb ;
663+ savedBBoxesCount ++ ;
666664
667665 return Lib . extendFlat ( { } , bb ) ;
668666} ;
669667
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+
670691/*
671692 * make a robust clipPath url from a local id
672693 * note! We'd better not be exporting from a page
0 commit comments