@@ -483,13 +483,13 @@ annotations.draw = function(gd, index, opt, value) {
483483
484484 var arrowX , arrowY ;
485485
486- if ( options . absoluteArrowTail ) {
487- arrowX = Lib . constrain ( annPosPx . x , 1 , fullLayout . width - 1 ) ;
488- arrowY = Lib . constrain ( annPosPx . y , 1 , fullLayout . height - 1 ) ;
489- } else {
490- // make sure the arrowhead (if there is one)
491- // and the annotation center are visible
492- if ( options . showarrow ) {
486+ // make sure the arrowhead (if there is one)
487+ // and the annotation center are visible
488+ if ( options . showarrow ) {
489+ if ( options . absoluteArrowTail ) {
490+ arrowX = Lib . constrain ( annPosPx . x , 1 , fullLayout . width - 1 ) ;
491+ arrowY = Lib . constrain ( annPosPx . y , 1 , fullLayout . height - 1 ) ;
492+ } else {
493493 arrowX = Lib . constrain ( annPosPx . x - options . ax , 1 , fullLayout . width - 1 ) ;
494494 arrowY = Lib . constrain ( annPosPx . y - options . ay , 1 , fullLayout . height - 1 ) ;
495495 }
@@ -511,8 +511,15 @@ annotations.draw = function(gd, index, opt, value) {
511511 annbg . call ( Drawing . setRect , borderwidth / 2 , borderwidth / 2 ,
512512 outerwidth - borderwidth , outerheight - borderwidth ) ;
513513
514- var annX = Math . round ( annPosPx . x - outerwidth / 2 ) ,
514+ var annX = 0 , annY = 0 ;
515+ if ( options . absoluteArrowTail ) {
516+ annX = Math . round ( annPosPx . aax - outerwidth / 2 ) ;
517+ annY = Math . round ( annPosPx . aay - outerheight / 2 ) ;
518+ } else {
519+ annX = Math . round ( annPosPx . x - outerwidth / 2 ) ;
515520 annY = Math . round ( annPosPx . y - outerheight / 2 ) ;
521+ }
522+
516523 ann . call ( Lib . setTranslate , annX , annY ) ;
517524
518525 var annbase = 'annotations[' + index + ']' ;
@@ -530,11 +537,18 @@ annotations.draw = function(gd, index, opt, value) {
530537 // looks like there may be a cross-browser solution, see
531538 // http://stackoverflow.com/questions/5364980/
532539 // how-to-get-the-width-of-an-svg-tspan-element
533- var arrowX0 = annPosPx . x + dx ,
534- arrowY0 = annPosPx . y + dy ,
540+ var arrowX0 , arrowY0 ;
541+
542+ if ( options . absoluteArrowTail ) {
543+ arrowX0 = annPosPx . aax + dx ;
544+ arrowY0 = annPosPx . aay + dy ;
545+ } else {
546+ arrowX0 = annPosPx . x + dx ;
547+ arrowY0 = annPosPx . y + dy ;
548+ }
535549
536550 // create transform matrix and related functions
537- transform =
551+ var transform =
538552 Lib . rotationXYMatrix ( textangle , arrowX0 , arrowY0 ) ,
539553 applyTransform = Lib . apply2DTransform ( transform ) ,
540554 applyTransform2 = Lib . apply2DTransform2 ( transform ) ,
@@ -549,33 +563,29 @@ annotations.draw = function(gd, index, opt, value) {
549563 [ arrowX0 + xHalf , arrowY0 - yHalf , arrowX0 - xHalf , arrowY0 - yHalf ]
550564 ] . map ( applyTransform2 ) ;
551565
552- if ( options . absoluteArrowTail ) {
553- arrowX0 = annPosPx . aax ;
554- arrowY0 = annPosPx . aay ;
555- } else {
556- // Remove the line if it ends inside the box. Use ray
557- // casting for rotated boxes: see which edges intersect a
558- // line from the arrowhead to far away and reduce with xor
559- // to get the parity of the number of intersections.
560- if ( edges . reduce ( function ( a , x ) {
561- return a ^
562- ! ! lineIntersect ( arrowX , arrowY , arrowX + 1e6 , arrowY + 1e6 ,
563- x [ 0 ] , x [ 1 ] , x [ 2 ] , x [ 3 ] ) ;
564- } , false ) ) {
565- // no line or arrow - so quit drawArrow now
566- return ;
567- }
568-
569- edges . forEach ( function ( x ) {
570- var p = lineIntersect ( arrowX0 , arrowY0 , arrowX , arrowY ,
566+ // Remove the line if it ends inside the box. Use ray
567+ // casting for rotated boxes: see which edges intersect a
568+ // line from the arrowhead to far away and reduce with xor
569+ // to get the parity of the number of intersections.
570+ if ( edges . reduce ( function ( a , x ) {
571+ return a ^
572+ ! ! lineIntersect ( arrowX , arrowY , arrowX + 1e6 , arrowY + 1e6 ,
571573 x [ 0 ] , x [ 1 ] , x [ 2 ] , x [ 3 ] ) ;
572- if ( p ) {
573- arrowX0 = p . x ;
574- arrowY0 = p . y ;
575- }
576- } ) ;
574+ } , false ) ) {
575+ // no line or arrow - so quit drawArrow now
576+ return ;
577577 }
578578
579+ edges . forEach ( function ( x ) {
580+ var p = lineIntersect ( arrowX0 , arrowY0 , arrowX , arrowY ,
581+ x [ 0 ] , x [ 1 ] , x [ 2 ] , x [ 3 ] ) ;
582+ if ( p ) {
583+ arrowX0 = p . x ;
584+ arrowY0 = p . y ;
585+ }
586+ } ) ;
587+
588+
579589 var strokewidth = options . arrowwidth ,
580590 arrowColor = options . arrowcolor ;
581591
@@ -645,12 +655,12 @@ annotations.draw = function(gd, index, opt, value) {
645655 update [ annbase + '.ay' ] = ya ?
646656 ( options . ay + dy / ya . _m ) :
647657 ( 1 - ( ( arrowY + dy - gs . t ) / gs . h ) ) ;
648- } else {
649- anng . attr ( {
650- transform : 'rotate(' + textangle + ',' +
651- xcenter + ',' + ycenter + ')'
652- } ) ;
653658 }
659+
660+ anng . attr ( {
661+ transform : 'rotate(' + textangle + ',' +
662+ xcenter + ',' + ycenter + ')'
663+ } ) ;
654664 } ,
655665 doneFn : function ( dragged ) {
656666 if ( dragged ) {
@@ -680,7 +690,6 @@ annotations.draw = function(gd, index, opt, value) {
680690 element : ann . node ( ) ,
681691 prepFn : function ( ) {
682692 var pos = Lib . getTranslate ( ann ) ;
683-
684693 x0 = pos . x ;
685694 y0 = pos . y ;
686695 update = { } ;
@@ -689,8 +698,13 @@ annotations.draw = function(gd, index, opt, value) {
689698 ann . call ( Lib . setTranslate , x0 + dx , y0 + dy ) ;
690699 var csr = 'pointer' ;
691700 if ( options . showarrow ) {
692- update [ annbase + '.ax' ] = options . ax + dx ;
693- update [ annbase + '.ay' ] = options . ay + dy ;
701+ if ( options . absoluteArrowTail ) {
702+ update [ annbase + '.ax' ] = xa . p2l ( xa . l2p ( options . ax ) + dx ) ;
703+ update [ annbase + '.ay' ] = ya . p2l ( ya . l2p ( options . ay ) + dy ) ;
704+ } else {
705+ update [ annbase + '.ax' ] = options . ax + dx ;
706+ update [ annbase + '.ay' ] = options . ay + dy ;
707+ }
694708 drawArrow ( dx , dy ) ;
695709 }
696710 else {
0 commit comments