From 2e12d73151dd6d8f3af53b96934a5833cd6bbafa Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sun, 1 Jun 2025 13:11:29 +0300 Subject: [PATCH] randomize generated fake data in `FakeAirQualityDistributionService`. --- ...fake_air_quality_distribution_service.dart | 55 +++++++++++++++---- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart b/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart index 59f4947b..264addab 100644 --- a/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart +++ b/lib/pages/analytics/services/air_quality_distribution/fake_air_quality_distribution_service.dart @@ -11,23 +11,54 @@ class FakeAirQualityDistributionService implements AirQualityDistributionService Future> getAirQualityDistribution( GetAirQualityDistributionParam param, ) async { - return List.generate(30, (index) { - final date = DateTime(2025, 5, 1).add(Duration(days: index)); + return Future.delayed( + const Duration(milliseconds: 400), + () => List.generate(30, (index) { + final date = DateTime(2025, 5, 1).add(Duration(days: index)); - final values = _generateRandomPercentages(); + final values = _generateRandomPercentages(); + final nullMask = List.generate(6, (_) => _shouldBeNull()); - return AirQualityDataModel( - date: date, - good: values[0], - moderate: values[1], - poor: values[2], - unhealthy: values[3], - severe: values[4], - hazardous: values[5], - ); + // If all values are null, force at least one to be non-null + if (nullMask.every((isNull) => isNull)) { + nullMask[_random.nextInt(6)] = false; + } + + // Redistribute percentages among non-null values + final nonNullValues = _redistributePercentages(values, nullMask); + + return AirQualityDataModel( + date: date, + good: nullMask[0] ? null : nonNullValues[0], + moderate: nullMask[1] ? null : nonNullValues[1], + poor: nullMask[2] ? null : nonNullValues[2], + unhealthy: nullMask[3] ? null : nonNullValues[3], + severe: nullMask[4] ? null : nonNullValues[4], + hazardous: nullMask[5] ? null : nonNullValues[5], + ); + }), + ); + } + + List _redistributePercentages( + List originalValues, List nullMask) { + // Calculate total of non-null values + double nonNullSum = 0; + for (int i = 0; i < originalValues.length; i++) { + if (!nullMask[i]) { + nonNullSum += originalValues[i]; + } + } + + // Redistribute percentages to maintain 100% total + return List.generate(originalValues.length, (i) { + if (nullMask[i]) return 0; + return (originalValues[i] / nonNullSum * 100).roundToDouble(); }); } + bool _shouldBeNull() => _random.nextDouble() < 0.6; + List _generateRandomPercentages() { final values = List.generate(6, (_) => _random.nextDouble());