class TimeSeriesMapper { /// ========================= /// 📅 DAILY (24 JAM) /// ========================= static List toDaily({ required List data, required DateTime Function(T) getTime, required double Function(T) getValue, }) { final now = DateTime.now(); final sums = List.filled(24, 0.0); final counts = List.filled(24, 0); for (final item in data) { final time = getTime(item); if (_isSameDay(time, now)) { final hour = time.hour; sums[hour] += getValue(item); counts[hour]++; } } return List.generate(24, (i) { if (counts[i] == 0) return 0; return sums[i] / counts[i]; // 🔥 average, bukan overwrite }); } /// ========================= /// 📅 WEEKLY (7 HARI) /// ========================= static List toWeekly({ required List data, required DateTime Function(T) getTime, required double Function(T) getValue, }) { final now = DateTime.now(); final sums = List.filled(7, 0.0); final counts = List.filled(7, 0); DateTime startOfWeek = now.subtract(Duration(days: now.weekday - 1)); startOfWeek = DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day); for (final item in data) { final time = getTime(item); if (time.isAfter(startOfWeek)) { final index = time.weekday - 1; sums[index] += getValue(item); counts[index]++; } } return List.generate(7, (i) { if (counts[i] == 0) return 0; return sums[i] / counts[i]; }); } /// ========================= /// 📅 MONTHLY /// ========================= static List toMonthly({ required List data, required DateTime Function(T) getTime, required double Function(T) getValue, }) { final now = DateTime.now(); final daysInMonth = DateTime(now.year, now.month + 1, 0).day; final sums = List.filled(daysInMonth, 0.0); final counts = List.filled(daysInMonth, 0); for (final item in data) { final time = getTime(item); if (time.month == now.month && time.year == now.year) { final index = time.day - 1; sums[index] += getValue(item); counts[index]++; } } return List.generate(daysInMonth, (i) { if (counts[i] == 0) return 0; return sums[i] / counts[i]; }); } /// ========================= /// 🧠 HELPER /// ========================= static bool _isSameDay(DateTime a, DateTime b) { return a.year == b.year && a.month == b.month && a.day == b.day; } static List smooth(List data) { if (data.length < 3) return data; List result = []; for (int i = 0; i < data.length; i++) { if (i == 0 || i == data.length - 1) { result.add(data[i]); } else { final avg = (data[i - 1] + data[i] + data[i + 1]) / 3; result.add(avg); } } return result; } }