You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
579 lines
20 KiB
Dart
579 lines
20 KiB
Dart
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
|
|
import 'package:diplomaticquarterapp/models/SmartWatch/WeeklyHeartRateResModel.dart';
|
|
import 'package:diplomaticquarterapp/models/SmartWatch/YearlyHeartRateResModel.dart';
|
|
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
|
|
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
|
|
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
|
|
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
|
|
import 'package:diplomaticquarterapp/uitl/utils.dart';
|
|
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
|
|
import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart';
|
|
import 'package:diplomaticquarterapp/widgets/charts/show_chart.dart';
|
|
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
class HeartRateTracker extends StatefulWidget {
|
|
@override
|
|
_HeartRateTrackerState createState() => _HeartRateTrackerState();
|
|
}
|
|
|
|
class _HeartRateTrackerState extends State<HeartRateTracker> with SingleTickerProviderStateMixin {
|
|
late TabController _tabController;
|
|
|
|
late ProjectViewModel projectViewModel;
|
|
|
|
num weeklyStatsAvgValue = 0;
|
|
num monthlyStatsAvgValue = 0;
|
|
num yearlyStatsAvgValue = 0;
|
|
|
|
num avgWeeklyHearRateValue = 0;
|
|
num avgMonthlyHearRateValue = 0;
|
|
num avgYearlyHearRateValue = 0;
|
|
|
|
int weeklyDataLength = 0;
|
|
int monthlyDataLength = 0;
|
|
int yearlyDataLength = 0;
|
|
|
|
List<WeeklyHeartRateResModel> weekyHearRateList = [];
|
|
List<WeeklyHeartRateResModel> monthlyHearRateList = [];
|
|
List<YearlyHeartRateResModel> yearlyHearRateList = [];
|
|
|
|
List<TimeSeriesSales2> weeklyTimeSeriesData = [];
|
|
List<TimeSeriesSales2> monthlyTimeSeriesData = [];
|
|
List<TimeSeriesSales2> yearlyTimeSeriesData = [];
|
|
|
|
bool isWeeklyDataLoaded = false;
|
|
bool isMonthlyDataLoaded = false;
|
|
bool isYearlyDataLoaded = false;
|
|
|
|
@override
|
|
void initState() {
|
|
_tabController = new TabController(length: 3, vsync: this);
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
getWeeklyHeartRateData();
|
|
});
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
projectViewModel = Provider.of(context);
|
|
return AppScaffold(
|
|
isShowAppBar: true,
|
|
appBarTitle: TranslationBase.of(context).heart,
|
|
showNewAppBar: true,
|
|
showNewAppBarTitle: true,
|
|
isShowDecPage: false,
|
|
body: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
TabBar(
|
|
controller: _tabController,
|
|
indicatorWeight: 3.0,
|
|
indicatorSize: TabBarIndicatorSize.tab,
|
|
labelColor: Color(0xff2B353E),
|
|
unselectedLabelColor: Color(0xff575757),
|
|
labelPadding: EdgeInsets.only(top: 0, bottom: 0, left: 20, right: 20),
|
|
labelStyle: TextStyle(
|
|
fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins',
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: -0.48,
|
|
),
|
|
unselectedLabelStyle: TextStyle(
|
|
fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins',
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: -0.48,
|
|
),
|
|
tabs: [
|
|
Tab(text: TranslationBase.of(context).weekly),
|
|
Tab(text: TranslationBase.of(context).monthlyTab),
|
|
Tab(text: TranslationBase.of(context).yearly),
|
|
],
|
|
onTap: (value) {
|
|
print(value);
|
|
if (value == 0) {
|
|
getWeeklyHeartRateData();
|
|
} else if (value == 1) {
|
|
getMonthlyHeartRateData();
|
|
} else {
|
|
getYearlyHeartRateData();
|
|
}
|
|
},
|
|
),
|
|
Expanded(
|
|
child: new TabBarView(
|
|
physics: NeverScrollableScrollPhysics(),
|
|
children: [
|
|
isWeeklyDataLoaded
|
|
? avgWeeklyHearRateValue != 0
|
|
? getWeeklyHeartRateDetails()
|
|
: getNoDataWidget(context)
|
|
: Container(),
|
|
isMonthlyDataLoaded ? getMonthlyHeartRateDetails() : Container(),
|
|
isYearlyDataLoaded ? getYearlyHeartRateDetails() : Container()
|
|
],
|
|
controller: _tabController,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
getWeeklyHeartRateData() {
|
|
avgWeeklyHearRateValue = 0;
|
|
weeklyDataLength = 0;
|
|
DoctorsListService service = new DoctorsListService();
|
|
GifLoaderDialogUtils.showMyDialog(context);
|
|
service.getPatientHealthDataStats(3, 1, context).then((res) {
|
|
GifLoaderDialogUtils.hideDialog(context);
|
|
weekyHearRateList.clear();
|
|
res['Med_GetAvgWeekTransactionsStsList'].forEach((element) {
|
|
if (element['ValueAvg'] != null) {
|
|
weekyHearRateList.add(new WeeklyHeartRateResModel.fromJson(element));
|
|
num value = element['ValueAvg'];
|
|
avgWeeklyHearRateValue += value.toInt();
|
|
weeklyDataLength++;
|
|
}
|
|
});
|
|
if (weekyHearRateList.isNotEmpty) generateWeekData();
|
|
setState(() {
|
|
if (avgWeeklyHearRateValue != 0) {
|
|
weeklyStatsAvgValue = avgWeeklyHearRateValue ~/ weeklyDataLength;
|
|
}
|
|
isWeeklyDataLoaded = true;
|
|
});
|
|
}).catchError((err) {
|
|
GifLoaderDialogUtils.hideDialog(context);
|
|
print(err);
|
|
});
|
|
}
|
|
|
|
getMonthlyHeartRateData() {
|
|
avgMonthlyHearRateValue = 0;
|
|
monthlyDataLength = 0;
|
|
DoctorsListService service = new DoctorsListService();
|
|
GifLoaderDialogUtils.showMyDialog(context);
|
|
service.getPatientHealthDataStats(3, 2, context).then((res) {
|
|
GifLoaderDialogUtils.hideDialog(context);
|
|
monthlyHearRateList.clear();
|
|
print(res['Med_GetAvgMonthTransactionsStsList'].length);
|
|
res['Med_GetAvgMonthTransactionsStsList'].forEach((element) {
|
|
monthlyHearRateList.add(new WeeklyHeartRateResModel.fromJson(element));
|
|
if (element['ValueAvg'] != null) {
|
|
num value = element['ValueAvg'];
|
|
avgMonthlyHearRateValue += value.toInt();
|
|
monthlyDataLength++;
|
|
}
|
|
});
|
|
generateMonthData();
|
|
setState(() {
|
|
if (avgMonthlyHearRateValue != 0) {
|
|
monthlyStatsAvgValue = avgMonthlyHearRateValue ~/ monthlyDataLength;
|
|
}
|
|
isMonthlyDataLoaded = true;
|
|
});
|
|
}).catchError((err) {
|
|
GifLoaderDialogUtils.hideDialog(context);
|
|
print(err);
|
|
});
|
|
}
|
|
|
|
getYearlyHeartRateData() {
|
|
avgYearlyHearRateValue = 0;
|
|
yearlyDataLength = 0;
|
|
DoctorsListService service = new DoctorsListService();
|
|
GifLoaderDialogUtils.showMyDialog(context);
|
|
service.getPatientHealthDataStats(3, 3, context).then((res) {
|
|
GifLoaderDialogUtils.hideDialog(context);
|
|
yearlyHearRateList.clear();
|
|
res['Med_GetYearTransactionsStsList'].forEach((element) {
|
|
yearlyHearRateList.add(new YearlyHeartRateResModel.fromJson(element));
|
|
if (element['ValueAvg'] != null) {
|
|
num value = element['ValueAvg'];
|
|
avgYearlyHearRateValue += value;
|
|
yearlyDataLength++;
|
|
}
|
|
});
|
|
generateYearData();
|
|
setState(() {
|
|
if (avgYearlyHearRateValue != 0) {
|
|
yearlyStatsAvgValue = avgYearlyHearRateValue ~/ yearlyDataLength;
|
|
}
|
|
isYearlyDataLoaded = true;
|
|
});
|
|
}).catchError((err) {
|
|
GifLoaderDialogUtils.hideDialog(context);
|
|
print(err);
|
|
});
|
|
}
|
|
|
|
generateWeekData() {
|
|
if (weekyHearRateList.length > 0) {
|
|
weeklyTimeSeriesData.clear();
|
|
weekyHearRateList.forEach(
|
|
(element) {
|
|
weeklyTimeSeriesData.add(
|
|
TimeSeriesSales2(
|
|
DateUtil.convertStringToDate(element.machineDate!),
|
|
element.valueAvg != null ? element.valueAvg!.toDouble() : 0.0,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
generateMonthData() {
|
|
if (monthlyHearRateList.length > 0) {
|
|
monthlyTimeSeriesData.clear();
|
|
monthlyHearRateList.forEach(
|
|
(element) {
|
|
monthlyTimeSeriesData.add(
|
|
TimeSeriesSales2(
|
|
DateUtil.convertStringToDate(element.machineDate!),
|
|
element.valueAvg != null ? element.valueAvg!.toDouble() : 0.0,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
generateYearData() {
|
|
if (yearlyHearRateList.length > 0) {
|
|
yearlyTimeSeriesData.clear();
|
|
yearlyHearRateList.forEach(
|
|
(element) {
|
|
yearlyTimeSeriesData.add(
|
|
TimeSeriesSales2(
|
|
new DateTime(element.year!, element.month!, 1),
|
|
element.valueAvg != null ? element.valueAvg!.toDouble() : 0.0,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
getWeeklyHeartRateDetails() {
|
|
return SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
child: ShowChart(
|
|
title: "",
|
|
timeSeries: weeklyTimeSeriesData,
|
|
indexes: weeklyTimeSeriesData.length ~/ 5.5,
|
|
horizontalInterval: 8,
|
|
isWeeklyOrMonthly: true,
|
|
),
|
|
),
|
|
Container(
|
|
child: Container(
|
|
decoration: cardRadius(12),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0),
|
|
child: Text(TranslationBase.of(context).avgHeartRate, style: TextStyle(fontSize: 18.0)),
|
|
),
|
|
Container(
|
|
margin: EdgeInsets.only(bottom: 10.0),
|
|
child: Text(weeklyStatsAvgValue.toString() + " " + TranslationBase.of(context).bpm, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
decoration: cardRadius(12),
|
|
margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Text(TranslationBase.of(context).details,
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: -0.48,
|
|
)),
|
|
),
|
|
Container(
|
|
padding: EdgeInsets.all(10),
|
|
color: Colors.transparent,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
weekyHearRateList.isEmpty
|
|
? Container(
|
|
child: Center(
|
|
child: Text(TranslationBase.of(context).noDataAvailable),
|
|
),
|
|
)
|
|
: Table(
|
|
columnWidths: {
|
|
0: FlexColumnWidth(2.5),
|
|
},
|
|
children: fullDataWeekly(context),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
getMonthlyHeartRateDetails() {
|
|
return SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
child: ShowChart(
|
|
title: "",
|
|
timeSeries: monthlyTimeSeriesData,
|
|
indexes: monthlyTimeSeriesData.length ~/ 5.5,
|
|
horizontalInterval: 8,
|
|
isWeeklyOrMonthly: true,
|
|
),
|
|
),
|
|
Container(
|
|
child: Container(
|
|
decoration: cardRadius(12),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0),
|
|
child: Text(TranslationBase.of(context).avgHeartRate, style: TextStyle(fontSize: 18.0)),
|
|
),
|
|
Container(
|
|
margin: EdgeInsets.only(bottom: 10.0),
|
|
child: Text(monthlyStatsAvgValue.toString() + " " + TranslationBase.of(context).bpm, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
decoration: cardRadius(12),
|
|
margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Text(TranslationBase.of(context).details,
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: -0.48,
|
|
)),
|
|
),
|
|
Container(
|
|
padding: EdgeInsets.all(10),
|
|
color: Colors.transparent,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
monthlyHearRateList.isEmpty
|
|
? Container(
|
|
child: Center(
|
|
child: Text(TranslationBase.of(context).noDataAvailable),
|
|
),
|
|
)
|
|
: Table(
|
|
columnWidths: {
|
|
0: FlexColumnWidth(2.5),
|
|
},
|
|
children: fullDataMonthly(context),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
getYearlyHeartRateDetails() {
|
|
return SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
child: ShowChart(
|
|
title: "",
|
|
timeSeries: yearlyTimeSeriesData,
|
|
indexes: yearlyTimeSeriesData.length ~/ 5.5,
|
|
horizontalInterval: 8,
|
|
),
|
|
),
|
|
Container(
|
|
child: Container(
|
|
decoration: cardRadius(12),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 5.0),
|
|
child: Text(TranslationBase.of(context).avgHeartRate, style: TextStyle(fontSize: 18.0)),
|
|
),
|
|
Container(
|
|
margin: EdgeInsets.only(bottom: 10.0),
|
|
child: Text(yearlyStatsAvgValue.toString() + " " + TranslationBase.of(context).bpm, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
decoration: cardRadius(12),
|
|
margin: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Text(TranslationBase.of(context).details,
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: -0.48,
|
|
)),
|
|
),
|
|
Container(
|
|
padding: EdgeInsets.all(10),
|
|
color: Colors.transparent,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
yearlyHearRateList.isEmpty
|
|
? Container(
|
|
child: Center(
|
|
child: Text(TranslationBase.of(context).noDataAvailable),
|
|
),
|
|
)
|
|
: Table(
|
|
columnWidths: {
|
|
0: FlexColumnWidth(2.5),
|
|
},
|
|
children: fullData(context),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
List<TableRow> fullDataWeekly(BuildContext context) {
|
|
List<TableRow> tableRow = [];
|
|
tableRow.add(
|
|
TableRow(
|
|
children: [
|
|
Utils.tableColumnTitle(TranslationBase.of(context).date),
|
|
Utils.tableColumnTitle(TranslationBase.of(context).heart),
|
|
],
|
|
),
|
|
);
|
|
weekyHearRateList.forEach(
|
|
(step) {
|
|
tableRow.add(
|
|
TableRow(
|
|
children: [
|
|
Utils.tableColumnValue(
|
|
'${DateUtil.getDayMonthYearDateFormatted(
|
|
DateUtil.convertStringToDate(step.machineDate!),
|
|
)} ',
|
|
isCapitable: false,
|
|
mProjectViewModel: projectViewModel),
|
|
Utils.tableColumnValue(step.valueAvg.toString() + " " + TranslationBase.of(context).bpm, isCapitable: false, mProjectViewModel: projectViewModel),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
return tableRow;
|
|
}
|
|
|
|
List<TableRow> fullDataMonthly(BuildContext context) {
|
|
List<TableRow> tableRow = [];
|
|
tableRow.add(
|
|
TableRow(
|
|
children: [
|
|
Utils.tableColumnTitle(TranslationBase.of(context).date),
|
|
Utils.tableColumnTitle(TranslationBase.of(context).heart),
|
|
],
|
|
),
|
|
);
|
|
monthlyHearRateList.forEach(
|
|
(step) {
|
|
tableRow.add(
|
|
TableRow(
|
|
children: [
|
|
Utils.tableColumnValue(
|
|
'${DateUtil.getDayMonthYearDateFormatted(
|
|
DateUtil.convertStringToDate(step.machineDate!),
|
|
)} ',
|
|
isCapitable: false,
|
|
mProjectViewModel: projectViewModel),
|
|
Utils.tableColumnValue(step.valueAvg.toString() + " " + TranslationBase.of(context).bpm, isCapitable: false, mProjectViewModel: projectViewModel),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
return tableRow;
|
|
}
|
|
|
|
List<TableRow> fullData(BuildContext context) {
|
|
List<TableRow> tableRow = [];
|
|
tableRow.add(
|
|
TableRow(
|
|
children: [
|
|
Utils.tableColumnTitle(TranslationBase.of(context).date),
|
|
Utils.tableColumnTitle(TranslationBase.of(context).distance),
|
|
],
|
|
),
|
|
);
|
|
yearlyHearRateList.forEach(
|
|
(step) {
|
|
tableRow.add(
|
|
TableRow(
|
|
children: [
|
|
Utils.tableColumnValue(
|
|
'${DateUtil.getDayMonthYearDateFormatted(
|
|
new DateTime(step.year!, step.month!, 1),
|
|
)} ',
|
|
isCapitable: false,
|
|
mProjectViewModel: projectViewModel),
|
|
Utils.tableColumnValue(step.valueAvg.toString() + " " + TranslationBase.of(context).bpm, isCapitable: false, mProjectViewModel: projectViewModel),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
return tableRow;
|
|
}
|
|
}
|