Merge branch 'feature-ucaf' into 'development'
Feature ucaf See merge request Cloud_Solution/doctor_app_flutter!253merge-requests/255/merge
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,257 @@
|
||||
class VitalSignHistory {
|
||||
var transNo;
|
||||
var projectID;
|
||||
var weightKg;
|
||||
var heightCm;
|
||||
var temperatureCelcius;
|
||||
var pulseBeatPerMinute;
|
||||
var respirationBeatPerMinute;
|
||||
var bloodPressureLower;
|
||||
var bloodPressureHigher;
|
||||
var sAO2;
|
||||
var fIO2;
|
||||
var painScore;
|
||||
var bodyMassIndex;
|
||||
var headCircumCm;
|
||||
var leanBodyWeightLbs;
|
||||
var idealBodyWeightLbs;
|
||||
var temperatureCelciusMethod;
|
||||
var pulseRhythm;
|
||||
var respirationPattern;
|
||||
var bloodPressureCuffLocation;
|
||||
var bloodPressureCuffSize;
|
||||
var bloodPressurePatientPosition;
|
||||
var painLocation;
|
||||
var painDuration;
|
||||
var painCharacter;
|
||||
var painFrequency;
|
||||
bool isPainManagementDone;
|
||||
var status;
|
||||
bool isVitalsRequired;
|
||||
var patientID;
|
||||
var createdOn;
|
||||
var doctorID;
|
||||
var clinicID;
|
||||
var triageCategory;
|
||||
var gCScore;
|
||||
var lineItemNo;
|
||||
DateTime vitalSignDate;
|
||||
var actualTimeTaken;
|
||||
var sugarLevel;
|
||||
var fBS;
|
||||
var rBS;
|
||||
var observationType;
|
||||
var heartRate;
|
||||
var muscleTone;
|
||||
var reflexIrritability;
|
||||
var bodyColor;
|
||||
var isFirstAssessment;
|
||||
var dateofBirth;
|
||||
var timeOfBirth;
|
||||
var bloodPressure;
|
||||
var bloodPressureCuffLocationDesc;
|
||||
var bloodPressureCuffSizeDesc;
|
||||
var bloodPressurePatientPositionDesc;
|
||||
var clinicName;
|
||||
var doctorImageURL;
|
||||
var doctorName;
|
||||
var painScoreDesc;
|
||||
var pulseRhythmDesc;
|
||||
var respirationPatternDesc;
|
||||
var temperatureCelciusMethodDesc;
|
||||
var time;
|
||||
|
||||
VitalSignHistory(
|
||||
{this.transNo,
|
||||
this.projectID,
|
||||
this.weightKg,
|
||||
this.heightCm,
|
||||
this.temperatureCelcius,
|
||||
this.pulseBeatPerMinute,
|
||||
this.respirationBeatPerMinute,
|
||||
this.bloodPressureLower,
|
||||
this.bloodPressureHigher,
|
||||
this.sAO2,
|
||||
this.fIO2,
|
||||
this.painScore,
|
||||
this.bodyMassIndex,
|
||||
this.headCircumCm,
|
||||
this.leanBodyWeightLbs,
|
||||
this.idealBodyWeightLbs,
|
||||
this.temperatureCelciusMethod,
|
||||
this.pulseRhythm,
|
||||
this.respirationPattern,
|
||||
this.bloodPressureCuffLocation,
|
||||
this.bloodPressureCuffSize,
|
||||
this.bloodPressurePatientPosition,
|
||||
this.painLocation,
|
||||
this.painDuration,
|
||||
this.painCharacter,
|
||||
this.painFrequency,
|
||||
this.isPainManagementDone,
|
||||
this.status,
|
||||
this.isVitalsRequired,
|
||||
this.patientID,
|
||||
this.createdOn,
|
||||
this.doctorID,
|
||||
this.clinicID,
|
||||
this.triageCategory,
|
||||
this.gCScore,
|
||||
this.lineItemNo,
|
||||
this.vitalSignDate,
|
||||
this.actualTimeTaken,
|
||||
this.sugarLevel,
|
||||
this.fBS,
|
||||
this.rBS,
|
||||
this.observationType,
|
||||
this.heartRate,
|
||||
this.muscleTone,
|
||||
this.reflexIrritability,
|
||||
this.bodyColor,
|
||||
this.isFirstAssessment,
|
||||
this.dateofBirth,
|
||||
this.timeOfBirth,
|
||||
this.bloodPressure,
|
||||
this.bloodPressureCuffLocationDesc,
|
||||
this.bloodPressureCuffSizeDesc,
|
||||
this.bloodPressurePatientPositionDesc,
|
||||
this.clinicName,
|
||||
this.doctorImageURL,
|
||||
this.doctorName,
|
||||
this.painScoreDesc,
|
||||
this.pulseRhythmDesc,
|
||||
this.respirationPatternDesc,
|
||||
this.temperatureCelciusMethodDesc,
|
||||
this.time});
|
||||
|
||||
VitalSignHistory.fromJson(Map<String, dynamic> json) {
|
||||
transNo = json['TransNo'];
|
||||
projectID = json['ProjectID'];
|
||||
weightKg = json['WeightKg'];
|
||||
heightCm = json['HeightCm'];
|
||||
temperatureCelcius = json['TemperatureCelcius'];
|
||||
pulseBeatPerMinute = json['PulseBeatPerMinute'];
|
||||
respirationBeatPerMinute = json['RespirationBeatPerMinute'];
|
||||
bloodPressureLower = json['BloodPressureLower'];
|
||||
bloodPressureHigher = json['BloodPressureHigher'];
|
||||
sAO2 = json['SAO2'];
|
||||
fIO2 = json['FIO2'];
|
||||
painScore = json['PainScore'];
|
||||
bodyMassIndex = json['BodyMassIndex'];
|
||||
headCircumCm = json['HeadCircumCm'];
|
||||
leanBodyWeightLbs = json['LeanBodyWeightLbs'];
|
||||
idealBodyWeightLbs = json['IdealBodyWeightLbs'];
|
||||
temperatureCelciusMethod = json['TemperatureCelciusMethod'];
|
||||
pulseRhythm = json['PulseRhythm'];
|
||||
respirationPattern = json['RespirationPattern'];
|
||||
bloodPressureCuffLocation = json['BloodPressureCuffLocation'];
|
||||
bloodPressureCuffSize = json['BloodPressureCuffSize'];
|
||||
bloodPressurePatientPosition = json['BloodPressurePatientPosition'];
|
||||
painLocation = json['PainLocation'];
|
||||
painDuration = json['PainDuration'];
|
||||
painCharacter = json['PainCharacter'];
|
||||
painFrequency = json['PainFrequency'];
|
||||
isPainManagementDone = json['IsPainManagementDone'];
|
||||
status = json['Status'];
|
||||
isVitalsRequired = json['IsVitalsRequired'];
|
||||
patientID = json['PatientID'];
|
||||
createdOn = json['CreatedOn'];
|
||||
doctorID = json['DoctorID'];
|
||||
clinicID = json['ClinicID'];
|
||||
triageCategory = json['TriageCategory'];
|
||||
gCScore = json['GCScore'];
|
||||
lineItemNo = json['LineItemNo'];
|
||||
vitalSignDate = json['VitalSignDate'];
|
||||
actualTimeTaken = json['ActualTimeTaken'];
|
||||
sugarLevel = json['SugarLevel'];
|
||||
fBS = json['FBS'];
|
||||
rBS = json['RBS'];
|
||||
observationType = json['ObservationType'];
|
||||
heartRate = json['HeartRate'];
|
||||
muscleTone = json['MuscleTone'];
|
||||
reflexIrritability = json['ReflexIrritability'];
|
||||
bodyColor = json['BodyColor'];
|
||||
isFirstAssessment = json['IsFirstAssessment'];
|
||||
dateofBirth = json['DateofBirth'];
|
||||
timeOfBirth = json['TimeOfBirth'];
|
||||
bloodPressure = json['BloodPressure'];
|
||||
bloodPressureCuffLocationDesc = json['BloodPressureCuffLocationDesc'];
|
||||
bloodPressureCuffSizeDesc = json['BloodPressureCuffSizeDesc'];
|
||||
bloodPressurePatientPositionDesc = json['BloodPressurePatientPositionDesc'];
|
||||
clinicName = json['ClinicName'];
|
||||
doctorImageURL = json['DoctorImageURL'];
|
||||
doctorName = json['DoctorName'];
|
||||
painScoreDesc = json['PainScoreDesc'];
|
||||
pulseRhythmDesc = json['PulseRhythmDesc'];
|
||||
respirationPatternDesc = json['RespirationPatternDesc'];
|
||||
temperatureCelciusMethodDesc = json['TemperatureCelciusMethodDesc'];
|
||||
time = json['Time'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['TransNo'] = this.transNo;
|
||||
data['ProjectID'] = this.projectID;
|
||||
data['WeightKg'] = this.weightKg;
|
||||
data['HeightCm'] = this.heightCm;
|
||||
data['TemperatureCelcius'] = this.temperatureCelcius;
|
||||
data['PulseBeatPerMinute'] = this.pulseBeatPerMinute;
|
||||
data['RespirationBeatPerMinute'] = this.respirationBeatPerMinute;
|
||||
data['BloodPressureLower'] = this.bloodPressureLower;
|
||||
data['BloodPressureHigher'] = this.bloodPressureHigher;
|
||||
data['SAO2'] = this.sAO2;
|
||||
data['FIO2'] = this.fIO2;
|
||||
data['PainScore'] = this.painScore;
|
||||
data['BodyMassIndex'] = this.bodyMassIndex;
|
||||
data['HeadCircumCm'] = this.headCircumCm;
|
||||
data['LeanBodyWeightLbs'] = this.leanBodyWeightLbs;
|
||||
data['IdealBodyWeightLbs'] = this.idealBodyWeightLbs;
|
||||
data['TemperatureCelciusMethod'] = this.temperatureCelciusMethod;
|
||||
data['PulseRhythm'] = this.pulseRhythm;
|
||||
data['RespirationPattern'] = this.respirationPattern;
|
||||
data['BloodPressureCuffLocation'] = this.bloodPressureCuffLocation;
|
||||
data['BloodPressureCuffSize'] = this.bloodPressureCuffSize;
|
||||
data['BloodPressurePatientPosition'] = this.bloodPressurePatientPosition;
|
||||
data['PainLocation'] = this.painLocation;
|
||||
data['PainDuration'] = this.painDuration;
|
||||
data['PainCharacter'] = this.painCharacter;
|
||||
data['PainFrequency'] = this.painFrequency;
|
||||
data['IsPainManagementDone'] = this.isPainManagementDone;
|
||||
data['Status'] = this.status;
|
||||
data['IsVitalsRequired'] = this.isVitalsRequired;
|
||||
data['PatientID'] = this.patientID;
|
||||
data['CreatedOn'] = this.createdOn;
|
||||
data['DoctorID'] = this.doctorID;
|
||||
data['ClinicID'] = this.clinicID;
|
||||
data['TriageCategory'] = this.triageCategory;
|
||||
data['GCScore'] = this.gCScore;
|
||||
data['LineItemNo'] = this.lineItemNo;
|
||||
data['VitalSignDate'] = this.vitalSignDate;
|
||||
data['ActualTimeTaken'] = this.actualTimeTaken;
|
||||
data['SugarLevel'] = this.sugarLevel;
|
||||
data['FBS'] = this.fBS;
|
||||
data['RBS'] = this.rBS;
|
||||
data['ObservationType'] = this.observationType;
|
||||
data['HeartRate'] = this.heartRate;
|
||||
data['MuscleTone'] = this.muscleTone;
|
||||
data['ReflexIrritability'] = this.reflexIrritability;
|
||||
data['BodyColor'] = this.bodyColor;
|
||||
data['IsFirstAssessment'] = this.isFirstAssessment;
|
||||
data['DateofBirth'] = this.dateofBirth;
|
||||
data['TimeOfBirth'] = this.timeOfBirth;
|
||||
data['BloodPressure'] = this.bloodPressure;
|
||||
data['BloodPressureCuffLocationDesc'] = this.bloodPressureCuffLocationDesc;
|
||||
data['BloodPressureCuffSizeDesc'] = this.bloodPressureCuffSizeDesc;
|
||||
data['BloodPressurePatientPositionDesc'] =
|
||||
this.bloodPressurePatientPositionDesc;
|
||||
data['ClinicName'] = this.clinicName;
|
||||
data['DoctorImageURL'] = this.doctorImageURL;
|
||||
data['DoctorName'] = this.doctorName;
|
||||
data['PainScoreDesc'] = this.painScoreDesc;
|
||||
data['PulseRhythmDesc'] = this.pulseRhythmDesc;
|
||||
data['RespirationPatternDesc'] = this.respirationPatternDesc;
|
||||
data['TemperatureCelciusMethodDesc'] = this.temperatureCelciusMethodDesc;
|
||||
data['Time'] = this.time;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,217 @@
|
||||
import 'package:doctor_app_flutter/widgets/charts/app_time_series_chart.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LineChartCurved extends StatelessWidget {
|
||||
final String title;
|
||||
final List<TimeSeriesSales2> timeSeries;
|
||||
final int indexes;
|
||||
|
||||
LineChartCurved({this.title, this.timeSeries, this.indexes});
|
||||
|
||||
List<int> xAxixs = List();
|
||||
List<double> yAxixs = List();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
getXaxix();
|
||||
getYaxix();
|
||||
return AspectRatio(
|
||||
aspectRatio: 1.1,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(18)),
|
||||
// color: Colors.white,
|
||||
),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 15,
|
||||
letterSpacing: 2),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 10,),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 18.0, left: 16.0),
|
||||
child: LineChart(
|
||||
sampleData1(context),
|
||||
swapAnimationDuration: const Duration(milliseconds: 250),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
getXaxix() {
|
||||
for (int index = 0; index < timeSeries.length; index++) {
|
||||
int mIndex = indexes * index;
|
||||
if (mIndex < timeSeries.length) {
|
||||
xAxixs.add(mIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
getYaxix() {
|
||||
int indexess= (timeSeries.length*0.30).toInt();
|
||||
for (int index = 0; index < timeSeries.length; index++) {
|
||||
int mIndex = indexess * index;
|
||||
if (mIndex < timeSeries.length) {
|
||||
yAxixs.add(timeSeries[mIndex].sales);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LineChartData sampleData1(context) {
|
||||
return LineChartData(
|
||||
lineTouchData: LineTouchData(
|
||||
touchTooltipData: LineTouchTooltipData(
|
||||
tooltipBgColor: Colors.white,
|
||||
|
||||
),
|
||||
touchCallback: (LineTouchResponse touchResponse) {},
|
||||
handleBuiltInTouches: true,
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: true, drawVerticalLine: true, drawHorizontalLine: true),
|
||||
titlesData: FlTitlesData(
|
||||
bottomTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTextStyles: (value) => const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 10,
|
||||
),
|
||||
rotateAngle:-65,
|
||||
//rotateAngle:-65,
|
||||
margin: 22,
|
||||
getTitles: (value) {
|
||||
if (timeSeries.length < 15) {
|
||||
if (timeSeries.length > value.toInt()) {
|
||||
return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}';
|
||||
} else
|
||||
return '';
|
||||
} else {
|
||||
if (value.toInt() == 0)
|
||||
return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}';
|
||||
if (value.toInt() == timeSeries.length - 1)
|
||||
return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}';
|
||||
if (xAxixs.contains(value.toInt())) {
|
||||
return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
),
|
||||
leftTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTextStyles: (value) => const TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10,
|
||||
),
|
||||
getTitles: (value) {
|
||||
// if (timeSeries.length < 10) {
|
||||
// return '${value.toInt()}';
|
||||
// } else {
|
||||
// if (value == getMinY())
|
||||
// return '${value.toInt()}';
|
||||
// if (value == getMaxY())
|
||||
// return '${value.toInt()}';
|
||||
// if (yAxixs.contains(value)) {
|
||||
// return '${value.toInt()}';
|
||||
// }
|
||||
// return '';
|
||||
// }
|
||||
return '${value.toInt()}';
|
||||
},
|
||||
margin: 12,
|
||||
),
|
||||
),
|
||||
borderData: FlBorderData(
|
||||
show: true,
|
||||
border: const Border(
|
||||
bottom: BorderSide(
|
||||
color: Colors.black,
|
||||
width: 0.5,
|
||||
),
|
||||
left: BorderSide(
|
||||
color: Colors.black,
|
||||
),
|
||||
right: BorderSide(
|
||||
color: Colors.black,
|
||||
),
|
||||
top: BorderSide(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
),
|
||||
),
|
||||
minX: 0,
|
||||
maxX: (timeSeries.length - 1).toDouble(),
|
||||
maxY: getMaxY()+0.3,
|
||||
minY: getMinY(),
|
||||
lineBarsData: getData(context),
|
||||
);
|
||||
}
|
||||
|
||||
double getMaxY() {
|
||||
double max = 0;
|
||||
timeSeries.forEach((element) {
|
||||
double resultValueDouble = element.sales;
|
||||
if (resultValueDouble > max) max = resultValueDouble;
|
||||
});
|
||||
|
||||
return max.roundToDouble() ;
|
||||
}
|
||||
|
||||
double getMinY() {
|
||||
double min = timeSeries[0].sales;
|
||||
timeSeries.forEach((element) {
|
||||
double resultValueDouble = element.sales;
|
||||
if (resultValueDouble < min) min = resultValueDouble;
|
||||
});
|
||||
int value = min.toInt();
|
||||
|
||||
return value.toDouble();
|
||||
}
|
||||
|
||||
List<LineChartBarData> getData(context) {
|
||||
List<FlSpot> spots = List();
|
||||
for (int index = 0; index < timeSeries.length; index++) {
|
||||
spots.add(FlSpot(index.toDouble(), timeSeries[index].sales));
|
||||
}
|
||||
|
||||
final LineChartBarData lineChartBarData1 = LineChartBarData(
|
||||
spots: spots,
|
||||
isCurved: true,
|
||||
colors: [Theme.of(context).primaryColor],
|
||||
barWidth: 5,
|
||||
isStrokeCapRound: true,
|
||||
dotData: FlDotData(
|
||||
show: false,
|
||||
),
|
||||
belowBarData: BarAreaData(
|
||||
show: false,
|
||||
),
|
||||
);
|
||||
|
||||
return [
|
||||
lineChartBarData1,
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,257 @@
|
||||
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
|
||||
import 'package:doctor_app_flutter/widgets/charts/app_time_series_chart.dart';
|
||||
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LineChartCurvedBloodPressure extends StatelessWidget {
|
||||
final String title;
|
||||
final List<TimeSeriesSales2> timeSeries1;
|
||||
final List<TimeSeriesSales2> timeSeries2;
|
||||
final int indexes;
|
||||
|
||||
LineChartCurvedBloodPressure(
|
||||
{this.title, this.timeSeries1, this.indexes, this.timeSeries2});
|
||||
|
||||
List<int> xAxixs = List();
|
||||
List<double> yAxixs = List();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
getXaxix();
|
||||
return AspectRatio(
|
||||
aspectRatio: 1.1,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(18)),
|
||||
// color: Colors.white,
|
||||
),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: Colors.black, fontSize: 15, letterSpacing: 2),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(right: 18.0, left: 16.0, top: 15),
|
||||
child: LineChart(
|
||||
sampleData1(context),
|
||||
swapAnimationDuration: const Duration(milliseconds: 250),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.rectangle,
|
||||
color: Theme.of(context).primaryColor),
|
||||
),
|
||||
SizedBox(width: 5,),
|
||||
AppText(TranslationBase.of(context).systolicLng)
|
||||
],
|
||||
),
|
||||
SizedBox(width: 15,),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.rectangle,
|
||||
color: Colors.grey),
|
||||
),
|
||||
SizedBox(width: 5,),
|
||||
AppText(TranslationBase.of(context).diastolicLng)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
getXaxix() {
|
||||
for (int index = 0; index < timeSeries1.length; index++) {
|
||||
int mIndex = indexes * index;
|
||||
if (mIndex < timeSeries1.length) {
|
||||
xAxixs.add(mIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LineChartData sampleData1(context) {
|
||||
return LineChartData(
|
||||
lineTouchData: LineTouchData(
|
||||
touchTooltipData: LineTouchTooltipData(
|
||||
tooltipBgColor: Colors.white,
|
||||
),
|
||||
touchCallback: (LineTouchResponse touchResponse) {},
|
||||
handleBuiltInTouches: true,
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: true, drawVerticalLine: true, drawHorizontalLine: true),
|
||||
titlesData: FlTitlesData(
|
||||
bottomTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTextStyles: (value) => const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 10,
|
||||
),
|
||||
rotateAngle: -65,
|
||||
//rotateAngle:-65,
|
||||
margin: 22,
|
||||
getTitles: (value) {
|
||||
if (timeSeries1.length < 15) {
|
||||
if (timeSeries1.length > value.toInt()) {
|
||||
return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}';
|
||||
} else
|
||||
return '';
|
||||
} else {
|
||||
if (value.toInt() == 0)
|
||||
return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}';
|
||||
if (value.toInt() == timeSeries1.length - 1)
|
||||
return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}';
|
||||
if (xAxixs.contains(value.toInt())) {
|
||||
return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
),
|
||||
leftTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTextStyles: (value) => const TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10,
|
||||
),
|
||||
getTitles: (value) {
|
||||
return '${value.toInt()}';
|
||||
},
|
||||
margin: 12,
|
||||
),
|
||||
),
|
||||
borderData: FlBorderData(
|
||||
show: true,
|
||||
border: const Border(
|
||||
bottom: BorderSide(
|
||||
color: Colors.black,
|
||||
width: 0.5,
|
||||
),
|
||||
left: BorderSide(
|
||||
color: Colors.black,
|
||||
),
|
||||
right: BorderSide(
|
||||
color: Colors.black,
|
||||
),
|
||||
top: BorderSide(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
),
|
||||
),
|
||||
minX: 0,
|
||||
maxX: (timeSeries1.length - 1).toDouble(),
|
||||
maxY: getMaxY() + 0.3,
|
||||
minY: getMinY(),
|
||||
lineBarsData: getData(context),
|
||||
);
|
||||
}
|
||||
|
||||
double getMaxY() {
|
||||
double max = 0;
|
||||
timeSeries1.forEach((element) {
|
||||
double resultValueDouble = element.sales;
|
||||
if (resultValueDouble > max) max = resultValueDouble;
|
||||
});
|
||||
timeSeries2.forEach((element) {
|
||||
double resultValueDouble = element.sales;
|
||||
if (resultValueDouble > max) max = resultValueDouble;
|
||||
});
|
||||
|
||||
return max.roundToDouble();
|
||||
}
|
||||
|
||||
double getMinY() {
|
||||
double min = timeSeries1[0].sales;
|
||||
timeSeries1.forEach((element) {
|
||||
double resultValueDouble = element.sales;
|
||||
if (resultValueDouble < min) min = resultValueDouble;
|
||||
});
|
||||
timeSeries2.forEach((element) {
|
||||
double resultValueDouble = element.sales;
|
||||
if (resultValueDouble < min) min = resultValueDouble;
|
||||
});
|
||||
|
||||
int value = min.toInt();
|
||||
|
||||
return value.toDouble();
|
||||
}
|
||||
|
||||
List<LineChartBarData> getData(context) {
|
||||
List<FlSpot> spots = List();
|
||||
for (int index = 0; index < timeSeries1.length; index++) {
|
||||
spots.add(FlSpot(index.toDouble(), timeSeries1[index].sales));
|
||||
}
|
||||
|
||||
List<FlSpot> spots2 = List();
|
||||
for (int index = 0; index < timeSeries2.length; index++) {
|
||||
spots2.add(FlSpot(index.toDouble(), timeSeries2[index].sales));
|
||||
}
|
||||
|
||||
final LineChartBarData lineChartBarData1 = LineChartBarData(
|
||||
spots: spots,
|
||||
isCurved: true,
|
||||
colors: [Theme.of(context).primaryColor],
|
||||
barWidth: 5,
|
||||
isStrokeCapRound: true,
|
||||
dotData: FlDotData(
|
||||
show: false,
|
||||
),
|
||||
belowBarData: BarAreaData(
|
||||
show: false,
|
||||
),
|
||||
);
|
||||
final LineChartBarData lineChartBarData2 = LineChartBarData(
|
||||
spots: spots2,
|
||||
isCurved: true,
|
||||
colors: [Colors.grey],
|
||||
barWidth: 5,
|
||||
isStrokeCapRound: true,
|
||||
dotData: FlDotData(
|
||||
show: false,
|
||||
),
|
||||
belowBarData: BarAreaData(
|
||||
show: false,
|
||||
),
|
||||
);
|
||||
|
||||
return [lineChartBarData1, lineChartBarData2];
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
|
||||
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
|
||||
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
|
||||
import 'package:doctor_app_flutter/util/date-utils.dart';
|
||||
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
|
||||
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class VitalSignBloodPressureWidget extends StatefulWidget {
|
||||
final List<VitalSignHistory> vitalList;
|
||||
final String title1;
|
||||
final String title2;
|
||||
final String title3;
|
||||
final String viewKey1;
|
||||
final String viewKey2;
|
||||
|
||||
VitalSignBloodPressureWidget(
|
||||
{Key key, this.vitalList, this.title1, this.title2, this.viewKey1, this.title3, this.viewKey2});
|
||||
|
||||
@override
|
||||
_VitalSignDetailsWidgetState createState() => _VitalSignDetailsWidgetState();
|
||||
}
|
||||
|
||||
class _VitalSignDetailsWidgetState extends State<VitalSignBloodPressureWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ProjectViewModel projectViewModel = Provider.of(context);
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)),
|
||||
border: Border.all(color: Colors.grey, width: 1),
|
||||
),
|
||||
margin: EdgeInsets.all(20),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Table(
|
||||
border: TableBorder.symmetric(
|
||||
inside: BorderSide(width: 2.0, color: Colors.grey[300]),
|
||||
),
|
||||
children: fullData(projectViewModel),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<TableRow> fullData(ProjectViewModel projectViewModel) {
|
||||
List<TableRow> tableRow = [];
|
||||
tableRow.add(TableRow(children: [
|
||||
Container(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft:projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0),
|
||||
topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0)
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: AppText(
|
||||
TranslationBase.of(context).date,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
height: 60,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
|
||||
),
|
||||
child: Center(
|
||||
child: AppText(widget.title2, color: Colors.white),
|
||||
),
|
||||
height: 60),
|
||||
),
|
||||
Container(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0),
|
||||
topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0)
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: AppText(widget.title3, color: Colors.white),
|
||||
),
|
||||
height: 60),
|
||||
),
|
||||
]));
|
||||
widget.vitalList.forEach((vital) {
|
||||
var data = vital.toJson()[widget.viewKey1];
|
||||
if (data != 0)
|
||||
tableRow.add(TableRow(children: [
|
||||
Container(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Center(
|
||||
child: AppText(
|
||||
'${projectViewModel.isArabic ? DateUtils.getWeekDayArabic(vital.vitalSignDate.weekday) : DateUtils.getWeekDay(vital.vitalSignDate.weekday)}, ${vital.vitalSignDate.day} ${projectViewModel.isArabic ? DateUtils.getMonthArabic(vital.vitalSignDate.month) : DateUtils.getMonth(vital.vitalSignDate.month)}, ${vital.vitalSignDate.year} ',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Center(
|
||||
child: AppText(
|
||||
'${vital.toJson()[widget.viewKey1]}',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Center(
|
||||
child: AppText(
|
||||
'${vital.toJson()[widget.viewKey2]}',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
]));
|
||||
});
|
||||
return tableRow;
|
||||
}
|
||||
}
|
@ -1,246 +1,197 @@
|
||||
import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart';
|
||||
import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_req_model.dart';
|
||||
import 'package:doctor_app_flutter/core/viewModel/patient-vital-sign-viewmodel.dart';
|
||||
import 'package:doctor_app_flutter/lookups/patient_lookup.dart';
|
||||
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
|
||||
import 'package:doctor_app_flutter/screens/base/base_view.dart';
|
||||
import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item.dart';
|
||||
import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart';
|
||||
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
|
||||
import 'package:doctor_app_flutter/widgets/shared/errors/dr_app_embedded_error.dart';
|
||||
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
|
||||
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
|
||||
import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../config/shared_pref_kay.dart';
|
||||
import '../../../../config/size_config.dart';
|
||||
import '../../../../lookups/patient_lookup.dart';
|
||||
import '../../../../models/patient/patiant_info_model.dart';
|
||||
import '../../../../models/patient/vital_sign/vital_sign_res_model.dart';
|
||||
import '../../../../routes.dart';
|
||||
import '../../../../screens/patients/profile/vital_sign/vital_sign_item.dart';
|
||||
import '../../../../util/dr_app_shared_pref.dart';
|
||||
import '../../../../widgets/shared/app_scaffold_widget.dart';
|
||||
class VitalSignDetailsScreen extends StatelessWidget {
|
||||
|
||||
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
|
||||
int appointmentNo;
|
||||
int projectID;
|
||||
bool isNotOneAppointment;
|
||||
VitalSignDetailsScreen({this.appointmentNo, this.projectID,this.isNotOneAppointment=true});
|
||||
|
||||
class VitalSignDetailsScreen extends StatefulWidget {
|
||||
// VitalSignDetailsScreen({Key key, this.vitalSing}) : super(key: key);
|
||||
@override
|
||||
_VitalSignDetailsScreenState createState() => _VitalSignDetailsScreenState();
|
||||
}
|
||||
|
||||
class _VitalSignDetailsScreenState extends State<VitalSignDetailsScreen> {
|
||||
VitalSignResModel vitalSing;
|
||||
String url = "assets/images/";
|
||||
|
||||
|
||||
/*
|
||||
*@author: Elham Rababah
|
||||
*@Date:28/4/2020
|
||||
*@param: context
|
||||
*@return:
|
||||
*@desc: getVitalSignList Function
|
||||
*/
|
||||
getVitalSignList(BuildContext context, PatientViewModel model) async {
|
||||
Widget build(BuildContext context) {
|
||||
final routeArgs = ModalRoute.of(context).settings.arguments as Map;
|
||||
PatiantInformtion patient = routeArgs['patient'];
|
||||
String token = await sharedPref.getString(TOKEN);
|
||||
String type = await sharedPref.getString(SLECTED_PATIENT_TYPE);
|
||||
int inOutpatientType = 1;
|
||||
if (type == '0') {
|
||||
inOutpatientType = 2;
|
||||
}
|
||||
print(type);
|
||||
VitalSignReqModel vitalSignReqModel = VitalSignReqModel(
|
||||
patientID: patient.patientId,
|
||||
projectID: patient.projectId,
|
||||
tokenID: token,
|
||||
patientTypeID: patient.patientType,
|
||||
inOutpatientType: inOutpatientType,
|
||||
languageID: 2,
|
||||
transNo:
|
||||
patient.admissionNo != null ? int.parse(patient.admissionNo) : 0);
|
||||
model.getPatientVitalSign(vitalSignReqModel.toJson());
|
||||
}
|
||||
|
||||
|
||||
|
||||
final double contWidth = SizeConfig.realScreenWidth * 0.70;
|
||||
String from = routeArgs['from'];
|
||||
String to = routeArgs['to'];
|
||||
String imageBasePath = 'assets/images/';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final routeArgs = ModalRoute.of(context).settings.arguments as Map;
|
||||
vitalSing = routeArgs['vitalSing'];
|
||||
return BaseView<PatientViewModel>(
|
||||
onModelReady: (model) => getVitalSignList(context, model),
|
||||
builder: (_, model, w) => AppScaffold(
|
||||
baseViewModel: model,
|
||||
return BaseView<VitalSignsViewModel>(
|
||||
onModelReady: (model) => model.getPatientVitalSignHistory(patient, from, to),
|
||||
builder: (_, mode, widget) => AppScaffold(
|
||||
isShowAppBar: true,
|
||||
baseViewModel: mode,
|
||||
appBarTitle: TranslationBase.of(context).vitalSign,
|
||||
body: model.patientVitalSignOrderdSubList.length == 0
|
||||
? DrAppEmbeddedError(
|
||||
error: 'You don\'t have any vital Sings')
|
||||
: Container(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
BODY_MEASUREMENTS,
|
||||
arguments: {
|
||||
'title': TranslationBase.of(context)
|
||||
.bodyMeasurements,
|
||||
'key':
|
||||
vitalSignDetails.bodyMeasurements
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context)
|
||||
.bodyMeasurements,
|
||||
url: url + 'heartbeat.png',
|
||||
lastVal: model
|
||||
.patientVitalSignOrderdSubList[0]
|
||||
.heightCm
|
||||
.toString(),
|
||||
unit: 'Cm',
|
||||
),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
BODY_MEASUREMENTS,
|
||||
arguments: {
|
||||
'title': TranslationBase.of(context)
|
||||
.temperature,
|
||||
'key': vitalSignDetails.temperature,
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context)
|
||||
.temperature,
|
||||
url: url + 'heartbeat.png',
|
||||
lastVal: model
|
||||
.patientVitalSignOrderdSubList[0]
|
||||
.temperatureCelcius
|
||||
.toString(),
|
||||
unit: 'C',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
body: mode.patientVitalSignsHistory.length > 0
|
||||
? Container(
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
onTap: () =>isNotOneAppointment? Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: VitalSignItemDetailsScreen(
|
||||
pageKey: vitalSignDetails.Height,
|
||||
pageTitle: TranslationBase.of(context).height,
|
||||
vitalList: mode.patientVitalSignsHistory,
|
||||
),
|
||||
),
|
||||
):null,
|
||||
child: Container(
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context).height,
|
||||
imagePath: "${imageBasePath}vital_height.png",
|
||||
lastVal: mode.heightCm,
|
||||
unit: TranslationBase.of(context).cm,
|
||||
),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () => isNotOneAppointment ? Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: VitalSignItemDetailsScreen(
|
||||
pageKey: vitalSignDetails.Weight,
|
||||
pageTitle: TranslationBase.of(context).weight,
|
||||
vitalList: mode.patientVitalSignsHistory,
|
||||
),
|
||||
),
|
||||
):null,
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context).weight,
|
||||
imagePath: "${imageBasePath}vital_weight.png",
|
||||
unit: TranslationBase.of(context).kg,
|
||||
lastVal: mode.weightKg,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
onTap: () => isNotOneAppointment ? Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: VitalSignItemDetailsScreen(
|
||||
pageKey: vitalSignDetails.BodyMeasurements,
|
||||
pageTitle: TranslationBase.of(context)
|
||||
.bodyMeasurements,
|
||||
vitalList: mode.patientVitalSignsHistory,
|
||||
),
|
||||
),
|
||||
): null,
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context).body,
|
||||
imagePath: "${imageBasePath}vital_body_mass.png",
|
||||
lastVal: mode.bodyMax,
|
||||
unit: TranslationBase.of(context).mass,
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () => isNotOneAppointment ? Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: VitalSignItemDetailsScreen(
|
||||
pageKey: vitalSignDetails.Temperature,
|
||||
pageTitle:
|
||||
TranslationBase.of(context).temperature,
|
||||
vitalList: mode.patientVitalSignsHistory,
|
||||
),
|
||||
),
|
||||
):null,
|
||||
child: Container(
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context).temperature,
|
||||
imagePath: "${imageBasePath}vital_temperature.png",
|
||||
lastVal: mode.temperatureCelcius,
|
||||
unit: TranslationBase.of(context).tempC,
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
BODY_MEASUREMENTS,
|
||||
arguments: {
|
||||
'title':
|
||||
TranslationBase.of(context).pulse,
|
||||
'key': vitalSignDetails.pulse
|
||||
});
|
||||
},
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context).pulse,
|
||||
url: url + 'heartbeat.png',
|
||||
lastVal: model
|
||||
.patientVitalSignOrderdSubList[0]
|
||||
.pulseBeatPerMinute
|
||||
.toString(),
|
||||
unit: 'M',
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
BODY_MEASUREMENTS,
|
||||
arguments: {
|
||||
'title': TranslationBase.of(context)
|
||||
.respiration,
|
||||
'key': vitalSignDetails.pespiration
|
||||
});
|
||||
},
|
||||
child: VitalSignItem(
|
||||
des:
|
||||
TranslationBase.of(context).respiration,
|
||||
url: url + 'heartbeat.png',
|
||||
lastVal: model
|
||||
.patientVitalSignOrderdSubList[0]
|
||||
.respirationBeatPerMinute
|
||||
.toString(),
|
||||
unit: 'M',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
onTap: () => isNotOneAppointment ? Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: VitalSignItemDetailsScreen(
|
||||
pageKey: vitalSignDetails.heart,
|
||||
pageTitle: TranslationBase.of(context).heart,
|
||||
vitalList: mode.patientVitalSignsHistory,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
BODY_MEASUREMENTS,
|
||||
arguments: {
|
||||
'title': TranslationBase.of(context)
|
||||
.bloodPressure,
|
||||
'key': vitalSignDetails.bloodPressure
|
||||
});
|
||||
},
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context)
|
||||
.bloodPressure,
|
||||
url: url + 'heartbeat.png',
|
||||
lastVal: model
|
||||
.patientVitalSignOrderdSubList[0]
|
||||
.bloodPressure
|
||||
.toString(),
|
||||
unit: '',
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
BODY_MEASUREMENTS,
|
||||
arguments: {
|
||||
'title': TranslationBase.of(context)
|
||||
.oxygenation,
|
||||
'key': vitalSignDetails.oxygenation
|
||||
});
|
||||
},
|
||||
child: VitalSignItem(
|
||||
des:
|
||||
TranslationBase.of(context).oxygenation,
|
||||
url: url + 'heartbeat.png',
|
||||
lastVal: model
|
||||
.patientVitalSignOrderdSubList[0].fIO2
|
||||
.toString(),
|
||||
unit: '',
|
||||
),
|
||||
),
|
||||
],
|
||||
):null,
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context).heart,
|
||||
imagePath: "${imageBasePath}vital_heart_rate.png",
|
||||
lastVal: mode.hartRat,
|
||||
unit: TranslationBase.of(context).bpm,
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () => isNotOneAppointment ? Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: VitalSignItemDetailsScreen(
|
||||
pageKey: vitalSignDetails.Respiration,
|
||||
pageTitle:
|
||||
TranslationBase.of(context).respirationRate,
|
||||
vitalList: mode.patientVitalSignsHistory,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
BODY_MEASUREMENTS,
|
||||
arguments: {
|
||||
'title': TranslationBase.of(context)
|
||||
.painScale,
|
||||
'key': vitalSignDetails.painScale
|
||||
});
|
||||
},
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase
|
||||
.of(context)
|
||||
.painScale,
|
||||
url: url + 'heartbeat.png',
|
||||
),
|
||||
),
|
||||
],
|
||||
):null,
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context).respirationRate,
|
||||
imagePath: "${imageBasePath}vital_respiration.png",
|
||||
lastVal: mode.respirationBeatPerMinute,
|
||||
unit: TranslationBase.of(context).respirationSigns,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
onTap: () => isNotOneAppointment ? Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: VitalSignItemDetailsScreen(
|
||||
pageKey: vitalSignDetails.BloodPressure,
|
||||
pageTitle: TranslationBase.of(context).bloodPressure,
|
||||
vitalList: mode.patientVitalSignsHistory,
|
||||
),
|
||||
),
|
||||
],
|
||||
):null,
|
||||
child: VitalSignItem(
|
||||
des: TranslationBase.of(context).bloodPressure,
|
||||
imagePath: "${imageBasePath}vital_blood-pressure.png",
|
||||
lastVal: mode.bloodPressure,
|
||||
unit: TranslationBase.of(context).sysDias,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Center(
|
||||
child: AppText('No Data'),
|
||||
),
|
||||
),),);
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,122 @@
|
||||
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
|
||||
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
|
||||
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
|
||||
import 'package:doctor_app_flutter/util/date-utils.dart';
|
||||
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
|
||||
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hexcolor/hexcolor.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class VitalSignDetailsWidget extends StatefulWidget {
|
||||
final List<VitalSignHistory> vitalList;
|
||||
final String title1;
|
||||
final String title2;
|
||||
final String viewKey;
|
||||
|
||||
VitalSignDetailsWidget(
|
||||
{Key key, this.vitalList, this.title1, this.title2, this.viewKey});
|
||||
|
||||
@override
|
||||
_VitalSignDetailsWidgetState createState() => _VitalSignDetailsWidgetState();
|
||||
}
|
||||
|
||||
class _VitalSignDetailsWidgetState extends State<VitalSignDetailsWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ProjectViewModel projectViewModel = Provider.of(context);
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)),
|
||||
border: Border.all(color: Colors.grey, width: 1),
|
||||
),
|
||||
margin: EdgeInsets.all(20),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Table(
|
||||
border: TableBorder.symmetric(
|
||||
inside: BorderSide(width: 2.0, color: Colors.grey[300]),
|
||||
),
|
||||
children: fullData(projectViewModel),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<TableRow> fullData(ProjectViewModel projectViewModel) {
|
||||
List<TableRow> tableRow = [];
|
||||
tableRow.add(TableRow(children: [
|
||||
Container(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft:projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0),
|
||||
topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0)
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: AppText(
|
||||
TranslationBase.of(context).date,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
height: 60,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0),
|
||||
topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0)
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: AppText(widget.title2, color: Colors.white),
|
||||
),
|
||||
height: 60),
|
||||
)
|
||||
]));
|
||||
widget.vitalList.forEach((vital) {
|
||||
var data = vital.toJson()[widget.viewKey];
|
||||
if (data != 0)
|
||||
tableRow.add(TableRow(children: [
|
||||
Container(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Center(
|
||||
child: AppText(
|
||||
'${projectViewModel.isArabic ? DateUtils.getWeekDayArabic(vital.vitalSignDate.weekday) : DateUtils.getWeekDay(vital.vitalSignDate.weekday)}, ${vital.vitalSignDate.day} ${projectViewModel.isArabic ? DateUtils.getMonthArabic(vital.vitalSignDate.month) : DateUtils.getMonth(vital.vitalSignDate.month)}, ${vital.vitalSignDate.year} ',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Center(
|
||||
child: AppText(
|
||||
'${vital.toJson()[widget.viewKey]}',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
]));
|
||||
});
|
||||
return tableRow;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.dart';
|
||||
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart';
|
||||
import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_details_blood_pressurewideget.dart';
|
||||
import 'package:doctor_app_flutter/widgets/charts/app_time_series_chart.dart';
|
||||
import 'package:doctor_app_flutter/widgets/shared/app_expandable_notifier.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:charts_flutter/flutter.dart' as charts;
|
||||
|
||||
import 'LineChartCurved.dart';
|
||||
import 'LineChartCurvedBloodPressure.dart';
|
||||
|
||||
class VitalSingChartBloodPressure extends StatelessWidget {
|
||||
VitalSingChartBloodPressure({
|
||||
Key key,
|
||||
@required this.vitalList,
|
||||
@required this.name,
|
||||
@required this.viewKey1,
|
||||
@required this.viewKey2,
|
||||
@required this.title1,
|
||||
@required this.title2,
|
||||
@required this.title3,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<VitalSignHistory> vitalList;
|
||||
final String name;
|
||||
final String viewKey1;
|
||||
final String viewKey2;
|
||||
final String title1;
|
||||
final String title2;
|
||||
final String title3;
|
||||
List<TimeSeriesSales2> timeSeriesData1 = [];
|
||||
List<TimeSeriesSales2> timeSeriesData2 = [];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
generateData();
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
AppExpandableNotifier(
|
||||
// isExpand: true,
|
||||
headerWid: LineChartCurvedBloodPressure(
|
||||
title: name,
|
||||
timeSeries1: timeSeriesData1,
|
||||
timeSeries2: timeSeriesData2,
|
||||
indexes: timeSeriesData1.length ~/ 5.5,
|
||||
),
|
||||
bodyWid: VitalSignBloodPressureWidget(
|
||||
vitalList: vitalList,
|
||||
title1: title1,
|
||||
title2: title2,
|
||||
title3: title3,
|
||||
viewKey1: viewKey1,
|
||||
viewKey2: viewKey2,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
generateData() {
|
||||
if (vitalList.length > 0) {
|
||||
vitalList.reversed.toList().forEach(
|
||||
(element) {
|
||||
if (element.toJson()[viewKey1]?.toInt() != 0)
|
||||
timeSeriesData1.add(
|
||||
TimeSeriesSales2(
|
||||
new DateTime(element.vitalSignDate.year,
|
||||
element.vitalSignDate.month, element.vitalSignDate.day),
|
||||
element.toJson()[viewKey1].toDouble(),
|
||||
),
|
||||
);
|
||||
if (element.toJson()[viewKey2]?.toInt() != 0)
|
||||
timeSeriesData2.add(
|
||||
TimeSeriesSales2(
|
||||
new DateTime(element.vitalSignDate.year,
|
||||
element.vitalSignDate.month, element.vitalSignDate.day),
|
||||
element.toJson()[viewKey2].toDouble(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:charts_flutter/flutter.dart' as charts;
|
||||
|
||||
class AppBarChart extends StatelessWidget {
|
||||
const AppBarChart({
|
||||
Key key,
|
||||
@required this.seriesList,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<charts.Series> seriesList;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 400,
|
||||
margin: EdgeInsets.only(top: 60),
|
||||
child: charts.BarChart(
|
||||
seriesList,
|
||||
// animate: animate,
|
||||
|
||||
/// Customize the primary measure axis using a small tick renderer.
|
||||
/// Use String instead of num for ordinal domain axis
|
||||
/// (typically bar charts).
|
||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
||||
renderSpec: new charts.GridlineRendererSpec(
|
||||
// Display the measure axis labels below the gridline.
|
||||
//
|
||||
// 'Before' & 'after' follow the axis value direction.
|
||||
// Vertical axes draw 'before' below & 'after' above the tick.
|
||||
// Horizontal axes draw 'before' left & 'after' right the tick.
|
||||
labelAnchor: charts.TickLabelAnchor.before,
|
||||
|
||||
// Left justify the text in the axis.
|
||||
//
|
||||
// Note: outside means that the secondary measure axis would right
|
||||
// justify.
|
||||
labelJustification:
|
||||
charts.TickLabelJustification.outside,
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:charts_flutter/flutter.dart' as charts;
|
||||
|
||||
/// chart line
|
||||
/// [seriesList] charts series
|
||||
/// [chartTitle] the charts title
|
||||
/// [animate] enable and disable animate on create chart
|
||||
/// [includeArea] chart include Area
|
||||
/// [stacked] stacked chart over the design
|
||||
class AppLineChart extends StatelessWidget {
|
||||
final List<charts.Series> seriesList;
|
||||
final String chartTitle;
|
||||
final bool animate;
|
||||
final bool includeArea;
|
||||
final bool stacked;
|
||||
|
||||
AppLineChart(
|
||||
{Key key,
|
||||
@required this.seriesList,
|
||||
this.chartTitle,
|
||||
this.animate = true,
|
||||
this.includeArea = false,
|
||||
this.stacked = true});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
chartTitle,
|
||||
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Expanded(
|
||||
child: charts.LineChart(seriesList,
|
||||
defaultRenderer: charts.LineRendererConfig(
|
||||
includeArea: false, stacked: true),
|
||||
animate: animate),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
import 'package:charts_flutter/flutter.dart' as charts;
|
||||
import 'package:charts_flutter/flutter.dart';
|
||||
import 'package:doctor_app_flutter/config/size_config.dart';
|
||||
import 'package:doctor_app_flutter/widgets/data_display/list/flexible_container.dart';
|
||||
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// App Time Series Chart
|
||||
/// [seriesList] the series list
|
||||
/// [chartName] the name of the chart
|
||||
/// [startDate] the start date
|
||||
/// [endDate] the end date
|
||||
class AppTimeSeriesChart extends StatelessWidget {
|
||||
AppTimeSeriesChart({
|
||||
Key key,
|
||||
@required this.seriesList,
|
||||
this.chartName = '',
|
||||
this.startDate,
|
||||
this.endDate,
|
||||
});
|
||||
|
||||
final String chartName;
|
||||
final List<Series<dynamic, DateTime>> seriesList;
|
||||
final DateTime startDate;
|
||||
final DateTime endDate;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FlexibleContainer(
|
||||
heightFactor: 0.47,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
AppText(chartName, fontSize: SizeConfig.textMultiplier * 3),
|
||||
Container(
|
||||
height: SizeConfig.realScreenHeight * 0.37,
|
||||
child: Center(
|
||||
child: Container(
|
||||
child: charts.TimeSeriesChart(
|
||||
seriesList,
|
||||
animate: true,
|
||||
behaviors: [
|
||||
charts.RangeAnnotation(
|
||||
[
|
||||
charts.RangeAnnotationSegment(startDate, endDate,
|
||||
charts.RangeAnnotationAxisType.domain ),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TimeSeriesSales {
|
||||
final DateTime time;
|
||||
final int sales;
|
||||
|
||||
TimeSeriesSales(this.time, this.sales);
|
||||
}
|
||||
|
||||
class TimeSeriesSales2 {
|
||||
final DateTime time;
|
||||
final double sales;
|
||||
|
||||
TimeSeriesSales2(this.time, this.sales);
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Custom Item widget
|
||||
/// [startIcon] icon at the start of the widget
|
||||
/// [startIconSize] icon size of start icon
|
||||
/// [startIconColor] icon color of start icon
|
||||
/// [endIcon] icon at the end of the widget
|
||||
/// [endIconSize] icon size of end icon
|
||||
/// [endIconColor] icon color of end icon
|
||||
/// [disabled] disabled on tap function
|
||||
/// [onTap] opTap function
|
||||
/// [padding] padding of the widget
|
||||
/// [child] child of the widget
|
||||
/// [decoration] decoration of the widget
|
||||
class CustomItem extends StatelessWidget {
|
||||
final IconData startIcon;
|
||||
final double startIconSize;
|
||||
final Color startIconColor;
|
||||
final IconData endIcon;
|
||||
final double endIconSize;
|
||||
final Color endIconColor;
|
||||
final bool disabled;
|
||||
final Function onTap;
|
||||
final EdgeInsets padding;
|
||||
final Widget child;
|
||||
final BoxDecoration decoration;
|
||||
|
||||
CustomItem(
|
||||
{Key key,
|
||||
this.startIcon,
|
||||
this.disabled: false,
|
||||
this.onTap,
|
||||
this.startIconColor,
|
||||
this.endIcon = EvaIcons.chevronRight,
|
||||
this.padding,
|
||||
this.child,
|
||||
this.endIconColor,
|
||||
this.endIconSize = 20,
|
||||
this.decoration,
|
||||
this.startIconSize = 19})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IgnorePointer(
|
||||
ignoring: disabled,
|
||||
child: Container(
|
||||
decoration: decoration != null ? decoration : BoxDecoration(),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
if (onTap != null) onTap();
|
||||
},
|
||||
child: Padding(
|
||||
padding: padding != null
|
||||
? padding
|
||||
: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
if (startIcon != null)
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Icon(
|
||||
startIcon,
|
||||
color: startIconColor ?? Theme.of(context).primaryColor,
|
||||
size: startIconSize,
|
||||
),
|
||||
),
|
||||
if (startIcon != null) SizedBox(width: 18.0),
|
||||
Expanded(
|
||||
child: child,
|
||||
flex: 10,
|
||||
),
|
||||
endIcon == null
|
||||
? Expanded(child: Container())
|
||||
: Expanded(
|
||||
flex: 1,
|
||||
child: Icon(
|
||||
endIcon,
|
||||
color: endIconColor != null
|
||||
? endIconColor
|
||||
: Colors.grey[500],
|
||||
size: endIconSize,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
import 'package:flutter/material.dart';
|
||||
/// Flexible container widget
|
||||
/// [widthFactor] If non-null, the fraction of the incoming width given to the child.
|
||||
/// If non-null, the child is given a tight width constraint that is the max
|
||||
/// incoming width constraint multiplied by this factor.
|
||||
/// If null, the incoming width constraints are passed to the child
|
||||
|
||||
/// [heightFactor]If non-null, the fraction of the incoming height given to the child.
|
||||
/// If non-null, the child is given a tight height constraint that is the max
|
||||
/// incoming height constraint multiplied by this factor.
|
||||
/// If null, the incoming height constraints are passed to the child
|
||||
/// [padding] add padding to the container
|
||||
/// [child] child widget inside the container
|
||||
class FlexibleContainer extends StatelessWidget {
|
||||
final double widthFactor;
|
||||
final double heightFactor;
|
||||
final EdgeInsets padding;
|
||||
final Widget child;
|
||||
|
||||
FlexibleContainer({
|
||||
Key key,
|
||||
this.widthFactor = 0.9,
|
||||
this.heightFactor = 1,
|
||||
this.padding,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
// widthFactor: widthFactor,
|
||||
// heightFactor: heightFactor,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
child: Material(
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Container(
|
||||
padding: padding,
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Theme.of(context).dividerColor, width: 2.0),
|
||||
borderRadius: BorderRadius.circular(8.0)),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// FadePage animation
|
||||
/// [page]
|
||||
class FadePage extends PageRouteBuilder {
|
||||
final Widget page;
|
||||
FadePage({this.page})
|
||||
: super(
|
||||
opaque: false,
|
||||
fullscreenDialog: true,
|
||||
barrierDismissible: true,
|
||||
barrierColor: Colors.black.withOpacity(0.8),
|
||||
pageBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
) =>
|
||||
page,
|
||||
transitionDuration: Duration(milliseconds: 300),
|
||||
transitionsBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child,
|
||||
) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: child
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
///Slide Up Page Route
|
||||
/// [widget] widget we need to slide up
|
||||
/// [fullscreenDialog] show the widget as full screen dialog
|
||||
/// [opaque] When an opaque route's entrance transition is complete, the routes behind the opaque route will not be built to save resources.
|
||||
class SlideUpPageRoute extends PageRouteBuilder {
|
||||
final Widget widget;
|
||||
final bool fullscreenDialog;
|
||||
final bool opaque;
|
||||
|
||||
SlideUpPageRoute(
|
||||
{this.widget, this.fullscreenDialog = false, this.opaque = true})
|
||||
: super(
|
||||
pageBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
) {
|
||||
return widget;
|
||||
},
|
||||
fullscreenDialog: fullscreenDialog,
|
||||
opaque: opaque,
|
||||
barrierColor: Color.fromRGBO(0, 0, 0, 0.5),
|
||||
barrierDismissible: true,
|
||||
transitionDuration: Duration(milliseconds: 800),
|
||||
transitionsBuilder: ((BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child) {
|
||||
var begin = Offset(0.0, 1.0);
|
||||
var end = Offset.zero;
|
||||
var curve = Curves.easeInOutQuint;
|
||||
|
||||
var tween =
|
||||
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
|
||||
|
||||
return SlideTransition(
|
||||
position: animation.drive(tween), child: child);
|
||||
}),
|
||||
);
|
||||
}
|