mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-11-27 05:04:56 +00:00
Compare commits
14 Commits
SP-1493-FE
...
SP-1494-FE
| Author | SHA1 | Date | |
|---|---|---|---|
| d6ef06c1b3 | |||
| c9aaf2580f | |||
| d9cd5d0438 | |||
| 3eb87dfde1 | |||
| f29ff2551f | |||
| 67dd59ee9c | |||
| bb3c3906d1 | |||
| 3873deca90 | |||
| 9431dd4500 | |||
| 63718185e7 | |||
| 1f4e82d567 | |||
| 9f68d171ff | |||
| 6eba640037 | |||
| 7a088074e3 |
6
lib/pages/analytics/helpers/format_number_to_kwh.dart
Normal file
6
lib/pages/analytics/helpers/format_number_to_kwh.dart
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
extension FormatNumberToKwh on num {
|
||||||
|
String get formatNumberToKwh {
|
||||||
|
final regExp = RegExp(r'(\d)(?=(\d{3})+$)');
|
||||||
|
return '${toStringAsFixed(0).replaceAllMapped(regExp, (match) => '${match[1]},')} kWh';
|
||||||
|
}
|
||||||
|
}
|
||||||
19
lib/pages/analytics/helpers/get_month_name_from_int.dart
Normal file
19
lib/pages/analytics/helpers/get_month_name_from_int.dart
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
extension GetMonthNameFromNumber on num {
|
||||||
|
String get getMonthName {
|
||||||
|
return switch (this) {
|
||||||
|
1 => 'JAN',
|
||||||
|
2 => 'FEB',
|
||||||
|
3 => 'MAR',
|
||||||
|
4 => 'APR',
|
||||||
|
5 => 'MAY',
|
||||||
|
6 => 'JUN',
|
||||||
|
7 => 'JUL',
|
||||||
|
8 => 'AUG',
|
||||||
|
9 => 'SEP',
|
||||||
|
10 => 'OCT',
|
||||||
|
11 => 'NOV',
|
||||||
|
12 => 'DEC',
|
||||||
|
_ => 'N/A'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
14
lib/pages/analytics/models/energy_data_model.dart
Normal file
14
lib/pages/analytics/models/energy_data_model.dart
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
class EnergyDataModel extends Equatable {
|
||||||
|
const EnergyDataModel({
|
||||||
|
required this.date,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
final DateTime date;
|
||||||
|
final double value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [date, value];
|
||||||
|
}
|
||||||
@ -3,6 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/bloc/analytics_tab_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/bloc/analytics_tab_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_page_tabs_and_children.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_page_tabs_and_children.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/fake_total_energy_consumption_service.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
||||||
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
||||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||||
@ -12,8 +14,17 @@ class AnalyticsPage extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider<AnalyticsTabBloc>(
|
return MultiBlocProvider(
|
||||||
|
providers: [
|
||||||
|
BlocProvider<AnalyticsTabBloc>(
|
||||||
create: (context) => AnalyticsTabBloc(),
|
create: (context) => AnalyticsTabBloc(),
|
||||||
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => TotalEnergyConsumptionBloc(
|
||||||
|
FakeTotalEnergyConsumptionService(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
child: const AnalyticsPageForm(),
|
child: const AnalyticsPageForm(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
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';
|
||||||
|
|
||||||
|
part 'total_energy_consumption_event.dart';
|
||||||
|
part 'total_energy_consumption_state.dart';
|
||||||
|
|
||||||
|
class TotalEnergyConsumptionBloc
|
||||||
|
extends Bloc<TotalEnergyConsumptionEvent, TotalEnergyConsumptionState> {
|
||||||
|
TotalEnergyConsumptionBloc(
|
||||||
|
this._totalEnergyConsumptionService,
|
||||||
|
) : super(const TotalEnergyConsumptionState()) {
|
||||||
|
on<TotalEnergyConsumptionLoadEvent>(_onTotalEnergyConsumptionLoadEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
final TotalEnergyConsumptionService _totalEnergyConsumptionService;
|
||||||
|
|
||||||
|
Future<void> _onTotalEnergyConsumptionLoadEvent(
|
||||||
|
TotalEnergyConsumptionLoadEvent event,
|
||||||
|
Emitter<TotalEnergyConsumptionState> emit,
|
||||||
|
) async {
|
||||||
|
emit(state.copyWith(status: TotalEnergyConsumptionStatus.loading));
|
||||||
|
try {
|
||||||
|
final chartData = await _totalEnergyConsumptionService.load(event.param);
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
chartData: chartData,
|
||||||
|
status: TotalEnergyConsumptionStatus.loaded,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
errorMessage: e.toString(),
|
||||||
|
status: TotalEnergyConsumptionStatus.failure,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
part of 'total_energy_consumption_bloc.dart';
|
||||||
|
|
||||||
|
sealed class TotalEnergyConsumptionEvent extends Equatable {
|
||||||
|
const TotalEnergyConsumptionEvent();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
final class TotalEnergyConsumptionLoadEvent extends TotalEnergyConsumptionEvent {
|
||||||
|
const TotalEnergyConsumptionLoadEvent({required this.param});
|
||||||
|
|
||||||
|
final GetTotalEnergyConsumptionParam param ;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [param];
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
part of 'total_energy_consumption_bloc.dart';
|
||||||
|
|
||||||
|
enum TotalEnergyConsumptionStatus {
|
||||||
|
initial,
|
||||||
|
loading,
|
||||||
|
loaded,
|
||||||
|
failure,
|
||||||
|
}
|
||||||
|
|
||||||
|
final class TotalEnergyConsumptionState extends Equatable {
|
||||||
|
const TotalEnergyConsumptionState({
|
||||||
|
this.status = TotalEnergyConsumptionStatus.initial,
|
||||||
|
this.chartData = const <EnergyDataModel>[],
|
||||||
|
this.errorMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<EnergyDataModel> chartData;
|
||||||
|
final TotalEnergyConsumptionStatus status;
|
||||||
|
final String? errorMessage;
|
||||||
|
|
||||||
|
TotalEnergyConsumptionState copyWith({
|
||||||
|
List<EnergyDataModel>? chartData,
|
||||||
|
TotalEnergyConsumptionStatus? status,
|
||||||
|
String? errorMessage,
|
||||||
|
}) {
|
||||||
|
return TotalEnergyConsumptionState(
|
||||||
|
chartData: chartData ?? this.chartData,
|
||||||
|
status: status ?? this.status,
|
||||||
|
errorMessage: errorMessage ?? this.errorMessage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [chartData, status, errorMessage];
|
||||||
|
}
|
||||||
@ -1,12 +1,47 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart';
|
||||||
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
|
||||||
class AnalyticsEnergyManagementView extends StatelessWidget {
|
class AnalyticsEnergyManagementView extends StatelessWidget {
|
||||||
const AnalyticsEnergyManagementView({super.key});
|
const AnalyticsEnergyManagementView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const Center(
|
return Padding(
|
||||||
child: Text('EnergyManagementView is Working!'),
|
padding: const EdgeInsets.all(32),
|
||||||
|
child: Row(
|
||||||
|
spacing: 20,
|
||||||
|
children: [
|
||||||
|
const Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Column(
|
||||||
|
spacing: 20,
|
||||||
|
children: [
|
||||||
|
Expanded(child: TotalEnergyConsumptionChartBox()),
|
||||||
|
Expanded(child: EnergyConsumptionPerDeviceChart()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
decoration: subSectionContainerDecoration.copyWith(
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(30),
|
||||||
|
child: const Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 2, child: PowerClampEnergyDataWidget()),
|
||||||
|
Expanded(child: EnergyConsumptionByPhasesChart()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class EnergyConsumptionByPhasesChart extends StatelessWidget {
|
||||||
|
const EnergyConsumptionByPhasesChart({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Placeholder();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
|
||||||
|
class EnergyConsumptionPerDeviceChart extends StatelessWidget {
|
||||||
|
const EnergyConsumptionPerDeviceChart({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: subSectionContainerDecoration.copyWith(
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(30),
|
||||||
|
child: const Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Energy Consumption per Device',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Expanded(
|
||||||
|
child: Placeholder(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class PowerClampEnergyDataWidget extends StatelessWidget {
|
||||||
|
const PowerClampEnergyDataWidget({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Placeholder();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,175 @@
|
|||||||
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/helpers/format_number_to_kwh.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/helpers/get_month_name_from_int.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
|
// energy_consumption_chart will return id, name and consumption
|
||||||
|
const phasesJson = {
|
||||||
|
"1": {
|
||||||
|
"phaseOne": 1000,
|
||||||
|
"phaseTwo": 2000,
|
||||||
|
"phaseThree": 3000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TotalEnergyConsumptionChart extends StatelessWidget {
|
||||||
|
const TotalEnergyConsumptionChart({required this.chartData, super.key});
|
||||||
|
|
||||||
|
final List<EnergyDataModel> chartData;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Expanded(
|
||||||
|
child: LineChart(
|
||||||
|
LineChartData(
|
||||||
|
titlesData: _titlesData(context),
|
||||||
|
lineBarsData: _lineBarsData,
|
||||||
|
gridData: FlGridData(
|
||||||
|
show: true,
|
||||||
|
drawVerticalLine: false,
|
||||||
|
drawHorizontalLine: true,
|
||||||
|
),
|
||||||
|
borderData: FlBorderData(
|
||||||
|
show: true,
|
||||||
|
border: const Border.symmetric(
|
||||||
|
horizontal: BorderSide(
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
width: 1,
|
||||||
|
style: BorderStyle.solid,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
lineTouchData: LineTouchData(
|
||||||
|
handleBuiltInTouches: true,
|
||||||
|
touchSpotThreshold: 2,
|
||||||
|
touchTooltipData: _lineTouchTooltipData(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
duration: Durations.extralong1,
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<LineChartBarData> get _lineBarsData {
|
||||||
|
return [
|
||||||
|
LineChartBarData(
|
||||||
|
preventCurveOvershootingThreshold: 0.1,
|
||||||
|
curveSmoothness: 0.55,
|
||||||
|
preventCurveOverShooting: true,
|
||||||
|
spots: chartData
|
||||||
|
.asMap()
|
||||||
|
.entries
|
||||||
|
.map(
|
||||||
|
(entry) => FlSpot(
|
||||||
|
entry.key.toDouble(),
|
||||||
|
entry.value.value,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
color: ColorsManager.blueColor.withValues(alpha: 0.6),
|
||||||
|
shadow: Shadow(color: Colors.black12),
|
||||||
|
show: true,
|
||||||
|
isCurved: true,
|
||||||
|
belowBarData: BarAreaData(
|
||||||
|
show: true,
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
ColorsManager.vividBlue.withValues(alpha: 0.3),
|
||||||
|
ColorsManager.vividBlue.withValues(alpha: 0.2),
|
||||||
|
ColorsManager.vividBlue.withValues(alpha: 0.1),
|
||||||
|
Colors.transparent,
|
||||||
|
],
|
||||||
|
begin: Alignment.center,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dotData: FlDotData(show: false),
|
||||||
|
isStrokeCapRound: true,
|
||||||
|
barWidth: 3,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
FlTitlesData _titlesData(BuildContext context) {
|
||||||
|
return FlTitlesData(
|
||||||
|
show: true,
|
||||||
|
bottomTitles: AxisTitles(
|
||||||
|
drawBelowEverything: true,
|
||||||
|
sideTitles: SideTitles(
|
||||||
|
interval: 1,
|
||||||
|
reservedSize: 32,
|
||||||
|
showTitles: true,
|
||||||
|
maxIncluded: true,
|
||||||
|
getTitlesWidget: (value, meta) => Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 20.0),
|
||||||
|
child: Text(
|
||||||
|
chartData.elementAtOrNull(value.toInt())?.date.month.getMonthName ??
|
||||||
|
'',
|
||||||
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
|
fontSize: 12,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
leftTitles: AxisTitles(
|
||||||
|
sideTitles: SideTitles(
|
||||||
|
showTitles: true,
|
||||||
|
maxIncluded: true,
|
||||||
|
reservedSize: 110,
|
||||||
|
getTitlesWidget: (value, meta) => Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.only(end: 12),
|
||||||
|
child: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Text(
|
||||||
|
value.formatNumberToKwh,
|
||||||
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
|
fontSize: 12,
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||||
|
topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
LineTouchTooltipData _lineTouchTooltipData() {
|
||||||
|
return LineTouchTooltipData(
|
||||||
|
getTooltipColor: (touchTooltipItem) => ColorsManager.whiteColors,
|
||||||
|
tooltipBorder: const BorderSide(color: ColorsManager.semiTransparentBlack),
|
||||||
|
tooltipRoundedRadius: 16,
|
||||||
|
showOnTopOfTheChartBoxArea: false,
|
||||||
|
tooltipPadding: const EdgeInsets.all(8.0),
|
||||||
|
getTooltipItems: _getTooltipItems,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<LineTooltipItem?> _getTooltipItems(List<LineBarSpot> touchedSpots) {
|
||||||
|
return touchedSpots.map((spot) {
|
||||||
|
return LineTooltipItem(
|
||||||
|
_getToolTipLabel(spot.x + 1, spot.y),
|
||||||
|
const TextStyle(
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getToolTipLabel(num month, double value) {
|
||||||
|
final monthLabel = month.getMonthName;
|
||||||
|
final valueLabel = value.formatNumberToKwh;
|
||||||
|
final labels = [monthLabel, valueLabel];
|
||||||
|
return labels.where((element) => element.isNotEmpty).join(', ');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';
|
||||||
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
|
||||||
|
class TotalEnergyConsumptionChartBox extends StatefulWidget {
|
||||||
|
const TotalEnergyConsumptionChartBox({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<TotalEnergyConsumptionChartBox> createState() =>
|
||||||
|
_TotalEnergyConsumptionChartBoxState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TotalEnergyConsumptionChartBoxState
|
||||||
|
extends State<TotalEnergyConsumptionChartBox> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
final param = GetTotalEnergyConsumptionParam(
|
||||||
|
startDate: DateTime.now().subtract(const Duration(days: 30)),
|
||||||
|
endDate: DateTime.now(),
|
||||||
|
spaceId: '123',
|
||||||
|
);
|
||||||
|
context.read<TotalEnergyConsumptionBloc>().add(
|
||||||
|
TotalEnergyConsumptionLoadEvent(param: param),
|
||||||
|
);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<TotalEnergyConsumptionBloc, TotalEnergyConsumptionState>(
|
||||||
|
builder: (context, state) => Container(
|
||||||
|
decoration: subSectionContainerDecoration.copyWith(
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(30),
|
||||||
|
child: Column(
|
||||||
|
spacing: 20,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Total Energy Consumption',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TotalEnergyConsumptionChart(chartData: state.chartData),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
class GetTotalEnergyConsumptionParam {
|
||||||
|
final DateTime? startDate;
|
||||||
|
final DateTime? endDate;
|
||||||
|
final String? spaceId;
|
||||||
|
|
||||||
|
GetTotalEnergyConsumptionParam({
|
||||||
|
this.startDate,
|
||||||
|
this.endDate,
|
||||||
|
this.spaceId,
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'startDate': startDate?.toIso8601String(),
|
||||||
|
'endDate': endDate?.toIso8601String(),
|
||||||
|
'spaceId': spaceId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
class FakeTotalEnergyConsumptionService implements TotalEnergyConsumptionService {
|
||||||
|
@override
|
||||||
|
Future<List<EnergyDataModel>> load(
|
||||||
|
GetTotalEnergyConsumptionParam param,
|
||||||
|
) {
|
||||||
|
return Future.value([
|
||||||
|
EnergyDataModel(date: DateTime(2025, 1), value: 18000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 2), value: 25000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 3), value: 22000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 4), value: 21000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 5), value: 30000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 6), value: 23000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 7), value: 21000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 8), value: 25000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 9), value: 21100),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 10), value: 22000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 11), value: 21000),
|
||||||
|
EnergyDataModel(date: DateTime(2025, 12), value: 27500),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';
|
||||||
|
|
||||||
|
abstract interface class TotalEnergyConsumptionService {
|
||||||
|
Future<List<EnergyDataModel>> load(
|
||||||
|
GetTotalEnergyConsumptionParam param,
|
||||||
|
);
|
||||||
|
}
|
||||||
14
pubspec.yaml
14
pubspec.yaml
@ -35,21 +35,21 @@ dependencies:
|
|||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.6
|
cupertino_icons: ^1.0.6
|
||||||
flutter_bloc: ^8.1.5
|
flutter_bloc: ^9.1.0
|
||||||
equatable: ^2.0.5
|
equatable: ^2.0.5
|
||||||
graphview: ^1.2.0
|
graphview: ^1.2.0
|
||||||
flutter_svg: ^2.0.10+1
|
flutter_svg: ^2.0.10+1
|
||||||
dio: ^5.5.0+1
|
dio: ^5.5.0+1
|
||||||
get_it: ^7.6.7
|
get_it: ^8.0.3
|
||||||
flutter_secure_storage: ^9.2.2
|
flutter_secure_storage: ^9.2.2
|
||||||
shared_preferences: ^2.3.0
|
shared_preferences: ^2.3.0
|
||||||
dropdown_button2: ^2.3.9
|
dropdown_button2: ^2.3.9
|
||||||
data_table_2: ^2.5.15
|
data_table_2: ^2.5.15
|
||||||
go_router:
|
go_router:
|
||||||
intl: ^0.19.0
|
intl: ^0.20.2
|
||||||
dropdown_search: ^5.0.6
|
dropdown_search: ^6.0.2
|
||||||
flutter_dotenv: ^5.1.0
|
flutter_dotenv: ^5.1.0
|
||||||
fl_chart: ^0.69.0
|
fl_chart: ^0.71.0
|
||||||
uuid: ^4.4.2
|
uuid: ^4.4.2
|
||||||
time_picker_spinner: ^1.0.0
|
time_picker_spinner: ^1.0.0
|
||||||
intl_phone_field: ^3.2.0
|
intl_phone_field: ^3.2.0
|
||||||
@ -60,7 +60,7 @@ dependencies:
|
|||||||
firebase_core: ^3.11.0
|
firebase_core: ^3.11.0
|
||||||
firebase_crashlytics: ^4.3.2
|
firebase_crashlytics: ^4.3.2
|
||||||
firebase_database: ^11.3.2
|
firebase_database: ^11.3.2
|
||||||
bloc: ^8.1.4
|
bloc: ^9.0.0
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
@ -72,7 +72,7 @@ dev_dependencies:
|
|||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
# package. See that file for information about deactivating specific lint
|
# package. See that file for information about deactivating specific lint
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^3.0.0
|
flutter_lints: ^5.0.0
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|||||||
Reference in New Issue
Block a user