Skip to content

Connection Styles ​

Connection styles control how the path between two ports is drawn. Vyuh Node Flow provides four built-in path styles, each suited for different use cases.

All Connection Styles Comparison Four-panel grid showing the same

two nodes connected with different styles: (1) Bezier - smooth flowing S-curve, (2) Smoothstep - right angles with rounded corners, (3) Step - sharp 90-degree angles, (4) Straight - direct diagonal line. Each labeled with style name and best use case. :::

Available Styles ​

Bezier (Smooth Curves) ​

Creates smooth, flowing cubic Bezier curves between nodes. Best for organic, natural-looking flows.

dart
connectionTheme: ConnectionTheme.light.copyWith(
  style: ConnectionStyles.bezier,
)

Best for:

  • Data pipelines
  • Workflow diagrams
  • Mind maps
  • When showing natural flow of information

Characteristics:

  • Smooth, organic curves
  • Automatically adjusts curve intensity based on distance
  • Handles sharp turns gracefully
  • Works well in all directions
dart
NodeFlowEditor(
  theme: NodeFlowTheme.light.copyWith(
    connectionTheme: ConnectionTheme.light.copyWith(
      style: ConnectionStyles.bezier,
    ),
  ),
)
dart
// Curvature is configured via the ConnectionTheme
NodeFlowEditor(
  theme: NodeFlowTheme.light.copyWith(
    connectionTheme: ConnectionTheme.light.copyWith(
      style: ConnectionStyles.bezier,
      bezierCurvature: 0.5, // 0.0 = more direct, 1.0 = maximum curve
    ),
  ),
)

Smoothstep (Rounded Steps) ​

Creates step patterns with rounded corners. Ideal for technical diagrams and structured workflows.

dart
connectionTheme: ConnectionTheme.light.copyWith(
  style: ConnectionStyles.smoothstep,
)

Best for:

  • Technical diagrams
  • Circuit designs
  • BPMN-style processes
  • When you need clean, structured paths

Characteristics:

  • Right-angle turns with rounded corners
  • Clean, professional appearance
  • Excellent for horizontal/vertical layouts
  • Predictable path routing
dart
NodeFlowEditor(
  theme: NodeFlowTheme.light.copyWith(
    connectionTheme: ConnectionTheme.light.copyWith(
      style: ConnectionStyles.smoothstep,
    ),
  ),
)
dart
// Corner radius is configured via the ConnectionTheme
NodeFlowEditor(
  theme: NodeFlowTheme.light.copyWith(
    connectionTheme: ConnectionTheme.light.copyWith(
      style: ConnectionStyles.smoothstep,
      cornerRadius: 10, // Radius of rounded corners
    ),
  ),
)

Step (Sharp Corners) ​

Creates step patterns with sharp, 90-degree corners. Perfect for grid-aligned, technical diagrams.

dart
connectionTheme: ConnectionTheme.light.copyWith(
  style: ConnectionStyles.step,
)

Best for:

  • Circuit diagrams
  • Network topologies
  • Grid-aligned layouts
  • When precision matters more than aesthetics

Characteristics:

  • Sharp 90-degree turns
  • No curves or rounding
  • Aligns perfectly with grids
  • Minimal visual complexity
dart
NodeFlowEditor(
  theme: NodeFlowTheme.light.copyWith(
    connectionTheme: ConnectionTheme.light.copyWith(
      style: ConnectionStyles.step,
    ),
  ),
)

Straight (Direct Lines) ​

Creates direct, straight lines between ports. Minimalist and performance-optimized.

dart
connectionTheme: ConnectionTheme.light.copyWith(
  style: ConnectionStyles.straight,
)

Best for:

  • Simple diagrams
  • When performance is critical
  • Minimalist designs
  • Dense graphs with many connections

Characteristics:

  • Direct line from source to target
  • Fastest rendering performance
  • Minimal visual clutter
  • Works well with diagonal layouts
dart
NodeFlowEditor(
  theme: NodeFlowTheme.light.copyWith(
    connectionTheme: ConnectionTheme.light.copyWith(
      style: ConnectionStyles.straight,
    ),
  ),
)

