Skip to the content.

Diagram Subsystem — API Guide

The diagram subsystem is mural’s Visio-/drawio-style diagramming layer: a canvas of movable shapes joined by routed connectors, with grouping, boolean combine, alignment, rich text, and persistence. This guide is the developer reference — the classes, dependency properties (DPs), methods, enums, and helper functions you wire together. For the end-user gesture reference, see diagram-user-manual.md.

Everything documented here is exported from mural/framework.


1. Architecture at a glance

The subsystem separates the model (data you own and persist) from the view (the control that renders and edits it):

Layer Type Role
Model DiagramDocument Owns the Nodes / Connectors collections, the mutation methods (CreateNode, Group, …) and Save / Load. (The palette lives in the framework ToolboxRepository, not the document.)
View Diagram An ItemsControl/Selector that renders the nodes on a Canvas, handles selection, drag, resize, connector interaction, and raises gesture events.
Items Figure, Group The canvas items themselves — visuals and data fused (no data/visual split, no per-item DataTemplate).
Edges Connector Self-drawing routed lines mounted as siblings behind the figures.

A key design choice: items in a Diagram are the Figure/Group instances directly. GetContainerForItemOverride returns each item unchanged, so a node is its own container. This is why you set Left, Fill, LabelText etc. straight on the Figure.

The view is glued to the model by collaborators (internal helpers the Diagram constructs) and by mutation wiring you attach once (§11). The Diagram never mutates data itself — it raises events (ItemDropped, DeleteRequested, GroupRequested, …) and a DiagramMutator (satisfied structurally by DiagramDocument) does the work.

Rendering layers

Nodes and connectors live in a two-layer panel (DiagramLayersPanel): connectors render first (behind), figures second (in front). The DiagramLayer attached property (Connectors / Figures) routes a child to the right layer.


2. Getting started

2.1 Minimal bootstrap (imperative)

import { Application } from '@pragmatic-tech-ai/mural/runtime';
import {
    DiagramDocument, DiagramStorageKey, ConnectorEndpoint,
} from '@pragmatic-tech-ai/mural/framework';

// Storage is optional — omit it to run without persistence.
const doc = new DiagramDocument(Application.current?.Services.get(DiagramStorageKey));

const start = doc.CreateNode('rectangle', 60, 60);   // → Figure | null
const end   = doc.CreateNode('ellipse',  240, 60);
start.LabelText = 'Start';
end.LabelText   = 'Process';

doc.CreateConnector(
    new ConnectorEndpoint({ Node: start }),
    new ConnectorEndpoint({ Node: end }));

Hand doc to the view via DataContext. In markup the Diagram binds its ItemsSource to Nodes and Connectors to Connectors.

2.2 Wiring the view in .mu

The Diagram control needs its ItemsSource, a Canvas-based ItemsPanel, and whichever feature toggles you want on. It auto-wires its Mutator from the DataContext when the context structurally implements DiagramMutator — DiagramDocument does, so no explicit Mutator binding is needed.

Diagram x:name="nodes"
    [ ItemsSource                  = $Nodes,
      Connectors                   = $Connectors,
      ItemsPanel                   = @DiagramCanvasPanel,   // a Canvas ItemsPanelTemplate
      SelectionMode                = Extended,
      AllowMarqueeSelection        = true,
      AlignmentGuidesEnabled       = true,
      SelectionResizeEnabled       = true,
      TextBlockAdornerEnabled      = true,
      ConnectorInteractionsEnabled = true,
      ReflectSelectionToItems      = true,
      DropReceiver                 = $Self,                 // relative-source-self
      Focusable                    = true ]

DropReceiver = $Self binds the drop target to this Diagram (the internal ScrollViewer is on the bubble path of every canvas drop). See the demo diagram.mu for a full workspace (toolbox, command toolbars, and format pane).


3. DiagramDocument — the model

extends Model, and structurally satisfies DiagramMutator, IDocument, and ICommandTarget.

new DiagramDocument(storage?: DiagramStorage)

Wires the SaveCommand / LoadCommand relay commands. The palette is no longer owned by the document — the Diagram control first-inits a ToolboxRepository (a Services singleton) with a built-in Shapes page; see Palette drops below.

Dependency properties

