Skip to content
D
Documentation

GroupModel

reference
4 min readUpdated

Import it from @grafloria/engine.

Also has every member of DiagramEntity, listed on its own entry.

ts
class GroupModel extends DiagramEntity

Properties

NameTypeDefaultDescription
namestring
membersSet<string>
isCollapsedbooleanfalse
bounds?{ x: number; y: number; width: number; height: number }
layoutTypeLayoutType'none'
layoutConfig?LayoutConfig
position{ x: number; y: number }
size?{ width: number; height: number; depth: number }
parentGroupId?string
memberValidation?MemberValidation
isHoveredbooleanfalse
padding?GroupPadding
headerHeight
zIndex0
fitModeGroupFitMode'exact'
constrainChildrenfalse
collapsedState?CollapsedState
subgraphLayout?SubgraphGroupConfig
laneConfig?LaneConfig
membershipRule?MembershipRule
capacity?number

Methods

  • constructor(config: { id?: string; name: string })
  • canAddMember(candidateId: string, diagram?: DiagramModel): boolean — Whether candidateId may legally join this group. Rejects self-membership, ancestor cycles (adding an ancestor group as a member would create a containment loop), and candidates failing the per-group memberValidation predicate. Node candidates only run the predicate check (nodes can't form group cycles).
  • getWipState(): { count: number; capacity?: number; state: 'unlimited' | 'under' | 'full' | 'over' } — WIP state for the capacity limit. 'under' = room to spare, 'full' = exactly at the limit (the visual warning threshold), 'over' = past it (only reachable by lowering capacity below the current count). Returns 'unlimited' when no capacity is set.
  • isOverCapacity(): boolean — True when at or beyond the capacity limit (warning state).
  • setCapacity(capacity: number | undefined): void — Set (or clear) the capacity / WIP limit, tracked for undo/diff.
  • addMember(entityId: string, diagram?: DiagramModel): void — Add member to group.
  • ownsItsFrame(): boolean — Whether a joining member may grow this group's frame. Frames that something else owns are left alone: a collapsed group, a layout container (setLayout), a swimlane or pool (laneConfig), a group that confines its members (constrainChildren: its frame is the extent they are kept inside), and a group drawn without a frame (metadata.frameChrome === 'none', as dashboard boards are).
  • removeMember(entityId: string, diagram?: DiagramModel): boolean — Remove member from group. When the member is a group whose parent is this group, its parentGroupId back-pointer is cleared so the nesting tree stays consistent.
  • setParent(newParentId: string | undefined, diagram?: DiagramModel): boolean — Reparent this group under newParentId (or detach when undefined), keeping both the parentGroupId pointer and the parents' members sets consistent. Rejects cycles (a group cannot be nested under one of its own descendants) and returns false without mutating anything.
  • setHovered(hovered: boolean): void — Set transient drag-hover highlight state and notify listeners. Renderers/canvas can subscribe to 'hover
    ' to outline a drop target.
  • expand(): void — Expand the group
  • collapse(): void — Collapse the group
  • setCollapsedState(state: CollapsedState | undefined): void — Set (or clear) the reversible collapse snapshot. Tracked as a change so the incremental diff-capture serializes it and undo/redo see it.
  • setLayout(type: 'flexbox', config: FlexboxLayoutConfig): void — Set layout configuration
  • setLayout(type: 'grid', config: GridLayoutConfig): void — Set layout configuration
  • setLayout(type: 'flexbox' | 'grid', config: LayoutConfig): void — Set layout configuration
  • clearLayout(): void — Clear layout configuration
  • getLayout(): { type: LayoutType; config?: LayoutConfig } — Get layout configuration
  • hasLayout(): boolean — Check if group has layout configured
  • getFlexboxLayout(): FlexboxLayoutConfig — Get layout as flexbox config
  • getGridLayout(): GridLayoutConfig — Get layout as grid config
  • calculateBounds(diagram: DiagramModel): void — Calculate bounds from member nodes using global bounds
  • getPadding(): { top: number; right: number; bottom: number; left: number } — Resolve {@link padding} to a full four-sided rectangle. undefined (the author never said) resolves to {@link DEFAULT_GROUP_PADDING}; an explicit value — including the 0 that loaders pin for legacy documents — is taken as written.
  • getOuterBounds(): GroupRect — The group's outer frame rectangle in world coordinates. Prefers explicit geometry (position + size) and falls back to the derived member bounds, matching how GroupMembershipService hit-tests a group.
  • getInnerBounds(): GroupRect — The rectangle members must stay inside: the outer frame minus padding and minus the header band (which is reserved at the top). Never returns a negative width/height.
  • fitToContents(diagram?: DiagramModel, options?: FitToContentsOptions): void — Auto-fit the group frame to its members' bounding box plus padding and the header band. This is the real consumer of padding/headerHeight that calculateBounds (a tight, padding-free box) never was.
  • growToFitMembers(diagram?: DiagramModel): boolean — Grow the frame just enough to take in every member, plus padding and the header band, without ever shrinking it. A group with no frame yet gets one fitted around its members. Writes nothing when the members already fit, so an unchanged frame records no change.
  • setFrame(rect: GroupRect): void — Write a world rectangle into the group's authoritative geometry (position + size) and the derived hit-test bounds, keeping the existing depth when present. Tracks a single 'bounds' change for undo/diff.
  • clampChildToExtent(nodeId: string, diagram?: DiagramModel): boolean — Clamp a member node so it stays fully inside the group's inner extent. No-op unless constrainChildren is set and the node is a direct member. Returns true when the node was actually moved. Absolute-coordinate model: this adjusts the node's world position directly.
  • restoreGeometry(geo: { position: { x: number; y: number }; size?: { width: number; height: number; depth: number }; bounds?: GroupRect; }): void — Restore raw geometry (position + optional size + bounds) captured before a collapse. Unlike setFrame this permits size === undefined so a group that had no explicit frame is restored to exactly that.
  • setZIndex(z: number): void — Set the group's stacking index (lower renders further back).
  • bringToFront(diagram?: DiagramModel): void — Bring this group in front of every other group (highest zIndex + 1). Minimal z-order API — the renderer honors zIndex ordering.
  • sendToBack(diagram?: DiagramModel): void — Send this group behind every other group (lowest zIndex - 1).
  • isAutoLayoutEnabled(): boolean — Is push-driven reflow active for this container?
  • requestLayout(diagram?: DiagramModel): void — THE push entry point: "something changed, reflow if you are supposed to." Distinct from {@link applyLayout}, which is the unconditional PULL — an explicit applyLayout() still works on an opted-out container.
  • applyLayout(diagram?: DiagramModel): void — Apply layout to member nodes Positions child nodes based on flex or grid layout configuration
  • serialize(): SerializedGroup — Serialize to JSON
  • static fromJSON(data: SerializedGroup): GroupModel (static) — Deserialize from JSON

Was this page helpful?

GroupModel — Grafloria