Per-Connection Styles ​

Apply different styles to individual connections:

dart
// Create connection with specific style override
final connection = Connection(
  id: 'conn-1',
  sourceNodeId: 'node-1',
  sourcePortId: 'out',
  targetNodeId: 'node-2',
  targetPortId: 'in',
  style: ConnectionStyles.bezier, // Override theme style
);

controller.addConnection(connection);

Combining Styles ​

You can mix styles in the same diagram by setting the style property on individual connections:

dart
// Data flow connection uses bezier curves
controller.addConnection(Connection(
  id: 'data-flow-1',
  sourceNodeId: 'source',
  sourcePortId: 'dataOut',
  targetNodeId: 'processor',
  targetPortId: 'dataIn',
  style: ConnectionStyles.bezier,
));

// Control flow connection uses sharp steps
controller.addConnection(Connection(
  id: 'control-flow-1',
  sourceNodeId: 'controller',
  sourcePortId: 'controlOut',
  targetNodeId: 'processor',
  targetPortId: 'controlIn',
  style: ConnectionStyles.step,
));

Style Comparison ​

StylePerformanceVisual AppealUse Case
BezierGoodHighNatural flows, data pipelines
SmoothstepGoodHighTechnical diagrams, workflows
StepExcellentMediumCircuit designs, grid layouts
StraightExcellentLowSimple diagrams, dense graphs

Temporary Connection Style ​

Customize the style used while dragging to create a connection:

dart
NodeFlowEditor(
  theme: NodeFlowTheme.light.copyWith(
    // Normal connections
    connectionTheme: ConnectionTheme.light.copyWith(
      style: ConnectionStyles.smoothstep,
    ),

    // While dragging - use temporaryConnectionTheme
    temporaryConnectionTheme: ConnectionTheme.light.copyWith(
      style: ConnectionStyles.straight,
      color: Colors.blue.withOpacity(0.5),
      strokeWidth: 2,
      dashPattern: [8, 4], // Dashed line
    ),
  ),
)

Best Practices ​

  1. Consistency: Use the same style for similar connection types
  2. Context: Choose style based on your domain (technical vs creative)
  3. Performance: Use straight for graphs with 100+ connections
  4. Grid Alignment: Use step or smoothstep with grid snapping
  5. User Preference: Consider allowing users to switch styles

Creating Custom Styles ​

Extend ConnectionStyle to create custom path algorithms. The API uses a segment-based architecture where you implement createSegments to define the path:

dart
import 'dart:math';

class WaveConnectionStyle extends ConnectionStyle {
  final double amplitude;
  final int waveCount;

  const WaveConnectionStyle({
    this.amplitude = 20.0,
    this.waveCount = 3,
  });

  @override
  String get id => 'wave';

  @override
  String get displayName => 'Wave';

  @override
  ({Offset start, List<PathSegment> segments}) createSegments(
    ConnectionPathParameters params,
  ) {
    // Generate wave points between start and end
    final segments = <PathSegment>[];
    final distance = (params.end - params.start).distance;
    final steps = (distance / 5).ceil();

    Offset previous = params.start;
    for (int i = 1; i <= steps; i++) {
      final t = i / steps;
      final x = params.start.dx + (params.end.dx - params.start.dx) * t;
      final wave = sin(t * waveCount * 2 * pi) * amplitude;
      final y = params.start.dy + (params.end.dy - params.start.dy) * t + wave;
      final current = Offset(x, y);
      segments.add(StraightSegment(end: current));
      previous = current;
    }

    return (start: params.start, segments: segments);
  }
}

Usage:

dart
NodeFlowEditor(
  theme: NodeFlowTheme.light.copyWith(
    connectionTheme: ConnectionTheme.light.copyWith(
      style: WaveConnectionStyle(amplitude: 15),
    ),
  ),
)

Common custom styles you can create:

  • Arc paths using CubicSegment for bezier curves
  • Circuit/Manhattan routing with perpendicular StraightSegments
  • Spiral or custom mathematical curves
  • Adaptive paths based on port positions and distance

See Also ​