Skip to content

Commit e93fdbf

Browse files
committed
arrow comments
1 parent dd32646 commit e93fdbf

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

src/marks/arrow.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class Arrow extends Mark {
2121
y2,
2222
bend = 0,
2323
headAngle = 60,
24-
headLength = 8,
24+
headLength = 8, // Disable the arrow with headLength = 0; or, use Plot.link.
2525
inset = 0,
2626
insetStart = inset,
2727
insetEnd = inset
@@ -71,6 +71,8 @@ export class Arrow extends Mark {
7171
.join("path")
7272
.call(applyDirectStyles, this)
7373
.attr("d", i => {
74+
// The start ⟨x1,y1⟩ and end ⟨x2,y2⟩ points may be inset, and the
75+
// ending line angle may be altered for inset swoopy arrows.
7476
let x1 = X1[i], y1 = Y1[i], x2 = X2[i], y2 = Y2[i];
7577
let lineAngle = Math.atan2(y2 - y1, x2 - x1);
7678
const lineLength = Math.hypot(x2 - x1, y2 - y1);
@@ -98,7 +100,7 @@ export class Arrow extends Mark {
98100
}
99101
// For the end inset, rotate the arrowhead so that it aligns
100102
// with the truncated end of the arrow. Since the arrow is a
101-
// segment of the circle centered at <cx,cy>, we can compute
103+
// segment of the circle centered at cx,cy, we can compute
102104
// the angular difference to the new endpoint.
103105
if (insetEnd) {
104106
const [x, y] = circleCircleIntersect([cx, cy, r], [x2, y2, insetEnd], sign * Math.sign(insetEnd));
@@ -135,13 +137,21 @@ export class Arrow extends Mark {
135137
}
136138
}
137139

138-
function pointPointCenter([ax, ay], [bx, by], r, sign = 1) {
140+
// Returns the center of a circle that goes through the two given points ⟨ax,ay⟩
141+
// and ⟨bx,by⟩ and has radius r. There are two such points; use the sign +1 or
142+
// -1 to chose between them. Returns [NaN, NaN] if r is too small.
143+
function pointPointCenter([ax, ay], [bx, by], r, sign) {
139144
const dx = bx - ax, dy = by - ay, d = Math.hypot(dx, dy);
140145
const k = sign * Math.sqrt(r * r - d * d / 4) / d;
141146
return [(ax + bx) / 2 - dy * k, (ay + by) / 2 + dx * k];
142147
}
143148

144-
function circleCircleIntersect([ax, ay, ar], [bx, by, br], sign = 1) {
149+
// Given two circles, one centered at ⟨ax,ay⟩ with radius ar, and the other
150+
// centered at ⟨bx,by⟩ with radius br, returns a point at which the two circles
151+
// intersect. There are typically two such points; use the sign +1 or -1 to
152+
// chose between them. Returns [NaN, NaN] if there is no intersection.
153+
// https://mathworld.wolfram.com/Circle-CircleIntersection.html
154+
function circleCircleIntersect([ax, ay, ar], [bx, by, br], sign) {
145155
const dx = bx - ax, dy = by - ay, d = Math.hypot(dx, dy);
146156
const x = (dx * dx + dy * dy - br * br + ar * ar) / (2 * d);
147157
const y = sign * Math.sign(ay) * Math.sqrt(ar * ar - x * x);

0 commit comments

Comments
 (0)