Documentation
¶
Overview ¶
Package flowgraph provides graph layout algorithms for flow nodes. It supports both horizontal (left-to-right) and vertical (top-to-bottom) layouts using BFS-based level assignment.
Index ¶
- Constants
- func ApplyLayout(nodes []mflow.Node, result *LayoutResult)
- func ApplyLayoutToNodePtrs(nodeMap map[idwrap.IDWrap]*mflow.Node, result *LayoutResult)
- func ApplyTransitiveReduction(edges []mflow.Edge, maxEdges int) []mflow.Edge
- func BuildIncomingAdjacency(edges []mflow.Edge) map[idwrap.IDWrap][]idwrap.IDWrap
- func BuildNodeMap(nodes []mflow.Node) map[idwrap.IDWrap]*mflow.Node
- func BuildOutgoingAdjacency(edges []mflow.Edge) map[idwrap.IDWrap][]idwrap.IDWrap
- func ConnectOrphans(nodes []mflow.Node, edges []mflow.Edge, flowID, startNodeID idwrap.IDWrap) []mflow.Edge
- func EdgeExists(edges []mflow.Edge, source, target idwrap.IDWrap) bool
- func FindStartNode(nodes []mflow.Node) (*mflow.Node, bool)
- func HasAlternativePath(adjMap map[idwrap.IDWrap][]idwrap.IDWrap, source, target idwrap.IDWrap) bool
- func LayoutNodes(nodes []mflow.Node, edges []mflow.Edge, config LayoutConfig) error
- func LinearizeNodes(startNodeID idwrap.IDWrap, allNodes []mflow.Node, edges []mflow.Edge) []mflow.Node
- type LayoutConfig
- type LayoutOrientation
- type LayoutResult
- type Position
Constants ¶
const DefaultMaxEdgesForReduction = 2000
DefaultMaxEdgesForReduction is the default threshold for skipping transitive reduction. Graphs with more edges than this will not be reduced (performance optimization).
Variables ¶
This section is empty.
Functions ¶
func ApplyLayout ¶
func ApplyLayout(nodes []mflow.Node, result *LayoutResult)
ApplyLayout applies the layout result to a slice of nodes.
func ApplyLayoutToNodePtrs ¶
func ApplyLayoutToNodePtrs(nodeMap map[idwrap.IDWrap]*mflow.Node, result *LayoutResult)
ApplyLayoutToNodePtrs applies the layout result to a map of node pointers.
func ApplyTransitiveReduction ¶
ApplyTransitiveReduction removes redundant edges from the graph. An edge A->C is redundant if there exists a path A->...->C via other edges.
If maxEdges is > 0 and len(edges) > maxEdges, the reduction is skipped for performance. Pass 0 to use DefaultMaxEdgesForReduction.
func BuildIncomingAdjacency ¶
BuildIncomingAdjacency builds a map of node ID -> list of source node IDs.
func BuildNodeMap ¶
BuildNodeMap creates a map of node ID -> node pointer for quick lookup.
func BuildOutgoingAdjacency ¶
BuildOutgoingAdjacency builds a map of node ID -> list of target node IDs.
func ConnectOrphans ¶
func ConnectOrphans(nodes []mflow.Node, edges []mflow.Edge, flowID, startNodeID idwrap.IDWrap) []mflow.Edge
ConnectOrphans creates edges from startNode to all nodes with no incoming edges. This ensures all nodes are reachable from the start node.
func EdgeExists ¶
EdgeExists checks if an edge exists between source and target.
func FindStartNode ¶
FindStartNode finds the start node (NODE_KIND_MANUAL_START or NODE_KIND_SUB_FLOW_TRIGGER) in a node slice.
func HasAlternativePath ¶
func HasAlternativePath(adjMap map[idwrap.IDWrap][]idwrap.IDWrap, source, target idwrap.IDWrap) bool
HasAlternativePath checks if there's a path from source to target that doesn't use the direct edge (i.e., goes through other nodes).
func LayoutNodes ¶
LayoutNodes is a convenience function that performs layout and applies positions. It returns an error if the start node is not found.
func LinearizeNodes ¶
func LinearizeNodes(startNodeID idwrap.IDWrap, allNodes []mflow.Node, edges []mflow.Edge) []mflow.Node
LinearizeNodes returns nodes in BFS traversal order (for YAML export). Neighbors are sorted alphabetically by name for deterministic ordering. Disconnected nodes are appended at the end, also sorted alphabetically.
Types ¶
type LayoutConfig ¶
type LayoutConfig struct {
// Orientation controls whether depth maps to X (horizontal) or Y (vertical).
Orientation LayoutOrientation
// SpacingPrimary is spacing along the primary axis (direction of flow).
SpacingPrimary float64
// SpacingSecondary is spacing perpendicular to flow (for parallel nodes).
SpacingSecondary float64
// StartX is the starting X position.
StartX float64
// StartY is the starting Y position.
StartY float64
}
LayoutConfig configures the layout algorithm.
func DefaultHorizontalConfig ¶
func DefaultHorizontalConfig() LayoutConfig
DefaultHorizontalConfig returns the default configuration for horizontal layout. This matches the harv2 layout: nodes flow left-to-right with vertical stacking.
func DefaultVerticalConfig ¶
func DefaultVerticalConfig() LayoutConfig
DefaultVerticalConfig returns the default configuration for vertical layout. This matches the ioworkspace layout: nodes flow top-to-bottom with horizontal stacking.
type LayoutOrientation ¶
type LayoutOrientation int
LayoutOrientation defines the primary direction of flow.
const ( // LayoutHorizontal: nodes flow left-to-right (X increases with depth). // Used by HAR import (harv2). LayoutHorizontal LayoutOrientation = iota // LayoutVertical: nodes flow top-to-bottom (Y increases with depth). // Used by YAML import (ioworkspace). LayoutVertical )
type LayoutResult ¶
type LayoutResult struct {
// Positions maps node IDs to their computed positions.
Positions map[idwrap.IDWrap]Position
// Levels maps node IDs to their depth level (0 = start node).
Levels map[idwrap.IDWrap]int
// MaxLevel is the deepest level in the graph.
MaxLevel int
}
LayoutResult contains the computed positions for each node.