(dx, dy)
| 498 | * while the head stays put, dx and dy are the pixel offsets |
| 499 | */ |
| 500 | var drawArrow = function(dx, dy) { |
| 501 | annGroup |
| 502 | .selectAll('.annotation-arrow-g') |
| 503 | .remove(); |
| 504 | |
| 505 | var headX = annPosPx.x.head; |
| 506 | var headY = annPosPx.y.head; |
| 507 | var tailX = annPosPx.x.tail + dx; |
| 508 | var tailY = annPosPx.y.tail + dy; |
| 509 | var textX = annPosPx.x.text + dx; |
| 510 | var textY = annPosPx.y.text + dy; |
| 511 | |
| 512 | // find the edge of the text box, where we'll start the arrow: |
| 513 | // create transform matrix to rotate the text box corners |
| 514 | var transform = Lib.rotationXYMatrix(textangle, textX, textY); |
| 515 | var applyTransform = Lib.apply2DTransform(transform); |
| 516 | var applyTransform2 = Lib.apply2DTransform2(transform); |
| 517 | |
| 518 | // calculate and transform bounding box |
| 519 | var width = +annTextBG.attr('width'); |
| 520 | var height = +annTextBG.attr('height'); |
| 521 | var xLeft = textX - 0.5 * width; |
| 522 | var xRight = xLeft + width; |
| 523 | var yTop = textY - 0.5 * height; |
| 524 | var yBottom = yTop + height; |
| 525 | var edges = [ |
| 526 | [xLeft, yTop, xLeft, yBottom], |
| 527 | [xLeft, yBottom, xRight, yBottom], |
| 528 | [xRight, yBottom, xRight, yTop], |
| 529 | [xRight, yTop, xLeft, yTop] |
| 530 | ].map(applyTransform2); |
| 531 | |
| 532 | // Remove the line if it ends inside the box. Use ray |
| 533 | // casting for rotated boxes: see which edges intersect a |
| 534 | // line from the arrowhead to far away and reduce with xor |
| 535 | // to get the parity of the number of intersections. |
| 536 | if(edges.reduce(function(a, x) { |
| 537 | return a ^ |
| 538 | !!Lib.segmentsIntersect(headX, headY, headX + 1e6, headY + 1e6, |
| 539 | x[0], x[1], x[2], x[3]); |
| 540 | }, false)) { |
| 541 | // no line or arrow - so quit drawArrow now |
| 542 | return; |
| 543 | } |
| 544 | |
| 545 | edges.forEach(function(x) { |
| 546 | var p = Lib.segmentsIntersect(tailX, tailY, headX, headY, |
| 547 | x[0], x[1], x[2], x[3]); |
| 548 | if(p) { |
| 549 | tailX = p.x; |
| 550 | tailY = p.y; |
| 551 | } |
| 552 | }); |
| 553 | |
| 554 | var strokewidth = options.arrowwidth; |
| 555 | var arrowColor = options.arrowcolor; |
| 556 | var arrowSide = options.arrowside; |
| 557 |
no test coverage detected
searching dependent graphs…