fletcher.edge()
Draw a path with arrow marks, labels, and automatic snapping to nodes.
fletcher.edge( ..args: coord str content, vertices: array, stroke: stroke, dash, extrude: number length array, corner-radius: length number none, marks: str array, mark-scale: number percent auto, label: content dictionary array, label-pos: ratio number length, label-side: auto none center top bottom left right start end, label-sep: length, label-fill, label-angle: angle auto top bottom left right, label-anchor: anchor, snap-to: none auto pair, snap-method: "trim" "move" pair, outset: length pair, shorten: length number array, name: label str, decorate, layer: number, crossing: bool, crossing-fill: color, crossing-thickness: number length, in-math: bool, debug, )
..argscoord or str or content
An edge’s positional arguments may specify:
- the edge’s
vertices, each given as a CeTZ coordinate; - the CeTZ path to apply edge marks, styles, and labels to;
- the edge’s
marks, e.g.,"->"or"solid=/=solid"; - the body content of an edge
label, e.g.,$f$; or - some other style flags (
dashed,dotted,double,triple,crossing).
Vertex coordinates come first but are optional:
edge(from, to, ..) // explicit start and end
edge(to, ..) == edge(auto, to, ..) // start from previous node
edge(..) == edge(auto, auto, ..) // between previous and next nodes
edge(from, v1, v2, ..vs, to, ..) // multiple vertices
edge(from, "->", to) // for two vertices, marks can go in the middleVertices after the first one can be relative coordinate shorthand strings containing the characters or commas, e.g., edge((0,0), "u,rr,d").
If applying edge effects to a CeTZ path, no vertices should be given and the path should be the first argument:
edge(cetz.draw.bezier(..), "<->") // add marks to a cetz pathIf given as positional arguments, an edge’s marks and label are disambiguated based on their types. For example, the following are equivalent:
edge(.., $f$, "->")
edge(.., "->", $f$)
edge(.., $f$, marks: "->")
edge(.., "->", label: $f$)
edge(.., label: $f$, marks: "->")verticesarray default ()
()Array of coordinates for the edge.
Vertices can also be specified as leading positional arguments (so edge((0,1), (1,1), $f$, ..) is the same as edge($f$, vertices: ((0,1), (1,1)), ..)).
strokestroke default auto
autoStroke style for the edge.
The default thickness matches the thickness of the symbol in the default math font with the current text size.
The default stroke style can be set with the edge-stroke option of diagram() or with cetz.draw.set-style(edge: (stroke: ..)).
dashdefault auto
autoSet the dash property of the current stroke style.
You can also set the dash style using stroke; this is simply an alias.
extrudenumber or length or array default auto
autoDraw a separate stroke for each extrusion offset to obtain a multi-stroke effect. Offsets may be numbers (specifying multiples of the stroke’s thickness) or lengths.
Some line styles can also be used as a shortcut:
edge("=")produces(extrude: (-2, 2))edge("==")produces(extrude: (-4, 0, 4))
corner-radiuslength or number or none default auto
autoRadius of curvature for rounded corners.
For extruded edges, this defines the radius of curvature of the innermost stroke as you go around the bend. Note that none, which enables miter joins, is different from 0.
This length specifies the corner radius for right-angled bends. The actual radius is smaller for acute angles and larger for obtuse angles to balance things visually. See path-effect.corner-radius for details.
marksstr or array default ()
()Marks or arrows to draw along the edge.
This can be a mark shorthand like "->", "<|.." or "-x-", or an array of mark objects like (none, ">") or ((pos: 0.7, inherit: "stealth"),).
Mark shorthands are strings of the form , where each is a mark name and is a line style (which must be the same for the whole edge). See the Built-in marks and line styles for all possible marks and line styles.
For more control, an array of mark shorthands or mark objects may be given.
#diagram(edge(marks: (none, ">"))) \
#diagram(edge(marks: (none, (inherit: ">", size: 20)))) \
#diagram(edge(marks: ((inherit: ">", pos: 0.7, stroke: 1pt + blue),)))mark-scalenumber or percent or auto default auto
autoMark size multiplier.
The size parameter of each mark is multiplied by the mark scale before being drawn.
This is an edge style that can also be set using diagram(mark-scale: ..) or cetz.draw.set-style(edge: (mark-scale: ..)).
labelcontent or dictionary or array default none
noneContent to place along the edge.
#diagram(edge("->", $f$))The label body may also be given as a positional argument.
edge(.., [Label])
edge(.., label: [Label])Label options can be specified with a dictionary, or as named arguments by adding label- as a prefix . For example, the following are the same:
edge(.., label: (body: [Label], pos: 25%))
edge(.., [Label], label-pos: 25%)Possible label options are:
body: the content to drawangle: orientation of the label body (seelabel-angle)pos: the label’s position along the edge path (seelabel-pos)sep: padding between the label’s body and the path (seelabel-sep)side: which side of the edge to place the body (seelabel-side)anchor: the CeTZ anchor to use for label body (seelabel-anchor)
Multiple labels can be specified with an array:
edge(.., label: ([First label], (body: [Second label], pos: 25%)))label-posratio or number or length default 50%
50%Position along the edge path to place labels.
This can be a ratio, relative to the total path length, or a float whose integer part refers to the segment number and whose fractional part interpolates along the segment (see Path anchors).
#diagram({
edge((0,0), (1,1), (2,1), (2,0), "->", label: (
(body: [1st], pos: 0.5),
(body: [2nd], pos: 1.5),
(body: [3rd], pos: 2.5, side: right),
))
})This can be given as an edge argument like edge(.., $f$, label-pos: 50%) or as a label option like edge(.., label: (body: $f$, pos: 50%)).
label-sideauto or none or center or top or bottom or left or right or start or end default auto
autoWhich side of the edge to place the label on.
If auto, the label is placed roughly above straight edges, or on the outside of curved edges.
An alignment (e.g., top, left, top + left) means place the label beside the edge to whichever side is nearer that direction. If given as an alignment, the side may flip depending on the edge’s angle.
If true, the label is placed above the edge assuming it goes left to right; false is the opposite side. In these cases, the side never flips depending on the edge’s angle.
If center or none, the label is placed directly over the edge, and the label fill defaults to white.
The special alignment values start and end place the label before or after a point, travelling along the edge. This works best when used like (pos: 0%, side: start) or (pos: 100%, side: end).
#diagram(edge((0,0), "->", (1,1), label: (
(body: `start`, side: start, pos: 0%),
(body: `left`, side: left, pos: 0%),
(body: `right`, side: right, pos: 0%),
(body: `center`, side: center, pos: 50%),
(body: `end`, side: end, pos: 100%),
(body: `top`, side: top, pos: 100%),
(body: `bottom`, side: bottom, pos: 100%),
)))This can be given as an edge argument like edge(.., $f$, label-side: top) or as a label option like edge(.., label: (body: $f$, side: top)).
label-seplength default 3pt
3ptSeparation between label body and the edge.
This can be given as an edge argument like edge(.., $f$, label-sep: 3pt) or as a label option like edge(.., label: (body: $f$, sep: 3pt)).
label-angleangle or auto or top or bottom or left or right default 0deg
0degAngle of the label’s body.
A positive angle goes anticlockwise, with 0deg being upright.
An alignment (e.g., top, right) means to rotate the label with the edge’s direction, such that the label is upright along edges going in that direction.
If auto, the best of left or right is chosen; that is, the label is rotated to be tangent to the edge and roughly the right way up.
This can be given as an edge argument like edge(.., $f$, label-angle: auto) or as a label option like edge(.., label: (body: $f$, angle: auto)).
label-anchoranchor default auto
autoThe CeTZ anchor to use for the label content.
If auto, the anchor is automatically chosen depending on label-side and the edge’s angle. This must be auto if the side option is set.
snap-tonone or auto or pair default (auto, auto)
(auto, auto)Names or coordinates of nodes or CeTZ objects to snap the edge’s ends to.
This can be none to disable snapping or auto to detect nearby nodes. A pair such as (none, auto) can be used to control snapping at each end independently.
You can use the "edge.snap" debug option to see the edge’s path before snapping is applied. Additionally, "edge.snap.from" and "edge.snap.to" highlight which nodes actually get snapped to.
snap-method"trim" or "move" or pair default auto
autoWhen an edge snaps to an object’s outline, the edge can be shifted in two ways: one method is to shorten the edge to the point where it meets the object (the "trim" method); the other method is to move the edge’s end vertex to the edge of the object (the "move" method).
You can pass a pair such as ("trim", "move") to control the methods for the start and end of the edge independently.
#diagram(
debug: "edge.snap",
node-fill: yellow,
node-shape: circle,
node((0,0), [Snapping]),
edge("->", `trim`, bend: +90deg, snap-method: "trim"),
edge("->", `move`, bend: -90deg, snap-method: "move"),
node((1,0), [Method]),
)outsetlength or pair default auto
autoGap between the end of the edge and connected nodes.
Similar to node.outset, but specific to the edge instead of the target node. Can be a single length or a pair of lengths (from, to) to control the outset at either end.
#diagram(
node-fill: teal,
node((0,0), [A], <a>),
node((1,0), [B], <b>),
edge(<a>, "<->", <b>, bend: +60deg, [No outset]),
edge(<a>, "<->", <b>, bend: -60deg, outset: 5pt, [Outset]),
)See also shorten.
shortenlength or number or array default 0
0Distance to shorten the edge at either end.
If a length is given, the edge is shortened at both ends. A pair of lengths (start, end) controls shortening at either end of the edge independently.
See also outset.
namelabel or str default none
noneName of the edge for use with coordinate anchors.
Giving a name to an edge allows the use of path anchors to connect other edges or CeTZ objects.
decoratedefault auto
autoApply CeTZ path decorations do the edge, such as wave or zigzag effects.
This can be a dictionary containing any of:
kind, one of"wave","zigzag","square"or"coil"wavelengthamplitudeshorten, distance from ends to start effect fromsmooth, distance over which to “ramp” the effect’s amplitude for a smoother transition
The shorten and smooth options can be lengths, distances (interpreted as multiples of wavelength) or a pair of these, controlling the values at the star and end of the path independently.
#diagram(
edge("ru,r", decorate: (kind: "wave", shorten: 5mm, smooth: 0)),
)#diagram(edge("rr", decorate: (
kind: "square",
amplitude: 3mm,
shorten: 0,
smooth: 2mm,
)))#diagram(
edge("ru,r", "~>", decorate: (shorten: (2, 0))),
)layernumber default auto
autoCanvas layer to draw edge on.
The default is -1 to be under nodes. Edges with equal layer are drawn in the order they are inserted.
See also node.layer, which is 1 by default.
crossingbool default false
falseDraw a backdrop under the edge to give the illusion of it crossing over other lines.
If true, draws a backdrop of color crossing-fill with a thickness crossing-thickness, which are both styles that can be set at the diagram level.
#diagram(
edge-stroke: 2pt,
edge((0,1), (1,0)),
edge((0,0), (1,1)),
edge((2,1), (3,0)),
edge((2,0), (3,1), crossing: true),
)To make sure crossing lines are drawn above other lines, order them later in the diagram or use layer.
crossing-fillcolor default auto
autoColor of the “crossing” backdrop (drawn when crossing is enabled). This should match the background of the figure to give the illusion of breaking lines below it.
crossing-thicknessnumber or length default auto
autoWidth of the “crossing” backdrop (drawn when crossing is enabled) as a length or a multiple of the stroke’s thickness.
in-mathbool default false
falseWhether to return a metadata object which can be placed inside equations, instead of returning an array of functions which can be inserted into a CeTZ canvas.
If you often use fletcher in math mode, consider defining the shortcut:
#let hom = edge.with(in-math: true)The hom edge function can be inserted into equations, like so:
#diagram($x hom(|=>) & f(x)$)See also node.in-math.
debugdefault auto
autoEnable debug annotations for only this edge. See Edge debug options.
If auto, the debug setting is inherited from the enclosing diagram() or flexigrid().