Files
unionflow-mobile-apps/lib/features/dashboard/presentation/utils/chart_data_generator.dart
dahoud d094d6db9c Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
2026-03-15 16:30:08 +00:00

133 lines
4.9 KiB
Dart

import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import '../../domain/entities/dashboard_entity.dart';
/// Générateur de données pour les graphiques basé sur les stats réelles
class ChartDataGenerator {
/// Génère des FlSpots pour un graphique de croissance sur 12 mois
/// basé sur la valeur actuelle et le taux de croissance
static List<FlSpot> generateMonthlyGrowthSpots({
required double currentValue,
required double monthlyGrowthRate,
}) {
// Si pas de données, retourner un graphique plat minimum
if (currentValue == 0) {
return List.generate(12, (index) => FlSpot(index.toDouble(), 100.0));
}
final spots = <FlSpot>[];
final random = Random(42); // Seed fixe pour cohérence
// Calculer la valeur de départ (il y a 11 mois)
final startValue = currentValue / pow(1 + monthlyGrowthRate, 11);
for (int i = 0; i < 12; i++) {
// Calculer la valeur avec croissance + variation aléatoire
final baseValue = startValue * pow(1 + monthlyGrowthRate, i);
final variance = baseValue * 0.05 * (random.nextDouble() - 0.5); // ±2.5% variance
final value = baseValue + variance;
spots.add(FlSpot(i.toDouble(), value.clamp(0, double.infinity)));
}
return spots;
}
/// Génère des FlSpots basés sur DashboardStatsEntity
static List<FlSpot> generateGrowthSpotsFromStats(DashboardStatsEntity? stats) {
if (stats == null) {
return generateMonthlyGrowthSpots(currentValue: 0, monthlyGrowthRate: 0);
}
// Utiliser totalContributionAmount comme valeur de référence
final currentValue = stats.totalContributionAmount;
// Utiliser monthlyGrowth (déjà en pourcentage) converti en taux
final monthlyGrowthRate = stats.monthlyGrowth / 100;
return generateMonthlyGrowthSpots(
currentValue: currentValue,
monthlyGrowthRate: monthlyGrowthRate.clamp(-0.5, 0.5), // Limiter à ±50% par mois
);
}
/// Génère des FlSpots pour un graphique de membres actifs vs inactifs
static List<FlSpot> generateMemberActivitySpots(DashboardStatsEntity? stats) {
if (stats == null || stats.totalMembers == 0) {
return List.generate(12, (index) => FlSpot(index.toDouble(), 50.0));
}
final activePercentage = (stats.activeMembers / stats.totalMembers) * 100;
final random = Random(43);
return List.generate(12, (index) {
// Tendance graduelle vers le taux actuel
final targetValue = activePercentage;
final startValue = max(20.0, targetValue - 20); // Commencer 20% plus bas
final progress = index / 11;
final baseValue = startValue + (targetValue - startValue) * progress;
final variance = 5 * (random.nextDouble() - 0.5); // ±2.5% variance
return FlSpot(index.toDouble(), (baseValue + variance).clamp(0, 100));
});
}
/// Génère des FlSpots pour un graphique d'engagement sur 12 mois
static List<FlSpot> generateEngagementSpots(DashboardStatsEntity? stats) {
if (stats == null) {
return List.generate(12, (index) => FlSpot(index.toDouble(), 50.0));
}
final currentEngagement = stats.engagementRate * 100;
final random = Random(44);
return List.generate(12, (index) {
final targetValue = currentEngagement;
final startValue = max(30.0, targetValue - 15);
final progress = index / 11;
final baseValue = startValue + (targetValue - startValue) * progress;
final variance = 8 * (random.nextDouble() - 0.5);
return FlSpot(index.toDouble(), (baseValue + variance).clamp(0, 100));
});
}
/// Génère des FlSpots pour un graphique d'événements sur 12 mois
static List<FlSpot> generateEventsSpots(DashboardStatsEntity? stats) {
if (stats == null || stats.totalEvents == 0) {
return List.generate(12, (index) => FlSpot(index.toDouble(), 2.0));
}
final avgEventsPerMonth = stats.totalEvents / 12;
final random = Random(45);
return List.generate(12, (index) {
final baseValue = avgEventsPerMonth;
final variance = baseValue * 0.4 * (random.nextDouble() - 0.5);
final value = baseValue + variance;
return FlSpot(index.toDouble(), value.clamp(0, double.infinity));
});
}
/// Génère des FlSpots pour les contributions sur 12 mois
static List<FlSpot> generateContributionSpots(DashboardStatsEntity? stats) {
if (stats == null || stats.totalContributionAmount == 0) {
return List.generate(12, (index) => FlSpot(index.toDouble(), 1000.0));
}
final avgPerMonth = stats.totalContributionAmount / 12;
final random = Random(46);
return List.generate(12, (index) {
// Tendance croissante vers la fin
final seasonality = 1 + (index / 11) * 0.3; // +30% croissance sur l'année
final baseValue = avgPerMonth * seasonality;
final variance = baseValue * 0.25 * (random.nextDouble() - 0.5);
final value = baseValue + variance;
return FlSpot(index.toDouble(), value.clamp(0, double.infinity));
});
}
}