arrow
Draws a curved, arrowheaded connector from the first child to the second. Like line, arrow links elements that have already been placed by another layer or constraint — but it renders a directed, gently bowed arrow (powered by perfect-arrows) instead of a plain line. Reach for it in diagrams: callouts, pointer/heap edges, and labeled annotations.
gf.layer([
gf.rect({ w: 70, h: 40, fill: gf.color.blue[2] }).name("a"),
gf.rect({ w: 70, h: 40, fill: gf.color.red[2] }).name("b"),
])
.relate(({ a, b }) => [
gf.Constraint.distribute({ dir: "x", spacing: 120 }, [a, b]),
gf.Constraint.align({ y: "middle" }, [a, b]),
gf.arrow({ stroke: "#333", strokeWidth: 3 }, [a, b]),
])
.render(root, { w: 320, h: 100 });Signature
arrow({
// visual
stroke?, strokeWidth?, start?,
// curve shape (perfect-arrows)
bow?, stretch?, stretchMin?, stretchMax?,
padStart?, padEnd?, flip?, straights?,
}, [from, to])The children are usually two named elements: operands of a .relate() callback, or ref(...) calls (or datum-level sub-refs of a createName token). The arrow runs from the first child to the second. Fewer than two children renders nothing.
Parameters
A perfect-arrows box-to-box arrow between exactly two children.
| Option | Type | Default | Description |
|---|---|---|---|
bow | number | 0.2 | Baseline curvature. 0 is a straight line; higher values bow the arc further from center. |
stretch | number | 0.5 | How much the bow grows as the endpoints get closer, and shrinks as they get farther apart. |
stretchMin | number | 40 | Distance in pixels below which stretch has its full effect. |
stretchMax | number | 420 | Distance in pixels above which stretch has no effect. |
padStart | number | 5 | Gap in pixels between the source box and the start of the line. |
padEnd | number | 20 | Gap in pixels between the end of the line and the target box, leaving room for the arrowhead. |
flip | boolean | false | Flip which side the arrow bows toward. |
straights | boolean | true | Allow a perfectly straight line when the endpoints are axis-aligned, instead of forcing a slight bow. |
stroke | string | "black" | Color of the arrow's line and head, and of the start dot when shown. |
strokeWidth | number | 3 | Line width; also scales the arrowhead and the start dot. |
start | boolean | false | Draw a dot at the start endpoint. |
Curve shape
The arrow's path is a quadratic bezier whose bow and routing come straight from perfect-arrows' getBoxToBoxArrow. The bow, stretch, stretchMin, stretchMax, padStart, padEnd, flip, and straights options above are passed through to it unchanged.
Examples
// Labeled callout: a text label pointing at a named shape (gently bowed default)
layer([planets, label]).relate(({ label, Mercury }) => [
arrow({}, [label, Mercury]),
]);
// Pointer edge: straight, with a dot at the source (e.g. a heap/stack reference)
layer([stack, heap]).relate(({ stackSlot, heapCell }) => [
arrow({ bow: 0, stretch: 0, padStart: 0, stroke: "#1A5683", start: true }, [
stackSlot,
heapCell,
]),
]);
// Datum-level endpoints: arrow into a specific selected sub-element of a
// createName token (a token reaches across component boundaries)
arrow({ bow: 0, padEnd: 25, padStart: 0, stroke: "#1A5683", start: true }, [
ref(heap).path(0, 1).val,
ref(heap).path(0, 2).elmTuples[0],
]);Notes
- The arrow's bbox is the union of the resolved endpoints' boxes — like
line, it does not contribute its own space. - An arrow over string names is a
.relate()clause: it is laid out after the layer's constraints, so it runs between the final positions of its endpoints. A stringref("name")outside a.relate()clause is an error. WithcreateName()tokens, the name is global andref(token)works anywhere. - Use
lineorribboninstead when you want an undirected line (or a multi-stop polyline) with explicit bbox-anchor control; usearrowwhen you want a directed arrowhead and automatic curved routing. - Pair the operator with z-order constraints (
Constraint.zAbove/zBelow) when an arrow needs to sit between two elements in paint order.
