Create and connect atomically
Loading interactive example…Open in new tab ↗
controller.createConnected inserts the target and incoming connector in one admitted operation. The target can be a registered shape or standalone text. Both use the same connection geometry and history pipeline.
Try each creation button, then Undo: the target and connector disappear together. Redo restores both identities and the binding. Try invalid port requests a nonexistent port; the example reports the error and leaves the drawing unchanged. Use Fit after adding several targets to bring the expanded drawing into view.
The direct method returns the new ID. Its counterpart through controller.edits returns an EditResult whose id is the new connector's ID; the inline element keeps its supplied ID. A denied request, such as an invalid port, returns a denied result. Connection policy and document admission apply. Like add, authored insertion preserves supplied values rather than invoking the defaults factory.
Source
dart
String addConnectedTarget(
DiagramController controller, {
bool text = false,
bool invalidPort = false,
}) {
final revision = controller.document.revision;
final row = (controller.document.elements.length - 1) ~/ 2;
final decision = controller.edits.createConnected(
source: const BoundEndpoint(elementId: 'source'),
element: text
? TextElement(
id: 'target-$revision',
frame: DiagramRect.fromLTWH(260, row * 140 - 50, 200, 100),
textStory: TextStory.paragraph(
id: 'target-story-$revision',
blockId: 'target-block-$revision',
text: 'Text connects too',
),
)
: ShapeElement(
id: 'target-$revision',
type: Shapes.rectangle,
frame: DiagramRect.fromLTWH(260, row * 140 - 50, 200, 100),
textStory: TextStory.paragraph(
id: 'target-story-$revision',
blockId: 'target-block-$revision',
text: 'A connected idea',
),
),
toPort: invalidPort ? 'missing-port' : null,
route: ConnectorRoutes.quadratic,
)..requireAllowed();
return decision.id!;
}See Shapes for the complete argument contract.