Import it from @grafloria/engine.
tsclass PortModel extends DiagramEntity
Properties
| Name | Type | Default | Description |
|---|---|---|---|
nodeId | string | '' | |
type | 'input' | 'output' | 'bi' | ||
systemType? | string | ||
position | PortPosition | ||
alignment | PortAlignment | ||
offset | Point | ||
index | number | 0 | |
maxConnections | number | ||
currentConnections | Set<string> | ||
allowedTypes | Set<string> | ||
linkRoles | Map<string, 'source' | 'target'> | Which END of each attached link this port is — linkId → 'source'|'target'. DERIVED state, rebuilt from the diagram's links by DiagramModel.reconcilePortConnections(), exactly like currentConnections. It exists because fromMaxLinks / toMaxLinks need a DIRECTIONAL count and currentConnections is a direction-blind Set of link ids. A link registered without a role (legacy `addConnection(i | |
visible | boolean | true | |
style | Record<string, any> | {} | |
data | Record<string, any> | {} | |
group? | string | Named port group. Its config is inherited; these fields override it. | |
explicitSide | boolean | false | Was the side actually declared by the author? A port that only says group: 'in' must inherit the GROUP's side — without this flag the constructor's alignment.side = 'right' default would silently win. |
shape? | PortShapeSpec | Non-circle glyph: square / diamond / triangle / custom SVG path. | |
label? | PortLabelSpec | Port label + its layout mode. | |
layout? | PortLayoutSpec | Layout strategy override. Unset → the shape registry's anchor. | |
fromSpot? | PortSpot | Where a link leaves / lands on the glyph. | |
toSpot? | PortSpot | ||
spread? | PortSpreadSpec | Spread multiple links along this port's edge instead of piling them. | |
dataType? | string | Declarative data type: drives link validity AND glyph colour. | |
isConnectableStart? | boolean | May a link START at this port? Unset → true. | |
isConnectableEnd? | boolean | May a link END at this port? Unset → true. | |
fromMaxLinks? | number | null | Cap on OUTGOING links. null/unset → unlimited. | |
toMaxLinks? | number | null | Cap on INCOMING links. null/unset → unlimited. | |
allowSelfLink? | boolean | Allow a link whose source node IS its target node. Unset → false. | |
allowDuplicateLinks? | boolean | Allow a second link between the same ordered port pair. Unset → true. | |
dynamic? | boolean | Spawned by the dynamic auto-port allocator rather than authored. | |
renderingConfig? | any | ||
isHovered | boolean | false | Whether mouse is currently hovering over this port Used for visual feedback (scaling, highlighting) |
isHighlighted | boolean | false | Whether this port is highlighted as a valid connection target Set during connection drag operations |
isValidTarget | boolean | false | Whether this port is a valid target for current connection Set by ConnectionStateManager during drag |
Methods
constructor(config: { id?: string; type: 'input' | 'output' | 'bi'; systemType?: string; position?: PortPosition; alignment?: PortAlignment; side?: 'left' | 'right' | 'top' | 'bottom'; // NEW: Convenience parameter index?: number; // NEW: For multiple ports per side maxConnections?: number; // --- Wave 6 (all optional; unset === pre-wave-6 behaviour) ------------- group?: string; shape?: PortShapeSpec; label?: PortLabelSpec; layout?: PortLayoutSpec; fromSpot?: PortSpot; toSpot?: PortSpot; spread?: PortSpreadSpec; style?: Recor …get side(): 'left' | 'right' | 'top' | 'bottom'— Get the side this port is on (convenience getter) Set the side this port is on (convenience setter)set side(value: 'left' | 'right' | 'top' | 'bottom')— Get the side this port is on (convenience getter) Set the side this port is on (convenience setter)setPosition(position: PortPosition): void— Set positionsetAlignment(alignment: PortAlignment): void— Set alignmentsetOffset(offset: Point): void— Set offsetaddAllowedType(type: string): void— Add allowed typeremoveAllowedType(type: string): void— Remove allowed typeisTypeAllowed(type: string): boolean— Check if type is allowedaddConnection(linkId: string, role?: 'source' | 'target'): void— Add connectionrestoreConnection(linkId: string, role?: 'source' | 'target'): void— Load-time reconcile: register a connection WITHOUT the maxConnections guard or change tracking. The connection registry is derived state that is rebuilt deterministically from the diagram's links on load — a persisted graph may legitimately exceed a since-tightened maxConnections, so enforcement applies to NEW interactive connections (addConnection), never to reloading saved state.removeConnection(linkId: string): void— Remove connectioncanConnect(): boolean— Check if can accept more connectionsgetConnectionCount(): number— Get connection countgetFromLinkCount(): number— How many links LEAVE this port / how many ARRIVE at it.
A self-loop that both starts and ends here registers once in
currentConnections (the Set dedupes) but linkRoles can only hold one
role for it, so it is counted on whichever end was registered last. That is
acceptable — a port that allows self-links and also caps its directional
fan-out is pathological, and the TOTAL maxConnections cap still holds.
getToLinkCount(): numbercanConnectTo(targetPort: PortModel): boolean— Check if this port (as the SOURCE) can connect totargetPort(as the TARGET). Direction matters — this is not a symmetric predicate.
Rules:
- input can connect to output or bi
- output can connect to input or bi
- bi can connect to any
isConnectableStart on
the source, isConnectableEnd on the target, the per-direction
fromMaxLinks/toMaxLinks caps, the allowedTypes whitelist (which was
dead config — isTypeAllowed had no caller anywhere in the tree) and
dataType compatibility.
NOTE: this is the PORT-LOCAL rule. Rules that need the graph (self-links,
duplicate links, connection groups) live in evaluatePortConnection(),
which folds this in.
typeIdentity(): string— The name this port answers to when another port'sallowedTypeswhitelist is checked: its declared data type, else its systemType, else its direction.getAbsolutePosition(nodeBounds: BoundingBox): Point— Get absolute position relative to nodegetEdgePosition(nodeBounds: BoundingBox): Point— Get port position at node edge (for smart mode) Returns the position at the edge midpoint based on alignmentstatic findNearestPort( point: Point, ports: Map<string, PortModel>, nodeBounds: BoundingBox ): PortModel | null(static) — Find nearest port on a node to a given point Used in smart mode for auto-connect to nearest portgetDistanceFromPoint(point: Point, nodeBounds: BoundingBox): number— Calculate distance from point to this portresetInteractionState(): void— Reset interaction state Called when connection drag ends or is cancelledsetRenderingConfig(config: any): void— Set port rendering configuration from templategetRenderingConfig(): any | undefined— Get port rendering configurationgetEffectiveVisibility( node: any, globalDefault?: 'always' | 'on-hover' | 'never' | 'hidden' ): 'always' | 'on-hover' | 'never' | 'hidden'— Get effective visibility considering port and node configuration Priority: port config > node metadata > default ('on-hover')serialize(): SerializedPort— Serialize to JSONstatic fromJSON(data: SerializedPort): PortModel(static) — Deserialize from JSON
Was this page helpful?