From 8534cb3045c88e1f1246c0a69475069cdc0427a9 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Tue, 1 Jul 2025 18:56:17 +0300 Subject: [PATCH] Created decorators for energy management charts to divide values by 100, and modified the intervals. --- .../analytics/views/analytics_page.dart | 10 ++++-- .../energy_consumption_by_phases_chart.dart | 16 ++++----- .../energy_consumption_per_device_chart.dart | 6 ++-- ...ion_by_phases_value_divider_decorator.dart | 34 ++++++++++++++++++ ...on_per_device_value_divider_decorator.dart | 36 +++++++++++++++++++ ...ed_total_energy_consumption_decorator.dart | 26 ++++++++++++++ lib/pages/home/bloc/home_bloc.dart | 2 +- lib/utils/helpers/safe_division_helper.dart | 8 +++++ 8 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 lib/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_value_divider_decorator.dart create mode 100644 lib/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_value_divider_decorator.dart create mode 100644 lib/pages/analytics/services/total_energy_consumption/divided_total_energy_consumption_decorator.dart create mode 100644 lib/utils/helpers/safe_division_helper.dart diff --git a/lib/pages/analytics/modules/analytics/views/analytics_page.dart b/lib/pages/analytics/modules/analytics/views/analytics_page.dart index 4b04c3e9..c80c20ab 100644 --- a/lib/pages/analytics/modules/analytics/views/analytics_page.dart +++ b/lib/pages/analytics/modules/analytics/views/analytics_page.dart @@ -22,7 +22,9 @@ import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_en import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart'; import 'package:syncrow_web/pages/analytics/services/device_location/device_location_details_service_decorator.dart'; import 'package:syncrow_web/pages/analytics/services/device_location/remote_device_location_service.dart'; +import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_value_divider_decorator.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart'; +import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_value_divider_decorator.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart'; import 'package:syncrow_web/pages/analytics/services/occupacy/remote_occupancy_service.dart'; import 'package:syncrow_web/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart'; @@ -69,12 +71,16 @@ class _AnalyticsPageState extends State { ), BlocProvider( create: (context) => EnergyConsumptionByPhasesBloc( - RemoteEnergyConsumptionByPhasesService(_httpService), + EnergyConsumptionByPhasesValueDividerDecorator( + RemoteEnergyConsumptionByPhasesService(_httpService), + ), ), ), BlocProvider( create: (context) => EnergyConsumptionPerDeviceBloc( - RemoteEnergyConsumptionPerDeviceService(_httpService), + EnergyConsumptionPerDeviceValueDividerDecorator( + RemoteEnergyConsumptionPerDeviceService(_httpService), + ), ), ), BlocProvider( diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart index 52c6f591..9baea1f6 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart @@ -13,15 +13,15 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { }); final List energyData; + static const _kLeftTitlesInterval = 4.0; @override Widget build(BuildContext context) { return BarChart( BarChartData( - gridData: EnergyManagementChartsHelper.gridData().copyWith( checkToShowHorizontalLine: (value) => true, - horizontalInterval: 250, + horizontalInterval: _kLeftTitlesInterval, ), borderData: EnergyManagementChartsHelper.borderData(), barTouchData: _barTouchData(context), @@ -100,11 +100,11 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { }) { final data = energyData; - final date = DateFormat('dd/MM/yyyy').format(data[group.x.toInt()].date); - final phaseA = data[group.x.toInt()].energyConsumedA; - final phaseB = data[group.x.toInt()].energyConsumedB; - final phaseC = data[group.x.toInt()].energyConsumedC; - final total = data[group.x.toInt()].energyConsumedKw; + final date = DateFormat('dd/MM/yyyy').format(data[group.x].date); + final phaseA = data[group.x].energyConsumedA; + final phaseB = data[group.x].energyConsumedB; + final phaseC = data[group.x].energyConsumedC; + final total = data[group.x].energyConsumedKw; return BarTooltipItem( '$date\n', @@ -149,7 +149,7 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { FlTitlesData _titlesData(BuildContext context) { final titlesData = EnergyManagementChartsHelper.titlesData( context, - leftTitlesInterval: 250, + leftTitlesInterval: _kLeftTitlesInterval, ); final leftTitles = titlesData.leftTitles.copyWith( diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart index 1e74ad31..c0d8d995 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart @@ -7,6 +7,7 @@ class EnergyConsumptionPerDeviceChart extends StatelessWidget { const EnergyConsumptionPerDeviceChart({super.key, required this.chartData}); final List chartData; + static const _kLeftTitlesInterval = 2.5; @override Widget build(BuildContext context) { @@ -15,12 +16,11 @@ class EnergyConsumptionPerDeviceChart extends StatelessWidget { clipData: const FlClipData.vertical(), titlesData: EnergyManagementChartsHelper.titlesData( context, - leftTitlesInterval: 250, + leftTitlesInterval: _kLeftTitlesInterval, ), - gridData: EnergyManagementChartsHelper.gridData().copyWith( checkToShowHorizontalLine: (value) => true, - horizontalInterval: 250, + horizontalInterval: _kLeftTitlesInterval, ), borderData: EnergyManagementChartsHelper.borderData(), lineTouchData: EnergyManagementChartsHelper.lineTouchData(), diff --git a/lib/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_value_divider_decorator.dart b/lib/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_value_divider_decorator.dart new file mode 100644 index 00000000..7184a735 --- /dev/null +++ b/lib/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_value_divider_decorator.dart @@ -0,0 +1,34 @@ +import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart'; +import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart'; +import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_service.dart'; +import 'package:syncrow_web/utils/helpers/safe_division_helper.dart'; + +class EnergyConsumptionByPhasesValueDividerDecorator + implements EnergyConsumptionByPhasesService { + const EnergyConsumptionByPhasesValueDividerDecorator( + this._decoratee, { + this.divider = 100, + }); + + final EnergyConsumptionByPhasesService _decoratee; + final double divider; + + @override + Future> load( + GetEnergyConsumptionByPhasesParam param) async { + final result = await _decoratee.load(param); + return result.map((e) { + return PhasesEnergyConsumption( + date: e.date, + energyConsumedA: SafeDivisionHelper.divide(e.energyConsumedA, divider), + energyConsumedB: SafeDivisionHelper.divide(e.energyConsumedB, divider), + energyConsumedC: SafeDivisionHelper.divide(e.energyConsumedC, divider), + energyConsumedKw: SafeDivisionHelper.divide(e.energyConsumedKw, divider), + uuid: e.uuid, + createdAt: e.createdAt, + updatedAt: e.updatedAt, + deviceUuid: e.deviceUuid, + ); + }).toList(); + } +} diff --git a/lib/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_value_divider_decorator.dart b/lib/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_value_divider_decorator.dart new file mode 100644 index 00000000..12d7bbbc --- /dev/null +++ b/lib/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_value_divider_decorator.dart @@ -0,0 +1,36 @@ +import 'package:syncrow_web/pages/analytics/models/device_energy_data_model.dart'; +import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart'; +import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart'; +import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_service.dart'; +import 'package:syncrow_web/utils/helpers/safe_division_helper.dart'; + +class EnergyConsumptionPerDeviceValueDividerDecorator + implements EnergyConsumptionPerDeviceService { + const EnergyConsumptionPerDeviceValueDividerDecorator( + this._decoratee, { + this.divider = 100, + }); + + final EnergyConsumptionPerDeviceService _decoratee; + final double divider; + + @override + Future> load( + GetEnergyConsumptionPerDeviceParam param, + ) async { + final result = await _decoratee.load(param); + return result.map((device) { + return DeviceEnergyDataModel( + deviceId: device.deviceId, + deviceName: device.deviceName, + color: device.color, + energy: device.energy.map((e) { + return EnergyDataModel( + date: e.date, + value: SafeDivisionHelper.divide(e.value, divider), + ); + }).toList(), + ); + }).toList(); + } +} diff --git a/lib/pages/analytics/services/total_energy_consumption/divided_total_energy_consumption_decorator.dart b/lib/pages/analytics/services/total_energy_consumption/divided_total_energy_consumption_decorator.dart new file mode 100644 index 00000000..731ce0f8 --- /dev/null +++ b/lib/pages/analytics/services/total_energy_consumption/divided_total_energy_consumption_decorator.dart @@ -0,0 +1,26 @@ +import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart'; +import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart'; +import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/total_energy_consumption_service.dart'; +import 'package:syncrow_web/utils/helpers/safe_division_helper.dart'; + +class DividedTotalEnergyConsumptionDecorator + implements TotalEnergyConsumptionService { + const DividedTotalEnergyConsumptionDecorator( + this._decoratee, { + this.divider = 100, + }); + + final TotalEnergyConsumptionService _decoratee; + final double divider; + + @override + Future> load(GetTotalEnergyConsumptionParam param) async { + final result = await _decoratee.load(param); + return result.map((e) { + return EnergyDataModel( + date: e.date, + value: SafeDivisionHelper.divide(e.value, divider), + ); + }).toList(); + } +} diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index c1bcba6a..aa642e25 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -105,7 +105,7 @@ class HomeBloc extends Bloc { color: const Color(0xFF0026A2), ), HomeItemModel( - title: 'Devices Management', + title: 'Device Management', icon: Assets.devicesIcon, active: true, onPress: (context) { diff --git a/lib/utils/helpers/safe_division_helper.dart b/lib/utils/helpers/safe_division_helper.dart new file mode 100644 index 00000000..39e6d7e9 --- /dev/null +++ b/lib/utils/helpers/safe_division_helper.dart @@ -0,0 +1,8 @@ +abstract final class SafeDivisionHelper { + const SafeDivisionHelper._(); + + static double divide(num value, num divider) { + if (divider == 0) return 0; + return value / divider; + } +}