GroupAnnotation class

A group annotation that creates a region for containing nodes.

Group annotations create visual boundaries that can contain nodes. The membership and sizing behavior is determined by behavior:

  • GroupBehavior.bounds: Spatial containment - nodes inside bounds move with group. Group is manually resizable. Nodes can escape by dragging out.

  • GroupBehavior.explicit: Explicit membership - nodes are specified by ID. Group auto-sizes to fit member nodes + padding. Not resizable.

  • GroupBehavior.parent: Parent-child link - nodes specified by ID move with group when dragged. Group is manually resizable. Nodes can be positioned outside group bounds.

Features

  • Manual resizing from 8 handle positions (except for explicit behavior)
  • Customizable title and color
  • When moved, automatically moves contained/linked nodes
  • Typically rendered behind nodes (negative z-index)

Example

// Bounds behavior (default) - spatial containment
final regionGroup = GroupAnnotation(
  id: 'region-1',
  position: Offset(100, 100),
  size: Size(400, 300),
  title: 'Processing Region',
);

// Explicit behavior - auto-sized to fit members
final explicitGroup = GroupAnnotation(
  id: 'explicit-1',
  position: Offset.zero, // Will be computed
  size: Size.zero,       // Will be computed
  title: 'Data Pipeline',
  behavior: GroupBehavior.explicit,
  nodeIds: {'node-1', 'node-2', 'node-3'},
  // Default padding: 40 top (for title), 20 sides and bottom
);
explicitGroup.fitToNodes((id) => controller.nodes[id]);

// Parent behavior - linked nodes, manual size
final parentGroup = GroupAnnotation(
  id: 'parent-1',
  position: Offset(50, 50),
  size: Size(500, 400),
  title: 'Workflow Stage',
  behavior: GroupBehavior.parent,
  nodeIds: {'node-a', 'node-b'},
);
Inheritance

Constructors

GroupAnnotation({required String id, required Offset position, required Size size, required String title, Color color = Colors.blue, GroupBehavior behavior = GroupBehavior.bounds, Set<String>? nodeIds, EdgeInsets padding = defaultPadding, int zIndex = -1, bool isVisible = true, bool selected = false, bool isInteractive = true, Map<String, dynamic> metadata = const {}})
GroupAnnotation.fromJsonMap(Map<String, dynamic> json)
factory

Properties

behavior GroupBehavior
The behavior that determines how this group manages node membership.
no setter
bounds Rect
Gets the bounding rectangle for the group in graph coordinates.
no setteroverride
currentColor Color
The current color value (non-reactive).
no setter
currentTitle String
The current title value (non-reactive).
no setter
hashCode int
The hash code for this object.
no setterinherited
id String
Unique identifier for this annotation.
finalinherited
isEmpty bool
Whether this annotation is considered "empty" and has no content.
no setteroverride
isInteractive bool
Whether this annotation responds to user interactions.
finalinherited
isResizable bool
Whether this group can be manually resized.
no setter
isVisible bool
Whether the annotation is visible.
getter/setter pairinherited
layer AnnotationRenderLayer
The rendering layer for this annotation.
no setteroverride
metadata Map<String, dynamic>
Additional metadata for custom data storage.
finalinherited
monitoredNodeIds Set<String>
The set of node IDs that this annotation monitors for position/size changes.
no setteroverride
monitorNodes bool
Whether this annotation should receive automatic node lifecycle callbacks.
no setteroverride
nodeIds Set<String>
The set of explicitly linked node IDs.
no setter
observableBehavior → Observable<GroupBehavior>
Reactive observable for the group's behavior.
no setter
observableColor → Observable<Color>
Reactive observable for the group's color.
no setter
observableSize → Observable<Size>
Reactive observable for the group's size.
no setter
observableTitle → Observable<String>
Reactive observable for the group's title.
no setter
padding EdgeInsets
Padding around member nodes when computing bounds for GroupBehavior.explicit.
final
position Offset
The annotation's logical position (before grid snapping).
getter/setter pairinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
selected bool
Whether the annotation is currently selected.
getter/setter pairinherited
shouldRemoveWhenEmpty bool
Whether this annotation should be automatically removed when empty.
no setteroverride
size Size
The dimensions of the annotation for automatic hit testing.
no setteroverride
type String
The type of annotation (e.g., 'sticky', 'group', 'marker').
finalinherited
visualPosition Offset
The annotation's visual position (after grid snapping).
getter/setter pairinherited
zIndex int
The annotation's z-index (rendering order within its layer).
getter/setter pairinherited

Methods

addNode(String nodeId) → void
Adds a node to the explicit membership.
buildWidget(BuildContext context) Widget
Builds the visual representation of the annotation.
override
clearNodes() → void
Clears all explicitly linked nodes.
containsPoint(Offset point) bool
Automatic hit testing based on position and size.
inherited
containsRect(Rect rect) bool
Checks if a given rectangle is completely contained within this group.
copyWith({String? id, Offset? position, Size? size, String? title, Color? color, GroupBehavior? behavior, Set<String>? nodeIds, EdgeInsets? padding, int? zIndex, bool? isVisible, bool? isInteractive, Map<String, dynamic>? metadata}) GroupAnnotation
Creates a copy of this group annotation with optional property overrides.
fitToNodes(NodeLookup lookup) → void
Recomputes the group's position and size to fit all member nodes.
fromJson(Map<String, dynamic> json) → void
Deserializes JSON data into this annotation.
override
hasNode(String nodeId) bool
Checks if a node is an explicit member of this group.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onDragEnd() → void
Called when a drag operation ends on this annotation.
override
onDragMove(Offset delta, AnnotationDragContext context) → void
Called during drag with the movement delta.
override
onDragStart(AnnotationDragContext context) → void
Called when a drag operation starts on this annotation.
override
onNodeAdded(String nodeId, Rect nodeBounds, AnnotationDragContext context) bool
Called when a new node is added to the graph.
inherited
onNodeMoved(String nodeId, Offset newPosition, AnnotationDragContext context) → void
Called when a node's position changes.
override
onNodeResized(String nodeId, Size newSize, AnnotationDragContext context) → void
Called when a node's size changes.
override
onNodesDeleted(Set<String> nodeIds, AnnotationDragContext context) → void
Called when nodes are deleted from the graph.
override
onNodeVisibilityChanged(String nodeId, bool isVisible) → void
Called when a node's visibility changes.
inherited
onSelectionChanged(Set<String> selectedNodeIds) → void
Called when the node selection changes.
inherited
removeNode(String nodeId) → void
Removes a node from the explicit membership.
setBehavior(GroupBehavior newBehavior, {Set<String>? captureContainedNodes, NodeLookup? nodeLookup, bool clearNodesOnBoundsSwitch = true}) → void
Changes the group's behavior.
setSize(Size newSize) → void
Sets the group's size directly.
toJson() Map<String, dynamic>
Serializes this annotation to JSON.
override
toString() String
A string representation of this object.
inherited
updateColor(Color newColor) → void
Updates the group's color.
updateTitle(String newTitle) → void
Updates the group's title.

Operators

operator ==(Object other) bool
The equality operator.
inherited

Constants

defaultPadding → const EdgeInsets
Creates a GroupAnnotation from a JSON map.