Property Type Default Notes
Id string 'diagram-<seq>' Document identity.
Title string 'Diagram'  
IsDirty boolean false Set on mutation, cleared by Save/Load.
ActiveView Diagram \| undefined undefined Published so shell regions can bind the view’s commands.
Inspector DiagramInspector instance Format-Shape inspector panel.
Nodes ObservableCollection<Figure \| Group> empty The canvas items.
Connectors ObservableCollection<Connector> empty The edges.
Status string '' Status-strip text.
Storage DiagramStorage \| undefined ctor arg Persistence backend.
SaveCommand / LoadCommand RelayCommand \| undefined instances Bind to Save/Load buttons.

Methods

Method Returns Purpose
CreateNode(kind, x, y) Figure \| null Instantiate a catalog shape at (x, y); null if kind is unknown. Marks dirty.
CreateConnector(source, target) Connector \| null Materialize and add a connector between two ConnectorEndpoints.
DeleteNodes(items) void Remove figures/groups; cascades to delete connectors orphaned by the removal.
DeleteConnectors(connectors) void Remove connectors and detach their host subscriptions.
Group(items) void Wrap ≥2 top-level entries in a new Group (inserted at the lowest member index so it renders behind).
Ungroup(items) void Dissolve each Group; members lift to the group’s parent.
CombineSelection(items, mode) void Boolean-merge ≥2 figures’ geometries via GeometryCombineMode; replace inputs with one combined Figure.
Save() void Serialize Nodes + Connectors to Storage (key mural-diagram-state-v1); clears IsDirty.
Load() void Deserialize from Storage; repopulates the collections; clears IsDirty.

Because DiagramDocument is a DiagramMutator, binding it as the Diagram’s DataContext is all it takes for toolbar/keyboard gestures to flow into these methods.


4. Diagram — the control

extends Selector (which extends ItemsControl). Construct it via markup (it has a default style); most of its surface is DPs you set once.

4.1 Feature toggles

All default to false (or undefined) — opt in per feature:

Property Type Enables
AllowMarqueeSelection boolean (inherited) Rubber-band selection on empty canvas.
AlignmentGuidesEnabled boolean Snap-to-guide lines while dragging.
SelectionResizeEnabled boolean Resize handles around the selection bounds.
TextBlockAdornerEnabled boolean Move/rotate grips on a selected figure’s label.
ConnectorInteractionsEnabled boolean Drag-to-create and endpoint/waypoint editing of connectors.
ReflectSelectionToItems boolean Mirror selection onto each item’s IsSelected DP.

4.2 Data & template DPs

Property Type Notes
Connectors ObservableCollection<Model> \| undefined Bound to DiagramDocument.Connectors.
ConnectorTemplate DataTemplate \| undefined Optional template if connector items aren’t Connectors already.
DropReceiver Visual \| undefined The visual that accepts palette drops (usually $Self).
Mutator DiagramMutator \| undefined Auto-wired from a structurally-matching DataContext.
PositionSnap DiagramPositionSnap \| undefined (rect) => rect drag-snap callback (installed by the guides behavior).

4.3 Read-only selection state

SelectionLeft, SelectionTop, SelectionWidth, SelectionHeight, SelectionCount — the live bounding box + count of the current selection, for binding into an inspector or status strip.

4.4 Format-mirror DPs

When figures/connectors are selected these seed from the first leaf; writing them broadcasts the edit to every selected leaf (see FormatMirror):

SelectionFormatFill (Brush), SelectionFormatStroke (Pen), SelectionFormatSourceCap / SelectionFormatTargetCap (DataTemplate), SelectionFormatSourceCapScale / SelectionFormatTargetCapScale (number), SelectionIsConnector (boolean), ConnectorCapOptions (readonly CapOption[], from connectorCapOptions()).

4.5 Commands

Editing commands are exposed as RelayCommand DPs so a toolbar can bind them directly (see the demo’s four toolbars):

Each command’s CanExecute re-evaluates on selection change. The stable string ids for these commands are in DiagramCommandId (§13).

4.6 Events (listener add/remove pairs)

The Diagram raises gestures; a mutator (or your own code) subscribes:

Add / Remove Args Fired when
…ItemDroppedListener ItemDroppedArgs { Data, Position } A palette tile drops on the canvas.
…DeleteRequestedListener DeleteRequestedArgs { Items, Connectors } Delete/Backspace with a non-empty selection.
…GroupRequestedListener GroupRequestedArgs { Items } Ctrl+G / Group command.
…UngroupRequestedListener UngroupRequestedArgs { Groups } Ctrl+Shift+G / Ungroup command.
…CombineRequestedListener CombineRequestedArgs { Items, Mode } A Combine command.
…ConnectorCreatedListener ConnectorCreatedArgs { Source, Target } A drag-create gesture completes over a target.

Normally you don’t subscribe by hand — attachStandardDiagramMutations (§11) wires all six to a DiagramMutator.

4.7 Connector selection

Connectors carry their own selection track (separate from figure selection): SelectConnector, DeselectConnector, ClearConnectorSelection, IsConnectorSelected(c), SelectConnectorRange(from, to), the SelectedConnectors getter, and Add/RemoveConnectorSelectionChangedListener.

Collaborators (internal)

The Diagram constructs several internal helpers you don’t call directly but should know exist: SelectionBoundsTracker (maintains the read-only Selection* DPs), FormatMirror (seeds/broadcasts the format DPs), SelectionReflector (ReflectSelectionToItems), and DiagramConnectorsMaterializer (mounts each Connector — plus its caps and label — into the connectors layer, keeping them in sync with the collection). Its only public surface is the MaterializedVisuals map.


5. Figure and Group

5.1 Figure

extends ContentControl. A single positioned shape: a geometry, a fill/stroke, and a text label. Default size is FIGURE_DEFAULT_SIZE (80 dp).

Property Type Default MetaData
Left number 0 Arrange, TwoWay
Top number 0 Arrange, TwoWay
Kind string '' None
Geometry PathGeometry \| undefined undefined None
Fill Brush \| undefined default fill None
Stroke Pen \| undefined per-instance clone None
Text ShapeText instance Measure
Id string \| undefined undefined None
IsSelected boolean false None
PortProvider IPortProvider \| undefined undefined None
ExplicitPorts readonly Port[] \| undefined undefined None

Sugar: LabelText (get/set) proxies Text.Content.

Factories:

Figure.fromKind(kind, left, top, options?: { width?, height? }): Figure
Figure.fromSource(source, left, top, options?: { width?, height?, kind? }): Figure

Geometry / ports:

5.2 Group

extends ContentControl. A container whose Left/Top you move as a unit; Width/Height are read-only (computed from members).

new Group(initialMembers?: readonly (Figure | Group)[])

6. Shape catalog & geometry

The catalog is the registry of built-in shape kinds (35 of them: rectangle, ellipse, squircle, arrow, diamond, heart, …). Each entry provides a unit-1 geometry (a 1×1 path) that gets scaled to the node’s size.

SHAPE_CATALOG:     readonly ShapeCatalogEntry[]          // ordered list
SHAPE_CATALOG_MAP: ReadonlyMap<string, ShapeCatalogEntry> // by kind
interface ShapeCatalogEntry { kind: string; label: string; unit(): PathGeometry }
interface NormalizedGeometry { source: PathGeometry; x: number; y: number; w: number; h: number }
interface CombinableShape { Geometry: PathGeometry | undefined; Left: number; Top: number }

Helpers:

Function Purpose
buildNodeGeometry(kind, w, h) Scale the cached unit-1 geometry of kind to w×h.
scaleGeometry(source, w, h) Point-wise scale a unit-1 geometry via a matrix.
translateGeometry(geom, dx, dy) Translate a geometry in diagram space.
normalizeToUnit(geom) Reduce an arbitrary geometry to unit-1 form + bbox/position.
mergeShapes(nodes, mode) Boolean-combine N shapes (GeometryCombineMode) into one NormalizedGeometry.

7. Text — ShapeText

Every Figure and Connector owns a ShapeText (Figure.Text, Connector.Text). It’s a Control with its own template and can carry either a plain string (Content) or a rich FlowDocument (Document).

7.1 Core DPs

Property Type Default Purpose
Content string '' Plain text.
Document FlowDocument \| undefined undefined Rich content (overrides Content when set).
HasRichContent boolean false True while a Document is displayed.
IsEditing boolean false True during in-place edit.
IsEmpty (getter) boolean — Nothing to paint.

Typography: FontSize (12), FontWeight, FontStyle, Foreground, TextAlignment (Center), TextWrapping (Wrap), Padding (Thickness(2)).

7.2 Placement & transform

The text block can sit anywhere relative to its shape and be offset, resized, and rotated:

Property Type Default Purpose
Placement TextPlacement Center One of 13 anchors — inside (Center, Top, TopLeft, …) or outside (Above, Below, LeftOf, RightOf).
Offset Point (0,0) Nudge from the anchor.
Angle number 0 Rotation in degrees (centre pivot).
BlockWidth / BlockHeight number NaN Explicit block size; NaN = auto.
VerticalTextAlignment VerticalAlignment Center Vertical align within the block.
AutoFit TextAutoFit None ShrinkText scales text to fit; GrowShape grows the shape to the text.

Helpers: isOutsideTextPlacement(p) and computeTextBlockAnchor(placement, fw, fh, bw, bh) (top-left anchor of a bw×bh block within an fw×fh footprint).

7.3 In-place editing

Inside the editor, Ctrl+B/I/U toggle bold/italic/underline.

7.4 Rich-content helpers (FlowDocument)

Serialize, clone, and convert documents:

serializeFlowDocument(doc): SerializedDoc
deserializeFlowDocument(data): FlowDocument
cloneFlowDocument(doc): FlowDocument
flowDocumentToPlainText(doc): string
flowDocumentFromPlainText(text, align?): FlowDocument
isEffectivelyPlainDocument(doc): boolean   // no formatting beyond plain string
type SerializedRun       = { t: string; b?: boolean; i?: boolean; u?: boolean; f?: FieldKind }
type SerializedParagraph = { align?: TextAlignment; runs: readonly SerializedRun[] }
type SerializedDoc       = readonly SerializedParagraph[]

Author a rich label imperatively:

ellipse.Text.Document = deserializeFlowDocument([
    { runs: [{ t: 'Pro' }, { t: 'cess', b: true }] },   // "Process" with bold "cess"
]);

7.5 Fields — live tokens

A Field is an inline element (extends Run) whose text is computed from the owning shape/connector. Because it’s a Run, the whole text pipeline treats it as text; only serialization special-cases it (the key persists, the value recomputes).

enum FieldKind { Width, Height, Left, Top, Kind, Id, Length, SourceId, TargetId }
new Field(key = FieldKind.Width, initial = '')
Helper Purpose
documentWithFields(template) Parse {Token} markers in a string into Fields (or literal runs).
resolveFields(doc, resolve) Push resolved values into every Field via a FieldResolver.
isFieldKind(s) Type guard for a known field key.
type FieldResolver = (key: FieldKind) => string | undefined
// "Decision" over its own live dimensions — updates as the shape resizes.
squircle.Text.Document = documentWithFields('Decision\n{Width}×{Height}');
// A connector label with its live route length.
edge.Text.Document = documentWithFields('flows to · {Length}px');

Figures resolve Width/Height/Left/Top/Kind/Id; connectors additionally resolve Length/SourceId/TargetId.


8. Text shapes — TextShape & Callout

Preconfigured figures whose reason for being is their text.

TextShape extends Figure — a rectangular box with a transparent (but hit-testable) fill and a light outline, AutoFit = GrowShape (the box grows to its text). No new DPs; Kind = 'text'. It drags, edits, formats, and persists like any figure.

Callout extends TextShape — adds a leader line to a target:

Property Type Default Purpose
LeaderTargetNode Figure \| undefined undefined The figure the leader points at; tracked live.

Kind = 'callout'. The leader is a self-drawn Shape injected into the figure’s template canvas, drawn from the box edge toward the target’s centre; it re-draws whenever the callout or target moves. Setting LeaderTargetNode = undefined removes the leader.

const note = new TextShape();
note.Left = 380; note.Top = 210;
note.LabelText = 'Free-floating note';
doc.Nodes.Add(note);

const callout = new Callout();
callout.Left = 40; callout.Top = 320;
callout.LabelText = 'Points at the heart ↘';
callout.LeaderTargetNode = heart;
doc.Nodes.Add(callout);

On load, kind reconstructs the class ('text' → TextShape, 'callout' → Callout), and the leader target is re-wired by node id in a second pass.


9. Connectors

9.1 Connector

extends Shape — a self-drawing routed line.

Property Type Default Purpose
Source / Target ConnectorEndpoint \| undefined undefined The two ends.
Waypoints readonly Point[] \| undefined undefined User-placed intermediate points.
RoutingMode string RoutingMode.Orthogonal Straight / Orthogonal / Bezier.
AnchorClip AnchorClip Bbox Clip anchors to bounding box or true geometry.
SourceCapTemplate / TargetCapTemplate DataTemplate \| undefined undefined Arrowhead/cap templates.
SourceCapScale / TargetCapScale number 1 Cap size multiplier.
Text (read-only) ShapeText instance The connector label.
LabelPosition number 0.5 Label position along the route (0–1).

Read-only getters: LabelInstance, SourceCapInstance / TargetCapInstance, SourceCapContext / TargetCapContext, CurrentSourceAnchor / CurrentTargetAnchor, CurrentRoutePoints (the rendered polyline). Sugar: LabelText proxies Text.Content.

Methods: DetachFromHosts(), IsPortAnchored(end), GetPortSlotIndex(end), ReorderPortSlot(end, cursor), MovePortSlotToIndex(end, index). Static: GetCapInset(v) / SetCapInset(v, value) (a cap attached property).

9.2 ConnectorEndpoint

extends Model — the address of one end: a node + port, or a free point.

new ConnectorEndpoint(init?: ConnectorEndpointInit)
interface ConnectorEndpointInit {
    Node?: Model; PortName?: string; PortSide?: PortSide;
    PortIndex?: number; FreePoint?: Point;
}

DPs mirror the init fields: Node, PortName, PortSide, PortIndex, FreePoint.

9.3 Ports

A Port (extends Model) describes an attachment point in shape-local terms.

new Port(init?: PortInit)
enum PortCoordSpace { Bbox, Outline }
enum PortSide { N, S, E, W, Auto }
type ResolvedPortSide = Exclude<PortSide, PortSide.Auto>

DPs: Name (''), CoordSpace (Bbox), X/Y (0), OutlineT (0), Side (Auto).

PortResolver (static): resolve(port, host): ResolvedAnchor lowers a port into an anchor; locate(ports, host, port) returns its positional { side, index }. Hosts implement IPortHost { ArrangedRect; Geometry? }.

9.4 Routing

enum ConnectorEnd { Source, Target }
const RoutingMode = { Straight, Orthogonal, Bezier } as const
interface ResolvedAnchor { x; y; side: ResolvedPortSide; laneOffset? }
interface RouteSpec { sourceRect; sourceAnchor; targetRect; targetAnchor; waypoints }
interface IRouter {
    compute(spec: RouteSpec): PathGeometry;
    tangentAt(spec: RouteSpec, end: ConnectorEnd): number;  // radians
}

Routers are registered in a process-wide RouterRegistry (register(name, router) / resolve(name)). Register a custom IRouter to add a routing mode.

9.5 Polyline geometry helpers

For laying things out along a route (labels, decorations):

polylineLength(points): number
pointAlongPolyline(points, t): RoutePoint          // t ∈ [0,1] by arc length
nearestTOnPolyline(points, p): number              // fraction nearest to p
interface RoutePoint { point: Point; tangent: number }   // tangent in radians

9.6 Caps

connectorCapOptions(): CapOption[] builds the standard cap dropdown (None, Arrow, Filled Arrow, Open/Filled Circle, Diamond) — bind it to a ShapeFormatControl’s CapOptions.


10. Connector behaviors

Attach these to a Diagram for interactive connector editing (they’re driven automatically when ConnectorInteractionsEnabled = true, but the classes are public if you drive them yourself).

10.1 Create

const { behavior, detach } = attachConnectorCreate(diagram);

ConnectorCreateBehavior(diagram) — a drag-create state machine. IsActive, TransientConnector (getters). BeginCreate(sourceFigure, sourceSide, cursor), UpdateCursor(cursor), EndCreate(targetFigure, targetSide) (fires ConnectorCreated), Abort().

10.2 Edit

const { adorner, detach } = attachConnectorEditAdorner();

ConnectorEditAdorner() — endpoint/waypoint/segment drag state machine. IsActive, ActiveConnector (getters). BeginEndpointDrag(connector, end, cursor), BeginWaypointDrag(connector, index), BeginSegmentDrag(connector, index), InsertWaypointAndDrag(connector, index, point), UpdateCursor(cursor), EndDragOverTarget(figure, side), EndDragOverEmpty(), Abort(), RemoveWaypoint(connector, index). Free helper: segmentIsHorizontal(a, b).


11. Mutation wiring

The Diagram never edits data; it raises events and a DiagramMutator mutates. Wire the two together once:

