Vyuh Node Flow

repository·main·Indexed 41 days ago

https://github.com/vyuh-tech/vyuh_node_flow

A high-performance node-based flow editor for Flutter applications inspired by React Flow. It provides a framework for building interactive UIs with support for complex connections, animations, and custom themes. Key components include NodeFlowController for state management, NodeFlowEditor for rendering, and NodeFlowTheme for visual customization. The library supports advanced features like Level of Detail (LOD) rendering, minimaps, and connection validation.

Tokens
131.1K
Snippets
344
Records
441
Agent score
50%

What's inside Vyuh Node Flow

  1. Overview of Vyuh Node Flow features

    main

    Vyuh Node Flow is a high-performance, reactive node-based flow editor for Flutter, inspired by React Flow. It is built using MobX for reactive rendering and supports several advanced features:

    • Rendering & Performance: High-performance reactive rendering with MobX and Level of Detail (LOD) for automatic visual simplification during zooming.
    • Node & Port System: Type-safe node data using generics, a flexible port system with multiple shapes/positions, and fully customizable themes.
    • Connections: Multiple connection styles (bezier, smoothstep, straight, step) with customizable endpoints and animation effects (flowing dashes, particles, gradients, pulse).
    • Navigation & UI: AutoPan near viewport edges, viewport animations, a built-in minimap, and comprehensive keyboard shortcuts.
    • Workflow Tools: Annotations (sticky notes, markers, groups), read-only viewer mode, and JSON serialization for saving/loading flows.
    • Extensibility: An extension architecture for modular, pluggable features.
  2. Overview of NodeFlowEditor capabilities

    main

    The NodeFlowEditor is a comprehensive widget for building interactive node-based flow editors. It includes built-in support for:

    • Canvas & Viewport: Infinite canvas, pan & zoom, zoom-to-fit, animated viewport, grid background (with snap-to-grid), and a minimap.
    • Nodes: Custom node widgets via nodeBuilder, multiple shapes (rectangle, circle, diamond, hexagon), drag & drop, multi-selection, resizing, and Z-index layering.
    • Ports: Custom port widgets, multiple positions (left, right, top, bottom), various port types (source, target, bidirectional), and multi-connection support.
    • Connections: Interactive creation, multiple line styles (Bezier, smoothstep, step, straight), configurable arrows/endpoints, and connection validation hooks.
    • Annotations: Sticky notes, visual groups, markers, and node-following annotations.
    • Interaction: Keyboard shortcuts, context menus, auto-pan, and cursor feedback.
    • Alignment & Distribution: Tools to align nodes (left, right, top, bottom, center) and distribute them evenly.
    • Serialization: Full graph export/import to JSON, including custom data and annotations.
    • Theming: Comprehensive styling for nodes, connections, ports, annotations, labels, and the grid.
  3. How Level of Detail (LOD) works

    main

    The Level of Detail (LOD) system optimizes performance and reduces visual clutter by adjusting which visual elements are rendered based on the current normalized zoom (0.0 to 1.0) or the number of nodes in the viewport.

    Adaptive Rendering Modes

    When LOD is enabled, the system can switch from rendering individual widgets to a batched overview painter when:

    1. The normalized zoom falls below minThreshold.
    2. The number of nodes intersecting the viewport exceeds maxInteractiveNodes.

    Visual Transitions

    • Overview Mode: Nodes are rendered via a thumbnail painter rather than full widgets. Connections use simplified geometry (straight paths, no labels/endpoints) and are painted in batches. Nodes remain selectable, tappable, and draggable via spatial hit-testing. The node currently being interacted with (dragged/resized) is promoted to a real widget to maintain interaction fidelity.
    • Full Detail Mode: All elements (ports, labels, resize handles, etc.) are rendered as full widgets.

    Performance Benefits

    • Batched node rendering: Reduces widget tree complexity.
    • Simplified connection geometry: Skips routers and path-cache lookups.
    • Batched static edges: Groups connections with identical color/stroke to avoid rasterization bottlenecks.
    • Smaller reactive surface: Coalesces visibility queries and prevents unnecessary invalidations.
    // LOD uses normalized zoom (0.0 to 1.0) based on your min/max zoom configuration
    // Below 3%   -> minimal
    // 3% to 10%  -> standard
    // Above 10%  -> full
  4. Use NodeFlowViewer for read-only graph displays

    main

    The NodeFlowViewer is a specialized widget designed for displaying node flow graphs in a read-only mode. It is a wrapper around NodeFlowEditor using NodeFlowBehavior.preview, which enables navigation (panning, zooming, selecting, and dragging nodes) while strictly preventing structural changes like creating, updating, or deleting nodes and connections.

    Common Use Cases

    • Debug views: Visualizing workflow state during execution.
    • Previews: Displaying graph thumbnails with limited interaction.
    • Reports: Embedding flow visualizations in read-only contexts.
    • History views: Showing saved graph versions without allowing edits.
  5. Configure Port position and type inference

    main

    Ports are placed on the edges of a node using PortPosition. If you do not explicitly set a PortType, the type is automatically inferred from the position:

    • PortPosition.left or PortPosition.top $\rightarrow$ PortType.input (receives connections)
    • PortPosition.right or PortPosition.bottom $\rightarrow$ PortType.output (emits connections)

    Available positions:

    • PortPosition.left (default)
    • PortPosition.right
    • PortPosition.top
    • PortPosition.bottom
  6. How keyboard shortcuts work in NodeFlowEditor

    main

    Keyboard shortcuts are automatically enabled and integrated into the NodeFlowEditor. The system is built into the NodeFlowController and requires no manual setup.

    Internally, the editor wraps your content with a NodeFlowKeyboardHandler, which manages interactions using Flutter's native Actions and Shortcuts system. This ensures that shortcuts are available as soon as you provide a NodeFlowController to the NodeFlowEditor.

    // Shortcuts work automatically
    final controller = NodeFlowController<MyData, dynamic>();
    
    NodeFlowEditor(
      controller: controller,
      nodeBuilder: (context, node) => MyNodeWidget(node),
    )
  7. Configure Port positions and types

    main

    Ports can be placed on the left, right, top, or bottom edges of a node using PortPosition.

    Automatic Type Inference: If you do not explicitly specify a PortType, it is inferred from the position:

    • PortPosition.left or PortPosition.top $\rightarrow$ PortType.input
    • PortPosition.right or PortPosition.bottom $\rightarrow$ PortType.output

    Port Types:

    • PortType.input: Receives connections.
    • PortType.output: Emits connections.
    // Port on the left side (input by convention)
    Port(
      id: 'input-port',
      name: 'Input',
      position: PortPosition.left,
      type: PortType.input,
    )
    
    // Port on the right side (output by convention)
    Port(
      id: 'output-port',
      name: 'Output',
      position: PortPosition.right,
      type: PortType.output,
    )
  8. Compare expression evaluation strategies

    main

    When building node-based systems, choosing the right evaluation strategy is critical for performance and stability. Below is a comparison of the approaches considered for the node_math demo:

    ApproachTime ComplexitySpace ComplexityBest Use Case
    Topological Sort (Used)$O(V + E)$$O(V)$DAG evaluation (deterministic)
    Backtracking$O(2^n)$$O(n)$Search/Constraint problems (e.g., Sudoku)
    Recursive (Naive)$O(V + E)$$O(V) + ext{stack}$Small, simple graphs
    Lazy Evaluation$O( ext{needed})$$O(V)$Partial queries (on-demand)
    Reactive/IncrementalN/AN/AReal-time editing of very large graphs
  9. Compare available Grid Styles

    main

    Vyuh Node Flow provides several grid styles to balance visibility, clutter, and use cases. Choose a style based on your application's needs:

    StyleVisibilityClutterBest Use Case
    LinesHighMediumTechnical diagrams, precision work
    DotsMediumLowClean interfaces, modern designs
    CrossMediumLowEngineering, balance of subtle/clear
    HierarchicalHighMediumComplex diagrams, multiple org levels
    NoneN/ANonePresentations, minimal designs
  10. Visualize AutoPan Zones

    main

    Enable DebugMode.autoPanZone or DebugMode.all to see the edge zones where auto-panning activates during drag operations. The visualization shows:

    • Yellow zones: Areas where dragging triggers auto-panning.
    • Dashed rectangle: Safe area boundary (no auto-pan).
    • Zone widths: These match the edgePadding values from the AutoPanPlugin.

    Use this when:

    • Tuning edgePadding values for your UI layout.
    • Verifying asymmetric edge padding works correctly.
    • Testing autopan behavior with overlapping toolbars.
  11. Update Connection state reactively

    main

    Properties like animated, selected, and labels are MobX observables. Modifying them after construction will trigger automatic UI updates.

    // Get/set animation state
    connection.animated = true;
    
    // Get/set selection state
    connection.selected = true;
    
    // Get/set labels (use ConnectionLabel objects)
    connection.startLabel = ConnectionLabel.start(text: 'Begin');
    connection.label = ConnectionLabel.center(text: 'Data Flow');
    connection.endLabel = ConnectionLabel.end(text: 'End');
    
    // Get/set animation effect
    connection.animationEffect = FlowingDashEffect();
    
    // Get/set control points
    connection.controlPoints = [Offset(300, 200), Offset(400, 200)];