working on vital Sign feature with Charts
parent
307463865b
commit
8424e92c4b
@ -1,136 +1,257 @@
|
|||||||
class VitalSignData {
|
class VitalSignData {
|
||||||
int appointmentNo;
|
var transNo;
|
||||||
int bloodPressureCuffLocation;
|
var projectID;
|
||||||
int bloodPressureCuffSize;
|
var weightKg;
|
||||||
int bloodPressureHigher;
|
var heightCm;
|
||||||
int bloodPressureLower;
|
var temperatureCelcius;
|
||||||
int bloodPressurePatientPosition;
|
var pulseBeatPerMinute;
|
||||||
|
var respirationBeatPerMinute;
|
||||||
|
var bloodPressureLower;
|
||||||
|
var bloodPressureHigher;
|
||||||
|
var sAO2;
|
||||||
|
var fIO2;
|
||||||
|
var painScore;
|
||||||
var bodyMassIndex;
|
var bodyMassIndex;
|
||||||
int fio2;
|
var headCircumCm;
|
||||||
int headCircumCm;
|
var leanBodyWeightLbs;
|
||||||
int heightCm;
|
var idealBodyWeightLbs;
|
||||||
int idealBodyWeightLbs;
|
var temperatureCelciusMethod;
|
||||||
|
var pulseRhythm;
|
||||||
|
var respirationPattern;
|
||||||
|
var bloodPressureCuffLocation;
|
||||||
|
var bloodPressureCuffSize;
|
||||||
|
var bloodPressurePatientPosition;
|
||||||
|
var painLocation;
|
||||||
|
var painDuration;
|
||||||
|
var painCharacter;
|
||||||
|
var painFrequency;
|
||||||
bool isPainManagementDone;
|
bool isPainManagementDone;
|
||||||
|
var status;
|
||||||
bool isVitalsRequired;
|
bool isVitalsRequired;
|
||||||
int leanBodyWeightLbs;
|
var patientID;
|
||||||
String painCharacter;
|
var createdOn;
|
||||||
String painDuration;
|
var doctorID;
|
||||||
String painFrequency;
|
var clinicID;
|
||||||
String painLocation;
|
var triageCategory;
|
||||||
int painScore;
|
var gCScore;
|
||||||
int patientMRN;
|
var lineItemNo;
|
||||||
int patientType;
|
DateTime vitalSignDate;
|
||||||
int pulseBeatPerMinute;
|
var actualTimeTaken;
|
||||||
int pulseRhythm;
|
var sugarLevel;
|
||||||
int respirationBeatPerMinute;
|
var fBS;
|
||||||
int respirationPattern;
|
var rBS;
|
||||||
int sao2;
|
var observationType;
|
||||||
int status;
|
var heartRate;
|
||||||
int temperatureCelcius;
|
var muscleTone;
|
||||||
int temperatureCelciusMethod;
|
var reflexIrritability;
|
||||||
int waistSizeInch;
|
var bodyColor;
|
||||||
int weightKg;
|
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;
|
||||||
|
|
||||||
VitalSignData(
|
VitalSignData(
|
||||||
{this.appointmentNo,
|
{this.transNo,
|
||||||
this.bloodPressureCuffLocation,
|
this.projectID,
|
||||||
this.bloodPressureCuffSize,
|
this.weightKg,
|
||||||
this.bloodPressureHigher,
|
this.heightCm,
|
||||||
|
this.temperatureCelcius,
|
||||||
|
this.pulseBeatPerMinute,
|
||||||
|
this.respirationBeatPerMinute,
|
||||||
this.bloodPressureLower,
|
this.bloodPressureLower,
|
||||||
this.bloodPressurePatientPosition,
|
this.bloodPressureHigher,
|
||||||
|
this.sAO2,
|
||||||
|
this.fIO2,
|
||||||
|
this.painScore,
|
||||||
this.bodyMassIndex,
|
this.bodyMassIndex,
|
||||||
this.fio2,
|
|
||||||
this.headCircumCm,
|
this.headCircumCm,
|
||||||
this.heightCm,
|
|
||||||
this.idealBodyWeightLbs,
|
|
||||||
this.isPainManagementDone,
|
|
||||||
this.isVitalsRequired,
|
|
||||||
this.leanBodyWeightLbs,
|
this.leanBodyWeightLbs,
|
||||||
this.painCharacter,
|
this.idealBodyWeightLbs,
|
||||||
this.painDuration,
|
this.temperatureCelciusMethod,
|
||||||
this.painFrequency,
|
|
||||||
this.painLocation,
|
|
||||||
this.painScore,
|
|
||||||
this.patientMRN,
|
|
||||||
this.patientType,
|
|
||||||
this.pulseBeatPerMinute,
|
|
||||||
this.pulseRhythm,
|
this.pulseRhythm,
|
||||||
this.respirationBeatPerMinute,
|
|
||||||
this.respirationPattern,
|
this.respirationPattern,
|
||||||
this.sao2,
|
this.bloodPressureCuffLocation,
|
||||||
|
this.bloodPressureCuffSize,
|
||||||
|
this.bloodPressurePatientPosition,
|
||||||
|
this.painLocation,
|
||||||
|
this.painDuration,
|
||||||
|
this.painCharacter,
|
||||||
|
this.painFrequency,
|
||||||
|
this.isPainManagementDone,
|
||||||
this.status,
|
this.status,
|
||||||
this.temperatureCelcius,
|
this.isVitalsRequired,
|
||||||
this.temperatureCelciusMethod,
|
this.patientID,
|
||||||
this.waistSizeInch,
|
this.createdOn,
|
||||||
this.weightKg});
|
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});
|
||||||
|
|
||||||
VitalSignData.fromJson(Map<String, dynamic> json) {
|
VitalSignData.fromJson(Map<String, dynamic> json) {
|
||||||
appointmentNo = json['appointmentNo'];
|
transNo = json['TransNo'];
|
||||||
bloodPressureCuffLocation = json['bloodPressureCuffLocation'];
|
projectID = json['ProjectID'];
|
||||||
bloodPressureCuffSize = json['bloodPressureCuffSize'];
|
weightKg = json['WeightKg'];
|
||||||
bloodPressureHigher = json['bloodPressureHigher'];
|
heightCm = json['HeightCm'];
|
||||||
bloodPressureLower = json['bloodPressureLower'];
|
temperatureCelcius = json['TemperatureCelcius'];
|
||||||
bloodPressurePatientPosition = json['bloodPressurePatientPosition'];
|
pulseBeatPerMinute = json['PulseBeatPerMinute'];
|
||||||
bodyMassIndex = json['bodyMassIndex'];
|
respirationBeatPerMinute = json['RespirationBeatPerMinute'];
|
||||||
fio2 = json['fio2'];
|
bloodPressureLower = json['BloodPressureLower'];
|
||||||
headCircumCm = json['headCircumCm'];
|
bloodPressureHigher = json['BloodPressureHigher'];
|
||||||
heightCm = json['heightCm'];
|
sAO2 = json['SAO2'];
|
||||||
idealBodyWeightLbs = json['idealBodyWeightLbs'];
|
fIO2 = json['FIO2'];
|
||||||
isPainManagementDone = json['isPainManagementDone'];
|
painScore = json['PainScore'];
|
||||||
isVitalsRequired = json['isVitalsRequired'];
|
bodyMassIndex = json['BodyMassIndex'];
|
||||||
leanBodyWeightLbs = json['leanBodyWeightLbs'];
|
headCircumCm = json['HeadCircumCm'];
|
||||||
painCharacter = json['painCharacter'];
|
leanBodyWeightLbs = json['LeanBodyWeightLbs'];
|
||||||
painDuration = json['painDuration'];
|
idealBodyWeightLbs = json['IdealBodyWeightLbs'];
|
||||||
painFrequency = json['painFrequency'];
|
temperatureCelciusMethod = json['TemperatureCelciusMethod'];
|
||||||
painLocation = json['painLocation'];
|
pulseRhythm = json['PulseRhythm'];
|
||||||
painScore = json['painScore'];
|
respirationPattern = json['RespirationPattern'];
|
||||||
patientMRN = json['patientMRN'];
|
bloodPressureCuffLocation = json['BloodPressureCuffLocation'];
|
||||||
patientType = json['patientType'];
|
bloodPressureCuffSize = json['BloodPressureCuffSize'];
|
||||||
pulseBeatPerMinute = json['pulseBeatPerMinute'];
|
bloodPressurePatientPosition = json['BloodPressurePatientPosition'];
|
||||||
pulseRhythm = json['pulseRhythm'];
|
painLocation = json['PainLocation'];
|
||||||
respirationBeatPerMinute = json['respirationBeatPerMinute'];
|
painDuration = json['PainDuration'];
|
||||||
respirationPattern = json['respirationPattern'];
|
painCharacter = json['PainCharacter'];
|
||||||
sao2 = json['sao2'];
|
painFrequency = json['PainFrequency'];
|
||||||
status = json['status'];
|
isPainManagementDone = json['IsPainManagementDone'];
|
||||||
temperatureCelcius = json['temperatureCelcius'];
|
status = json['Status'];
|
||||||
temperatureCelciusMethod = json['temperatureCelciusMethod'];
|
isVitalsRequired = json['IsVitalsRequired'];
|
||||||
waistSizeInch = json['waistSizeInch'];
|
patientID = json['PatientID'];
|
||||||
weightKg = json['weightKg'];
|
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() {
|
Map<String, dynamic> toJson() {
|
||||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
data['appointmentNo'] = this.appointmentNo;
|
data['TransNo'] = this.transNo;
|
||||||
data['bloodPressureCuffLocation'] = this.bloodPressureCuffLocation;
|
data['ProjectID'] = this.projectID;
|
||||||
data['bloodPressureCuffSize'] = this.bloodPressureCuffSize;
|
data['WeightKg'] = this.weightKg;
|
||||||
data['bloodPressureHigher'] = this.bloodPressureHigher;
|
data['HeightCm'] = this.heightCm;
|
||||||
data['bloodPressureLower'] = this.bloodPressureLower;
|
data['TemperatureCelcius'] = this.temperatureCelcius;
|
||||||
data['bloodPressurePatientPosition'] = this.bloodPressurePatientPosition;
|
data['PulseBeatPerMinute'] = this.pulseBeatPerMinute;
|
||||||
data['bodyMassIndex'] = this.bodyMassIndex;
|
data['RespirationBeatPerMinute'] = this.respirationBeatPerMinute;
|
||||||
data['fio2'] = this.fio2;
|
data['BloodPressureLower'] = this.bloodPressureLower;
|
||||||
data['headCircumCm'] = this.headCircumCm;
|
data['BloodPressureHigher'] = this.bloodPressureHigher;
|
||||||
data['heightCm'] = this.heightCm;
|
data['SAO2'] = this.sAO2;
|
||||||
data['idealBodyWeightLbs'] = this.idealBodyWeightLbs;
|
data['FIO2'] = this.fIO2;
|
||||||
data['isPainManagementDone'] = this.isPainManagementDone;
|
data['PainScore'] = this.painScore;
|
||||||
data['isVitalsRequired'] = this.isVitalsRequired;
|
data['BodyMassIndex'] = this.bodyMassIndex;
|
||||||
data['leanBodyWeightLbs'] = this.leanBodyWeightLbs;
|
data['HeadCircumCm'] = this.headCircumCm;
|
||||||
data['painCharacter'] = this.painCharacter;
|
data['LeanBodyWeightLbs'] = this.leanBodyWeightLbs;
|
||||||
data['painDuration'] = this.painDuration;
|
data['IdealBodyWeightLbs'] = this.idealBodyWeightLbs;
|
||||||
data['painFrequency'] = this.painFrequency;
|
data['TemperatureCelciusMethod'] = this.temperatureCelciusMethod;
|
||||||
data['painLocation'] = this.painLocation;
|
data['PulseRhythm'] = this.pulseRhythm;
|
||||||
data['painScore'] = this.painScore;
|
data['RespirationPattern'] = this.respirationPattern;
|
||||||
data['patientMRN'] = this.patientMRN;
|
data['BloodPressureCuffLocation'] = this.bloodPressureCuffLocation;
|
||||||
data['patientType'] = this.patientType;
|
data['BloodPressureCuffSize'] = this.bloodPressureCuffSize;
|
||||||
data['pulseBeatPerMinute'] = this.pulseBeatPerMinute;
|
data['BloodPressurePatientPosition'] = this.bloodPressurePatientPosition;
|
||||||
data['pulseRhythm'] = this.pulseRhythm;
|
data['PainLocation'] = this.painLocation;
|
||||||
data['respirationBeatPerMinute'] = this.respirationBeatPerMinute;
|
data['PainDuration'] = this.painDuration;
|
||||||
data['respirationPattern'] = this.respirationPattern;
|
data['PainCharacter'] = this.painCharacter;
|
||||||
data['sao2'] = this.sao2;
|
data['PainFrequency'] = this.painFrequency;
|
||||||
data['status'] = this.status;
|
data['IsPainManagementDone'] = this.isPainManagementDone;
|
||||||
data['temperatureCelcius'] = this.temperatureCelcius;
|
data['Status'] = this.status;
|
||||||
data['temperatureCelciusMethod'] = this.temperatureCelciusMethod;
|
data['IsVitalsRequired'] = this.isVitalsRequired;
|
||||||
data['waistSizeInch'] = this.waistSizeInch;
|
data['PatientID'] = this.patientID;
|
||||||
data['weightKg'] = this.weightKg;
|
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;
|
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,145 @@
|
|||||||
|
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/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<VitalSignData> 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,196 @@
|
|||||||
import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart';
|
// import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item.dart';
|
||||||
import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_req_model.dart';
|
// import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart';
|
||||||
import 'package:doctor_app_flutter/screens/base/base_view.dart';
|
// import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
|
||||||
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
|
// import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
|
||||||
import 'package:doctor_app_flutter/widgets/shared/errors/dr_app_embedded_error.dart';
|
// import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
// import 'package:flutter/material.dart';
|
||||||
|
//
|
||||||
import '../../../../config/shared_pref_kay.dart';
|
// class VitalSignDetailsScreen extends StatelessWidget {
|
||||||
import '../../../../config/size_config.dart';
|
// static const String url = "assets/images/";
|
||||||
import '../../../../lookups/patient_lookup.dart';
|
//
|
||||||
import '../../../../models/patient/patiant_info_model.dart';
|
// int appointmentNo;
|
||||||
import '../../../../models/patient/vital_sign/vital_sign_res_model.dart';
|
// int projectID;
|
||||||
import '../../../../routes.dart';
|
// bool isNotOneAppointment;
|
||||||
import '../../../../screens/patients/profile/vital_sign/vital_sign_item.dart';
|
// VitalSignDetailsScreen({this.appointmentNo, this.projectID,this.isNotOneAppointment=true});
|
||||||
import '../../../../util/dr_app_shared_pref.dart';
|
// List<ImagesInfo> imagesInfo = List();
|
||||||
import '../../../../widgets/shared/app_scaffold_widget.dart';
|
//
|
||||||
|
//
|
||||||
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
class VitalSignDetailsScreen extends StatefulWidget {
|
// imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/ar/0.png'));
|
||||||
// VitalSignDetailsScreen({Key key, this.vitalSing}) : super(key: key);
|
// imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/en/1.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/my-vital-signs/ar/1.png'));
|
||||||
@override
|
// return BaseView<VitalSignViewModel>(
|
||||||
_VitalSignDetailsScreenState createState() => _VitalSignDetailsScreenState();
|
// onModelReady: appointmentNo != null && projectID != null
|
||||||
}
|
// ? (model) => model.getPatientVitalSign(
|
||||||
|
// appointmentNo: appointmentNo, projectID: projectID)
|
||||||
class _VitalSignDetailsScreenState extends State<VitalSignDetailsScreen> {
|
// : (model) => model.getPatientVitalSign(),
|
||||||
VitalSignResModel vitalSing;
|
// builder: (_, mode, widget) => AppScaffold(
|
||||||
String url = "assets/images/";
|
// isShowAppBar: true,
|
||||||
|
// appBarTitle: TranslationBase.of(context).vitalSigns,
|
||||||
|
// baseViewModel: mode,
|
||||||
/*
|
// description: TranslationBase.of(context).infoSigns,
|
||||||
*@author: Elham Rababah
|
// imagesInfo: imagesInfo,
|
||||||
*@Date:28/4/2020
|
// body: mode.vitalSignResModelList.length > 0
|
||||||
*@param: context
|
// ? Container(
|
||||||
*@return:
|
// child: ListView(
|
||||||
*@desc: getVitalSignList Function
|
// children: <Widget>[
|
||||||
*/
|
// Row(
|
||||||
getVitalSignList(BuildContext context, PatientViewModel model) async {
|
// children: <Widget>[
|
||||||
final routeArgs = ModalRoute.of(context).settings.arguments as Map;
|
// InkWell(
|
||||||
PatiantInformtion patient = routeArgs['patient'];
|
// onTap: () =>isNotOneAppointment? Navigator.push(
|
||||||
String token = await sharedPref.getString(TOKEN);
|
// context,
|
||||||
String type = await sharedPref.getString(SLECTED_PATIENT_TYPE);
|
// FadePage(
|
||||||
int inOutpatientType = 1;
|
// page: VitalSignItemDetailsScreen(
|
||||||
if (type == '0') {
|
// pageKey: VitalSignDetails.Height,
|
||||||
inOutpatientType = 2;
|
// pageTitle: TranslationBase.of(context).height,
|
||||||
}
|
// vitalList: mode.vitalSignResModelList,
|
||||||
print(type);
|
// ),
|
||||||
VitalSignReqModel vitalSignReqModel = VitalSignReqModel(
|
// ),
|
||||||
patientID: patient.patientId,
|
// ):null,
|
||||||
projectID: patient.projectId,
|
// child: Container(
|
||||||
tokenID: token,
|
// child: VitalSignItem(
|
||||||
patientTypeID: patient.patientType,
|
// des: TranslationBase.of(context).height,
|
||||||
inOutpatientType: inOutpatientType,
|
// icon: DQIcons.height,
|
||||||
languageID: 2,
|
// lastVal: mode.heightCm,
|
||||||
transNo:
|
// unit: TranslationBase.of(context).cm,
|
||||||
patient.admissionNo != null ? int.parse(patient.admissionNo) : 0);
|
// ),
|
||||||
model.getPatientVitalSign(vitalSignReqModel.toJson());
|
// ),
|
||||||
}
|
// ),
|
||||||
|
// InkWell(
|
||||||
|
// onTap: () => isNotOneAppointment ? Navigator.push(
|
||||||
|
// context,
|
||||||
final double contWidth = SizeConfig.realScreenWidth * 0.70;
|
// FadePage(
|
||||||
|
// page: VitalSignItemDetailsScreen(
|
||||||
@override
|
// pageKey: VitalSignDetails.Weight,
|
||||||
Widget build(BuildContext context) {
|
// pageTitle: TranslationBase.of(context).weight,
|
||||||
final routeArgs = ModalRoute.of(context).settings.arguments as Map;
|
// vitalList: mode.vitalSignResModelList,
|
||||||
vitalSing = routeArgs['vitalSing'];
|
// ),
|
||||||
return BaseView<PatientViewModel>(
|
// ),
|
||||||
onModelReady: (model) => getVitalSignList(context, model),
|
// ):null,
|
||||||
builder: (_, model, w) => AppScaffold(
|
// child: VitalSignItem(
|
||||||
baseViewModel: model,
|
// des: TranslationBase.of(context).weight,
|
||||||
appBarTitle: TranslationBase.of(context).vitalSign,
|
// icon: DQIcons.weight_scale,
|
||||||
body: model.patientVitalSignOrderdSubList.length == 0
|
// unit: TranslationBase.of(context).kg,
|
||||||
? DrAppEmbeddedError(
|
// lastVal: mode.weightKg,
|
||||||
error: 'You don\'t have any vital Sings')
|
// ),
|
||||||
: Container(
|
// ),
|
||||||
child: Column(
|
// ],
|
||||||
children: <Widget>[
|
// ),
|
||||||
Row(
|
// Row(
|
||||||
children: <Widget>[
|
// children: <Widget>[
|
||||||
InkWell(
|
// InkWell(
|
||||||
onTap: () {
|
// onTap: () => isNotOneAppointment ? Navigator.push(
|
||||||
Navigator.of(context).pushNamed(
|
// context,
|
||||||
BODY_MEASUREMENTS,
|
// FadePage(
|
||||||
arguments: {
|
// page: VitalSignItemDetailsScreen(
|
||||||
'title': TranslationBase.of(context)
|
// pageKey: vitalSignDetails.BodyMeasurements,
|
||||||
.bodyMeasurements,
|
// pageTitle: TranslationBase.of(context)
|
||||||
'key':
|
// .bodyMeasurements,
|
||||||
vitalSignDetails.bodyMeasurements
|
// vitalList: mode.vitalSignResModelList,
|
||||||
});
|
// ),
|
||||||
},
|
// ),
|
||||||
child: Container(
|
// ): null,
|
||||||
child: VitalSignItem(
|
// child: VitalSignItem(
|
||||||
des: TranslationBase.of(context)
|
// des: TranslationBase.of(context).body,
|
||||||
.bodyMeasurements,
|
// icon: DQIcons.bmi,
|
||||||
url: url + 'heartbeat.png',
|
// lastVal: mode.bodyMax,
|
||||||
lastVal: model
|
// unit: TranslationBase.of(context).mass,
|
||||||
.patientVitalSignOrderdSubList[0]
|
// ),
|
||||||
.heightCm
|
// ),
|
||||||
.toString(),
|
// InkWell(
|
||||||
unit: 'Cm',
|
// onTap: () => isNotOneAppointment ? Navigator.push(
|
||||||
),
|
// context,
|
||||||
),
|
// FadePage(
|
||||||
),
|
// page: VitalSignItemDetailsScreen(
|
||||||
InkWell(
|
// pageKey: VitalSignDetails.Temperature,
|
||||||
onTap: () {
|
// pageTitle:
|
||||||
Navigator.of(context).pushNamed(
|
// TranslationBase.of(context).temperature,
|
||||||
BODY_MEASUREMENTS,
|
// vitalList: mode.vitalSignResModelList,
|
||||||
arguments: {
|
// ),
|
||||||
'title': TranslationBase.of(context)
|
// ),
|
||||||
.temperature,
|
// ):null,
|
||||||
'key': vitalSignDetails.temperature,
|
// child: Container(
|
||||||
});
|
// child: VitalSignItem(
|
||||||
},
|
// des: TranslationBase.of(context).temperature,
|
||||||
child: Container(
|
// icon: DQIcons.thermometer,
|
||||||
child: VitalSignItem(
|
// lastVal: mode.temperatureCelcius,
|
||||||
des: TranslationBase.of(context)
|
// unit: TranslationBase.of(context).tempC,
|
||||||
.temperature,
|
// ),
|
||||||
url: url + 'heartbeat.png',
|
// ),
|
||||||
lastVal: model
|
// ),
|
||||||
.patientVitalSignOrderdSubList[0]
|
// ],
|
||||||
.temperatureCelcius
|
// ),
|
||||||
.toString(),
|
// Row(
|
||||||
unit: 'C',
|
// children: <Widget>[
|
||||||
),
|
// InkWell(
|
||||||
),
|
// onTap: () => isNotOneAppointment ? Navigator.push(
|
||||||
),
|
// context,
|
||||||
],
|
// FadePage(
|
||||||
),
|
// page: VitalSignItemDetailsScreen(
|
||||||
Row(
|
// pageKey: VitalSignDetails.heart,
|
||||||
children: <Widget>[
|
// pageTitle: TranslationBase.of(context).heart,
|
||||||
InkWell(
|
// vitalList: mode.vitalSignResModelList,
|
||||||
onTap: () {
|
// ),
|
||||||
Navigator.of(context).pushNamed(
|
// ),
|
||||||
BODY_MEASUREMENTS,
|
// ):null,
|
||||||
arguments: {
|
// child: VitalSignItem(
|
||||||
'title':
|
// des: TranslationBase.of(context).heart,
|
||||||
TranslationBase.of(context).pulse,
|
// icon: DQIcons.heart,
|
||||||
'key': vitalSignDetails.pulse
|
// lastVal: mode.hartRat,
|
||||||
});
|
// unit: TranslationBase.of(context).bpm,
|
||||||
},
|
// ),
|
||||||
child: VitalSignItem(
|
// ),
|
||||||
des: TranslationBase.of(context).pulse,
|
// InkWell(
|
||||||
url: url + 'heartbeat.png',
|
// onTap: () => isNotOneAppointment ? Navigator.push(
|
||||||
lastVal: model
|
// context,
|
||||||
.patientVitalSignOrderdSubList[0]
|
// FadePage(
|
||||||
.pulseBeatPerMinute
|
// page: VitalSignItemDetailsScreen(
|
||||||
.toString(),
|
// pageKey: VitalSignDetails.Respiration,
|
||||||
unit: 'M',
|
// pageTitle:
|
||||||
),
|
// TranslationBase.of(context).respirationRate,
|
||||||
),
|
// vitalList: mode.vitalSignResModelList,
|
||||||
InkWell(
|
// ),
|
||||||
onTap: () {
|
// ),
|
||||||
Navigator.of(context).pushNamed(
|
// ):null,
|
||||||
BODY_MEASUREMENTS,
|
// child: VitalSignItem(
|
||||||
arguments: {
|
// des: TranslationBase.of(context).respirationRate,
|
||||||
'title': TranslationBase.of(context)
|
// icon: DQIcons.outline,
|
||||||
.respiration,
|
// lastVal: mode.respirationBeatPerMinute,
|
||||||
'key': vitalSignDetails.pespiration
|
// unit: TranslationBase.of(context).respirationSigns,
|
||||||
});
|
// ),
|
||||||
},
|
// ),
|
||||||
child: VitalSignItem(
|
// ],
|
||||||
des:
|
// ),
|
||||||
TranslationBase.of(context).respiration,
|
// Row(
|
||||||
url: url + 'heartbeat.png',
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
lastVal: model
|
// children: <Widget>[
|
||||||
.patientVitalSignOrderdSubList[0]
|
// InkWell(
|
||||||
.respirationBeatPerMinute
|
// onTap: () => isNotOneAppointment ? Navigator.push(
|
||||||
.toString(),
|
// context,
|
||||||
unit: 'M',
|
// FadePage(
|
||||||
),
|
// page: VitalSignItemDetailsScreen(
|
||||||
),
|
// pageKey: VitalSignDetails.BloodPressure,
|
||||||
],
|
// pageTitle: TranslationBase.of(context).bloodPressure,
|
||||||
),
|
// vitalList: mode.vitalSignResModelList,
|
||||||
Row(
|
// ),
|
||||||
children: <Widget>[
|
// ),
|
||||||
InkWell(
|
// ):null,
|
||||||
onTap: () {
|
// child: VitalSignItem(
|
||||||
Navigator.of(context).pushNamed(
|
// des: TranslationBase.of(context).bloodPressure,
|
||||||
BODY_MEASUREMENTS,
|
// icon: DQIcons.blood_pressure,
|
||||||
arguments: {
|
// lastVal: mode.bloodPressure,
|
||||||
'title': TranslationBase.of(context)
|
// unit: TranslationBase.of(context).sysDias,
|
||||||
.bloodPressure,
|
// ),
|
||||||
'key': vitalSignDetails.bloodPressure
|
// ),
|
||||||
});
|
// ],
|
||||||
},
|
// ),
|
||||||
child: VitalSignItem(
|
// ],
|
||||||
des: TranslationBase.of(context)
|
// ),
|
||||||
.bloodPressure,
|
// )
|
||||||
url: url + 'heartbeat.png',
|
// : Center(
|
||||||
lastVal: model
|
// child: Texts('No Data'),
|
||||||
.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: '',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
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',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),),);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -0,0 +1,121 @@
|
|||||||
|
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/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<VitalSignData> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,84 @@
|
|||||||
|
import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-data.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<VitalSignData> 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);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue