Connectors and labels
Connect and label shapes
dart
final connectionId = session.store.connections.create(
ConnectorElement(
id: 'review-to-approval',
start: BoundEndpoint(elementId: sourceId, portId: 'output'),
end: BoundEndpoint(elementId: targetId, portId: 'input'),
router: DiagramRouterKind.bezier,
),
);
session.store.connections.reconnect(
connectionId,
atStart: false,
endpoint: BoundEndpoint(elementId: anotherTargetId, portId: 'input'),
);
final labelId = session.store.connectorLabels.add(
connectionId,
fraction: 0.5,
);The example assumes those IDs and ports exist. Omit portId for a shape anchor or use FreeEndpoint for an unbound endpoint. Connection commands apply the session's connection policy; reconnection retains the other connection properties. Routing supports straight, elbow (orthogonal), quadratic and cubic Bezier paths.
Labels are attachments owned by the connector. Their fraction ranges from 0 to 1 along resolved path length; they also have offset, size and a shared text story. The label service supports update, selection and removal. The registry's connector labeling capability controls availability and maximum count.
ConnectorLabelingCapability
The default connector label is plain inline text, centered on its path anchor. It grows horizontally to fit one line and has no resize handles.
| Property | Default | Contract |
|---|---|---|
maximumLabels | 2 | Maximum attachments on a connector. |
defaultFontSize | 14 | Inherited label text size in logical pixels; explicit run sizes take precedence. |
singleLine | true | One paragraph with inline formatting; Enter exits editing. |
resizable | false | No resize handles or resize commands by default. |
movable | true | Dragging projects the label onto the visible path, between fractions 0 and 1. |
textEditable | true | Double-click creates or edits a label. |
deletable | true | A selected label can be removed independently. |
defaultSize | DiagramSize(120, 32) | Initial minimum box; single-line text expands its resolved width as needed. |
minimumSize | DiagramSize(24, 16) | Admission limit for authored label geometry. |
Select a connector and press Enter to edit its first label and select all its text. If it has no labels, Enter creates one at the midpoint. Double-clicking the path uses the same entry behavior; it reuses the first stored label instead of adding duplicates. Double-clicking a specific label edits that attachment and retains paragraph word-selection gestures.
These interactions are built into the connector labeling capability. Locked connectors, disabled labeling, or textEditable: false prevent entry. Merely entering an existing label creates no document/history change. Enter within the default single-line editor exits it. Clearing text removes visible ink and the idle hit box; reactivation can reopen the existing empty attachment. Use connectorLabels.add explicitly for additional labels, up to the configured limit. Hosts can opt into multiline or resizable labels through a custom capability.
The default inherited font size is 14 px, shared by measurement, painting, caret geometry, the inspector and size shortcuts. Explicit DiagramTextRun.fontSize values are preserved. Set ConnectorLabelingCapability(defaultFontSize: ...) to customize the inherited size for a registry.
Style one label
Select a label to show Connector label in the inspector. Its font size, text color and inline marks affect that attachment only. The connector stroke and other labels keep their own styles. Plain labels expose text properties; choosing Badge also exposes fill, border color/style/width, radius and padding. Single-line labels do not show list or paragraph-alignment controls.
Text styling uses the shared DiagramTextRun fields (fontSize, color, fontFamily, marks), not a separate label-only text model. For example:
dart
session.store.connectorLabels.update(
connectionId,
labelId,
story: DiagramTextStory(
id: existingStory.id,
blocks: [
for (final block in existingStory.blocks)
block.copyWith(runs: [
for (final run in block.runs)
run.copyWith(fontSize: 20, color: const DiagramColor(0xff2454d8)),
]),
],
),
presentation: const DiagramBadgeLabelPresentation(
fill: DiagramColor(0xffffffff),
stroke: DiagramColor(0xff2454d8),
strokeWidth: 2,
cornerRadius: 8,
padding: 6,
),
);existingStory is the selected attachment's current story. Preserve its IDs and other run properties when restyling. A text change and presentation change in the same call publish and undo together.
connectorLabels.update
dart
void update(
String connectorId,
String labelId, {
DiagramTextStory? story,
double? fraction,
DiagramPoint? offset,
DiagramSize? size,
DiagramLabelPresentation? presentation,
})| Argument | Contract |
|---|---|
connectorId, labelId | Required positional identities. Missing or locked targets reject the operation. |
story | Shared paragraph/run content. Requires text editing capability. |
fraction | Position along resolved path length, from 0 to 1; requires movement capability. |
offset | World-space displacement from the path anchor; requires movement capability. |
size | Authored label size; requires resize capability, disabled by default. |
presentation | Plain text or badge surface. Omitted fields preserve their current values. |
All named arguments default to null, meaning unchanged. The method returns void; invalid values, missing capabilities or targets throw. Host admission denial throws DiagramChangeDenied. No partial update occurs.
DiagramLabelPresentation
| Production | Contract |
|---|---|
const DiagramPlainLabelPresentation() | Text only. No fill, border, radius or padding properties. |
const DiagramBadgeLabelPresentation(...) | Rounded backing surface with the fields below. |
| Badge property | Type | Default |
|---|---|---|
fill | DiagramColor | 0xffffffff (white). Use transparent for a border-only badge. |
stroke | DiagramColor | 0xff94a3b8 (muted slate). |
strokeWidth | double | 0 (no border). |
strokeStyle | DiagramStrokeStyle | solid; also supports dashed and dotted. |
cornerRadius | double | 4. |
padding | double | 4. |
Dimensions must be finite and nonnegative. Padding must leave a valid text interior. copyWith returns a new badge value; equality includes every field. Border geometry is centered on the backing surface. Resolved visualBounds include its half-width bleed for hit testing, selection and scene bounds; text layout continues to use the padded interior. A visible badge fill or border reserves its area from path effects so particles cannot paint over it.
These styles are saved in JSON version 14 and rendered by the shared canvas/PNG painter. Earlier versions migrate with no border, preserving their appearance.