import '../models/timeline_entry.dart'; import '../models/projected_entry.dart'; import 'time_scale_service.dart'; class TimelineProjectionService { const TimelineProjectionService(); Map> project({ required Iterable entries, required DateTime domainStart, required DateTime domainEnd, }) { final byGroup = >{}; for (final e in entries) { if (e.overlaps(domainStart, domainEnd)) { final startX = TimeScaleService.mapTimeToPosition( e.start.isBefore(domainStart) ? domainStart : e.start, domainStart, domainEnd, ).clamp(0.0, 1.0); final endX = TimeScaleService.mapTimeToPosition( e.end.isAfter(domainEnd) ? domainEnd : e.end, domainStart, domainEnd, ).clamp(0.0, 1.0); final pe = ProjectedEntry(entry: e, startX: startX, endX: endX); (byGroup[e.groupId] ??= []).add(pe); } } // Keep original order stable by lane then startX for (final list in byGroup.values) { list.sort((a, b) { final laneCmp = a.entry.lane.compareTo(b.entry.lane); if (laneCmp != 0) return laneCmp; return a.startX.compareTo(b.startX); }); } return byGroup; } }