calculateDependencyPaths method

void calculateDependencyPaths(
  1. double canvasWidth,
  2. double canvasHeight
)

Calculates and caches the Paths for dependency lines between visible tasks. Requires calculateTaskRects to be called first. Path coordinates are relative to the top-left of this painter's canvas.

Implementation

void calculateDependencyPaths(double canvasWidth, double canvasHeight) {
  _dependencyPaths.clear();
  if (_dayWidth <= 0) return; // Need valid layout

  final Map<String, GanttTask> taskMap = {
    for (var task in tasks) task.id: task
  };

  for (final task in tasks) {
    // Path is drawn *to* this task (the 'target')
    // Check if task rect (now relative to y=0) is valid
    if (task.taskRect != null && task.dependsOn != null) {
      final sourceTask = taskMap[task.dependsOn!];
      // Check if source task rect and connector pos are valid
      if (sourceTask?.taskRect != null &&
          sourceTask?.connectorCirclePos != null) {
        final startPoint = sourceTask!.connectorCirclePos!;
        final endPoint = Offset(task.taskRect!.left,
            task.taskRect!.center.dy); // Target middle-left

        // If points are too close, don't draw path to avoid visual clutter/errors
        if ((startPoint - endPoint).distanceSquared < 4.0) {
          continue;
        }

        // --- Elbow path logic ---
        // Adjust this logic as needed for desired appearance.
        // This routes below the source task and comes up to the target task vertically.

        const double horizontalOffset =
            5.0; // Small horizontal jog from connector
        const double verticalSpacing =
            10.0; // Space below the source task bottom
        final double routeY = sourceTask.taskRect!.bottom +
            verticalSpacing; // Y level for horizontal segment

        final path = Path();
        path.moveTo(startPoint.dx, startPoint.dy); // Start at connector
        path.lineTo(
            startPoint.dx + horizontalOffset, startPoint.dy); // Jog right
        path.lineTo(startPoint.dx + horizontalOffset,
            routeY); // Down to routing level
        path.lineTo(endPoint.dx - horizontalOffset,
            routeY); // Across to target X (minus jog)
        path.lineTo(endPoint.dx - horizontalOffset,
            endPoint.dy); // Up/Down to target Y
        path.lineTo(endPoint.dx, endPoint.dy); // Final segment into target

        // --- End Elbow path logic ---

        _dependencyPaths[task.id] = path;
      }
    }
  }
}