import { attachStandardDiagramMutations } from '@pragmatic-tech-ai/mural/framework';
const detach = attachStandardDiagramMutations(diagram, doc);   // doc is a DiagramMutator

This subscribes all six gesture events (ItemDropped, DeleteRequested, GroupRequested, UngroupRequested, CombineRequested, ConnectorCreated) to the matching mutator methods and returns a detach thunk.

interface DiagramMutator {
    Group(items): void;
    Ungroup(items): void;
    CombineSelection(items, mode): void;
    DeleteNodes(items): void;
    DeleteConnectors?(connectors): void;                       // optional
    CreateNode(kind, x, y): unknown | null | undefined;
    CreateConnector?(source, target): Connector | null | undefined;  // optional
    readonly NodeDropOffset?: { dx: number; dy: number };      // default (40, 40)
}

DiagramDocument implements this surface, so the Diagram auto-wires its Mutator from the DataContext — you often don’t call attachStandardDiagramMutations explicitly at all.

Palette drops

attachCanvasDropBehavior(receiver, diagram) attaches a drag-drop listener to receiver (a Border/ScrollViewer), translating host coordinates to canvas-local, accepting data that carries TOOLBOX_ITEM_FORMAT, and firing Diagram.ItemDropped. Returns a detach thunk. The drag payload carries the dropped item id; attach-standard-mutations looks the id up in the ToolboxRepository and calls the item’s registered IToolboxDropFactory (the shape factory delegates to mutator.CreateNode). The dropped node lands offset by NodeDropOffset (default (40, 40) — half the default node size — so the cursor maps to the node centre).

const TOOLBOX_ITEM_FORMAT = '@pragmatic-tech-ai/mural/toolbox-item';   // drag-data format key (item id)
interface ItemDroppedArgs { Data: DataObject; Position: Point }  // Position is canvas-local

Toolbox repository

The palette is a framework subsystem, resolved from Application.current.Services:


12. Persistence

interface DiagramStorage {
    GetItem(key: string): string | null;
    SetItem(key: string, value: string): void;
}
const DiagramStorageKey: ServiceKey<DiagramStorage>;   // DI token

Any localStorage/sessionStorage-compatible object satisfies DiagramStorage. Register your implementation on Application.current.Services under DiagramStorageKey, or pass one straight to the DiagramDocument constructor. Save/Load round-trip every node (position, geometry kind, fill/stroke, the full text spine — placement, transform, rich content, fields, auto-fit — and callout leader targets) and every connector (endpoints, waypoints, routing mode, label + position) under storage key mural-diagram-state-v1.


13. Enums

Enum Members
TextPlacement Center, Top, Bottom, Left, Right, TopLeft, TopRight, BottomLeft, BottomRight, Above, Below, LeftOf, RightOf
TextAutoFit None, ShrinkText, GrowShape
FieldKind Width, Height, Left, Top, Kind, Id, Length, SourceId, TargetId
AnchorClip Bbox, Geometry
PortCoordSpace Bbox, Outline
PortSide N, S, E, W, Auto
ConnectorEnd Source, Target
RoutingMode (const obj) Straight, Orthogonal, Bezier
DiagramCommandId AlignLeft/Right/Top/Middle/Center, DistributeHorizontal/Vertical, Group, Ungroup, CombineUnion/Intersect/Subtract/Exclude
DiagramLayer Connectors, Figures

Members carry explicit string values (e.g. TextPlacement.Bottom === 'bottom') so the wire form is stable. TextPlacement, TextAutoFit, FieldKind etc. are markup-facing where used in .mu.


14. Free-function index

Function Area
isOutsideTextPlacement, computeTextBlockAnchor Text placement
serializeFlowDocument, deserializeFlowDocument, cloneFlowDocument, flowDocumentToPlainText, flowDocumentFromPlainText, isEffectivelyPlainDocument Rich text
documentWithFields, resolveFields, isFieldKind Fields
buildNodeGeometry, scaleGeometry, translateGeometry, normalizeToUnit, mergeShapes Geometry
polylineLength, pointAlongPolyline, nearestTOnPolyline Route geometry
connectorCapOptions Caps
attachConnectorCreate, attachConnectorEditAdorner, segmentIsHorizontal Connector behaviors
attachStandardDiagramMutations, attachCanvasDropBehavior Mutation wiring

See also: diagram-user-manual.md for the end-user gesture and keyboard reference, and the working diagram demo for a complete wiring.