@@ -527,6 +527,7 @@ function drawNumbers(gd, plotGroup, cd, opts) {
527527
528528 var numbers = Lib . ensureSingle ( plotGroup , 'g' , 'numbers' ) ;
529529 var bignumberbBox , deltabBox ;
530+ var numbersbBox ;
530531
531532 var data = [ ] ;
532533 if ( trace . _hasNumber ) data . push ( 'number' ) ;
@@ -575,9 +576,7 @@ function drawNumbers(gd, plotGroup, cd, opts) {
575576 number . text ( bignumberPrefix + fmt ( cd [ 0 ] . y ) + bignumberSuffix ) ;
576577 }
577578
578- number . attr ( 'data-unformatted' , bignumberPrefix + fmt ( cd [ 0 ] . y ) + bignumberSuffix ) ;
579- bignumberbBox = Drawing . bBox ( number . node ( ) ) ;
580-
579+ bignumberbBox = measureText ( bignumberPrefix + fmt ( cd [ 0 ] . y ) + bignumberSuffix , trace . number . font , numbersAnchor ) ;
581580 return number ;
582581 }
583582
@@ -629,9 +628,7 @@ function drawNumbers(gd, plotGroup, cd, opts) {
629628 . call ( Color . fill , deltaFill ( cd [ 0 ] ) ) ;
630629 }
631630
632- delta . attr ( 'data-unformatted' , deltaFormatText ( deltaValue ( cd [ 0 ] ) ) ) ;
633- deltabBox = Drawing . bBox ( delta . node ( ) ) ;
634-
631+ deltabBox = measureText ( deltaFormatText ( deltaValue ( cd [ 0 ] ) ) , trace . delta . font , numbersAnchor ) ;
635632 return delta ;
636633 }
637634
@@ -641,10 +638,12 @@ function drawNumbers(gd, plotGroup, cd, opts) {
641638 delta = drawDelta ( ) ;
642639 key += trace . delta . position + trace . delta . font . size + trace . delta . font . family + trace . delta . valueformat ;
643640 key += trace . delta . increasing . symbol + trace . delta . decreasing . symbol ;
641+ numbersbBox = deltabBox ;
644642 }
645643 if ( trace . _hasNumber ) {
646644 drawBignumber ( ) ;
647645 key += trace . number . font . size + trace . number . font . family + trace . number . valueformat + trace . number . suffix + trace . number . prefix ;
646+ numbersbBox = bignumberbBox ;
648647 }
649648
650649 // Position delta relative to bignumber
@@ -659,53 +658,91 @@ function drawNumbers(gd, plotGroup, cd, opts) {
659658 ] ;
660659
661660 var dx , dy ;
661+ var padding = 0.75 * trace . delta . font . size ;
662662 if ( trace . delta . position === 'left' ) {
663- dx = cache ( trace , 'deltaPos' , 0 , bignumberbBox . left - deltabBox . right - 0.75 * trace . delta . font . size , key , Math . min ) ;
663+ dx = cache ( trace , 'deltaPos' , 0 , - 1 * ( bignumberbBox . width * ( position [ trace . align ] ) + deltabBox . width * ( 1 - position [ trace . align ] ) + padding ) , key , Math . min ) ;
664664 dy = bignumberCenter [ 1 ] - deltaCenter [ 1 ] ;
665+
666+ numbersbBox = {
667+ width : bignumberbBox . width + deltabBox . width + padding ,
668+ height : Math . max ( bignumberbBox . height , deltabBox . height ) ,
669+ left : deltabBox . left + dx ,
670+ right : bignumberbBox . right ,
671+ top : Math . min ( bignumberbBox . top , deltabBox . top + dy ) ,
672+ bottom : Math . max ( bignumberbBox . bottom , deltabBox . bottom + dy )
673+ } ;
665674 }
666675 if ( trace . delta . position === 'right' ) {
667- dx = cache ( trace , 'deltaPos' , 0 , bignumberbBox . right - deltabBox . left + 0.75 * trace . delta . font . size , key , Math . max ) ;
676+ dx = cache ( trace , 'deltaPos' , 0 , bignumberbBox . width * ( 1 - position [ trace . align ] ) + deltabBox . width * position [ trace . align ] + padding , key , Math . max ) ;
668677 dy = bignumberCenter [ 1 ] - deltaCenter [ 1 ] ;
678+
679+ numbersbBox = {
680+ width : bignumberbBox . width + deltabBox . width + padding ,
681+ height : Math . max ( bignumberbBox . height , deltabBox . height ) ,
682+ left : bignumberbBox . left ,
683+ right : deltabBox . right + dx ,
684+ top : Math . min ( bignumberbBox . top , deltabBox . top + dy ) ,
685+ bottom : Math . max ( bignumberbBox . bottom , deltabBox . bottom + dy )
686+ } ;
669687 }
670688 if ( trace . delta . position === 'bottom' ) {
671689 dx = null ;
672690 dy = deltabBox . height ;
691+
692+ numbersbBox = {
693+ width : Math . max ( bignumberbBox . width , deltabBox . width ) ,
694+ height : bignumberbBox . height + deltabBox . height ,
695+ left : Math . min ( bignumberbBox . left , deltabBox . left ) ,
696+ right : Math . max ( bignumberbBox . right , deltabBox . right ) ,
697+ top : bignumberbBox . bottom - bignumberbBox . height ,
698+ bottom : bignumberbBox . bottom + deltabBox . height
699+ } ;
673700 }
674701 if ( trace . delta . position === 'top' ) {
675702 dx = null ;
676703 dy = bignumberbBox . top ;
704+
705+ numbersbBox = {
706+ width : Math . max ( bignumberbBox . width , deltabBox . width ) ,
707+ height : bignumberbBox . height + deltabBox . height ,
708+ left : Math . min ( bignumberbBox . left , deltabBox . left ) ,
709+ right : Math . max ( bignumberbBox . right , deltabBox . right ) ,
710+ top : bignumberbBox . bottom - bignumberbBox . height - deltabBox . height ,
711+ bottom : bignumberbBox . bottom
712+ } ;
677713 }
678714
679715 delta . attr ( { dx : dx , dy : dy } ) ;
680716 }
681717
682718 // Resize numbers to fit within space and position
683- numbers . attr ( 'transform' , function ( ) {
684- var m = opts . numbersScaler ( numbers ) ;
685- key += m [ 2 ] ;
686- var scaleRatio = cache ( trace , 'numbersScale' , 1 , m [ 0 ] , key , Math . min ) ;
687- var numbersbBox = m [ 1 ] ;
688- var translateY ;
689- if ( ! trace . _scaleNumbers ) scaleRatio = 1 ;
690- if ( trace . _isAngular ) {
691- // align vertically to bottom
692- translateY = numbersY - scaleRatio * numbersbBox . bottom ;
693- } else {
694- // align vertically to center
695- translateY = numbersY - scaleRatio * ( numbersbBox . top + numbersbBox . bottom ) / 2 ;
696- }
719+ if ( trace . _hasNumber || trace . _hasDelta ) {
720+ numbers . attr ( 'transform' , function ( ) {
721+ var m = opts . numbersScaler ( numbersbBox ) ;
722+ key += m [ 2 ] ;
723+ var scaleRatio = cache ( trace , 'numbersScale' , 1 , m [ 0 ] , key , Math . min ) ;
724+ var translateY ;
725+ if ( ! trace . _scaleNumbers ) scaleRatio = 1 ;
726+ if ( trace . _isAngular ) {
727+ // align vertically to bottom
728+ translateY = numbersY - scaleRatio * numbersbBox . bottom ;
729+ } else {
730+ // align vertically to center
731+ translateY = numbersY - scaleRatio * ( numbersbBox . top + numbersbBox . bottom ) / 2 ;
732+ }
697733
698- // Stash the top position of numbersbBox for title positioning
699- trace . _numbersTop = scaleRatio * ( numbersbBox . top ) + translateY ;
734+ // Stash the top position of numbersbBox for title positioning
735+ trace . _numbersTop = scaleRatio * ( numbersbBox . top ) + translateY ;
700736
701- var ref = numbersbBox [ numbersAlign ] ;
702- if ( numbersAlign === 'center' ) ref = ( numbersbBox . left + numbersbBox . right ) / 2 ;
703- var translateX = numbersX - scaleRatio * ref ;
737+ var ref = numbersbBox [ numbersAlign ] ;
738+ if ( numbersAlign === 'center' ) ref = ( numbersbBox . left + numbersbBox . right ) / 2 ;
739+ var translateX = numbersX - scaleRatio * ref ;
704740
705- // Stash translateX
706- translateX = cache ( trace , 'numbersTranslate' , 0 , translateX , key , Math . max ) ;
707- return strTranslate ( translateX , translateY ) + ' scale(' + scaleRatio + ')' ;
708- } ) ;
741+ // Stash translateX
742+ translateX = cache ( trace , 'numbersTranslate' , 0 , translateX , key , Math . max ) ;
743+ return strTranslate ( translateX , translateY ) + ' scale(' + scaleRatio + ')' ;
744+ } ) ;
745+ }
709746}
710747
711748// Apply fill, stroke, stroke-width to SVG shape
@@ -786,21 +823,33 @@ function strTranslate(x, y) {
786823 return 'translate(' + x + ',' + y + ')' ;
787824}
788825
789- function fitTextInsideBox ( el , width , height ) {
826+ function fitTextInsideBox ( textBB , width , height ) {
790827 // compute scaling ratio to have text fit within specified width and height
791- var textBB = Drawing . bBox ( el . node ( ) ) ;
828+ // var textBB = Drawing.bBox(el.node());
792829 var ratio = Math . min ( width / textBB . width , height / textBB . height ) ;
793830 return [ ratio , textBB , width + 'x' + height ] ;
794831}
795832
796- function fitTextInsideCircle ( el , radius ) {
833+ function fitTextInsideCircle ( textBB , radius ) {
797834 // compute scaling ratio to have text fit within specified radius
798- var textBB = Drawing . bBox ( el . node ( ) ) ;
835+ // var textBB = Drawing.bBox(el.node());
799836 var elRadius = Math . sqrt ( ( textBB . width / 2 ) * ( textBB . width / 2 ) + textBB . height * textBB . height ) ;
800837 var ratio = radius / elRadius ;
801838 return [ ratio , textBB , radius ] ;
802839}
803840
841+ function measureText ( txt , font , textAnchor ) {
842+ var element = document . createElementNS ( 'http://www.w3.org/2000/svg' , 'text' ) ;
843+ var sel = d3 . select ( element ) ;
844+ sel . text ( txt )
845+ . attr ( 'x' , 0 )
846+ . attr ( 'y' , 0 )
847+ . attr ( 'text-anchor' , textAnchor )
848+ . attr ( 'data-unformatted' , txt )
849+ . call ( Drawing . font , font ) ;
850+ return Drawing . bBox ( sel . node ( ) ) ;
851+ }
852+
804853function cache ( trace , name , initialValue , value , key , fn ) {
805854 var objName = '_cache' + name ;
806855 if ( ! ( trace [ objName ] && trace [ objName ] . key === key ) ) {
0 commit comments