|  |  |  | @ -3,40 +3,43 @@ import 'package:fl_chart/fl_chart.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:hmg_patient_app_new/core/common_models/data_points.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:hmg_patient_app_new/theme/colors.dart'; | 
		
	
		
			
				|  |  |  |  | /// A customizable line graph widget using `fl_chart`. | 
		
	
		
			
				|  |  |  |  | /// | 
		
	
		
			
				|  |  |  |  | /// CustomGraph(dataPoints: sampleData, scrollDirection: Axis.horizontal,height: 200,maxY: 100, maxX:2.5, | 
		
	
		
			
				|  |  |  |  | ///               leftLabelFormatter: (value){ | 
		
	
		
			
				|  |  |  |  | ///                 Widget buildLabel(String label) { | 
		
	
		
			
				|  |  |  |  | ///                   return Padding( | 
		
	
		
			
				|  |  |  |  | ///                     padding: const EdgeInsets.only(right: 8), | 
		
	
		
			
				|  |  |  |  | ///                     child: Text( | 
		
	
		
			
				|  |  |  |  | ///                       label, | 
		
	
		
			
				|  |  |  |  | ///                       style: TextStyle( | 
		
	
		
			
				|  |  |  |  | ///                           fontSize: 8.fSize, color: AppColors.textColor, | 
		
	
		
			
				|  |  |  |  | ///                       fontFamily: | 
		
	
		
			
				|  |  |  |  | ///                       FontUtils.getFontFamilyForLanguage(false) | 
		
	
		
			
				|  |  |  |  | ///                       ), | 
		
	
		
			
				|  |  |  |  | ///                       textAlign: TextAlign.right, | 
		
	
		
			
				|  |  |  |  | ///                     ), | 
		
	
		
			
				|  |  |  |  | ///                   ); | 
		
	
		
			
				|  |  |  |  | ///                 } | 
		
	
		
			
				|  |  |  |  | ///                 switch (value.toInt()) { | 
		
	
		
			
				|  |  |  |  | /// Displays a line chart with configurable axis labels, colors, and data points. | 
		
	
		
			
				|  |  |  |  | /// Useful for visualizing time series or other sequential data. | 
		
	
		
			
				|  |  |  |  | /// | 
		
	
		
			
				|  |  |  |  | ///                   case 20: | 
		
	
		
			
				|  |  |  |  | ///                     return buildLabel("Critical Low"); | 
		
	
		
			
				|  |  |  |  | ///                   case 40: | 
		
	
		
			
				|  |  |  |  | ///                     return buildLabel("Low"); | 
		
	
		
			
				|  |  |  |  | ///                   case 60: | 
		
	
		
			
				|  |  |  |  | ///                     return buildLabel("Normal"); | 
		
	
		
			
				|  |  |  |  | ///                   case 80: | 
		
	
		
			
				|  |  |  |  | ///                     return buildLabel("High"); | 
		
	
		
			
				|  |  |  |  | ///                   case 100: | 
		
	
		
			
				|  |  |  |  | ///                     return buildLabel("Critical High"); | 
		
	
		
			
				|  |  |  |  | ///                 } | 
		
	
		
			
				|  |  |  |  | ///                 return const SizedBox.shrink(); | 
		
	
		
			
				|  |  |  |  | ///               }, | 
		
	
		
			
				|  |  |  |  | /// **Parameters:** | 
		
	
		
			
				|  |  |  |  | /// - [dataPoints]: List of `DataPoint` objects to plot. | 
		
	
		
			
				|  |  |  |  | /// - [leftLabelFormatter]: Function to build left axis labels. | 
		
	
		
			
				|  |  |  |  | /// - [bottomLabelFormatter]: Function to build bottom axis labels. | 
		
	
		
			
				|  |  |  |  | /// - [width]: Optional width of the chart. | 
		
	
		
			
				|  |  |  |  | /// - [height]: Required height of the chart. | 
		
	
		
			
				|  |  |  |  | /// - [maxY], [maxX], [minX]: Axis bounds. | 
		
	
		
			
				|  |  |  |  | /// - [spotColor]: Color of the touched spot marker. | 
		
	
		
			
				|  |  |  |  | /// - [graphColor]: Color of the line. | 
		
	
		
			
				|  |  |  |  | /// - [graphShadowColor]: Color of the area below the line. | 
		
	
		
			
				|  |  |  |  | /// - [graphGridColor]: Color of the grid lines. | 
		
	
		
			
				|  |  |  |  | /// - [bottomLabelColor]: Color of bottom axis labels. | 
		
	
		
			
				|  |  |  |  | /// - [bottomLabelSize]: Font size for bottom axis labels. | 
		
	
		
			
				|  |  |  |  | /// - [bottomLabelFontWeight]: Font weight for bottom axis labels. | 
		
	
		
			
				|  |  |  |  | /// - [leftLabelInterval]: Interval between left axis labels. | 
		
	
		
			
				|  |  |  |  | /// - [leftLabelReservedSize]: Reserved space for left axis labels. | 
		
	
		
			
				|  |  |  |  | /// - [scrollDirection]: Axis direction for scrolling. | 
		
	
		
			
				|  |  |  |  | /// - [showBottomTitleDates]: Whether to show bottom axis labels. | 
		
	
		
			
				|  |  |  |  | /// - [isFullScreeGraph]: Whether the graph is fullscreen. | 
		
	
		
			
				|  |  |  |  | /// - [makeGraphBasedOnActualValue]: Use `actualValue` for plotting. | 
		
	
		
			
				|  |  |  |  | /// | 
		
	
		
			
				|  |  |  |  | ///             ), | 
		
	
		
			
				|  |  |  |  | /// Example usage: | 
		
	
		
			
				|  |  |  |  | /// ```dart | 
		
	
		
			
				|  |  |  |  | /// CustomGraph( | 
		
	
		
			
				|  |  |  |  | ///   dataPoints: sampleData, | 
		
	
		
			
				|  |  |  |  | ///   leftLabelFormatter: (value) => ..., | 
		
	
		
			
				|  |  |  |  | ///   bottomLabelFormatter: (value, dataPoints) => ..., | 
		
	
		
			
				|  |  |  |  | ///   height: 200, | 
		
	
		
			
				|  |  |  |  | ///   scrollDirection: Axis.horizontal, | 
		
	
		
			
				|  |  |  |  | ///   maxY: 100, | 
		
	
		
			
				|  |  |  |  | ///   maxX: 2.5, | 
		
	
		
			
				|  |  |  |  | /// ) | 
		
	
		
			
				|  |  |  |  | class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  |   final List<DataPoint> dataPoints; | 
		
	
		
			
				|  |  |  |  |   final double? width; | 
		
	
	
		
			
				
					|  |  |  | @ -51,6 +54,8 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  |   final Color bottomLabelColor; | 
		
	
		
			
				|  |  |  |  |   final double? bottomLabelSize; | 
		
	
		
			
				|  |  |  |  |   final FontWeight? bottomLabelFontWeight; | 
		
	
		
			
				|  |  |  |  |   final double? leftLabelInterval; | 
		
	
		
			
				|  |  |  |  |   final double? leftLabelReservedSize; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   ///creates the left label and provide it to the chart as it will be used  by other part of the application so the label will be different for every chart | 
		
	
		
			
				|  |  |  |  |   final Widget Function(double) leftLabelFormatter; | 
		
	
	
		
			
				
					|  |  |  | @ -60,6 +65,7 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  |   final Axis scrollDirection; | 
		
	
		
			
				|  |  |  |  |   final bool showBottomTitleDates; | 
		
	
		
			
				|  |  |  |  |   final bool isFullScreeGraph; | 
		
	
		
			
				|  |  |  |  |   final bool makeGraphBasedOnActualValue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   const CustomGraph({ | 
		
	
		
			
				|  |  |  |  |     super.key, | 
		
	
	
		
			
				
					|  |  |  | @ -79,6 +85,9 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  |     this.bottomLabelColor = AppColors.textColor, | 
		
	
		
			
				|  |  |  |  |     this.bottomLabelFontWeight = FontWeight.w500, | 
		
	
		
			
				|  |  |  |  |     this.bottomLabelSize, | 
		
	
		
			
				|  |  |  |  |     this.leftLabelInterval, | 
		
	
		
			
				|  |  |  |  |     this.leftLabelReservedSize, | 
		
	
		
			
				|  |  |  |  |     this.makeGraphBasedOnActualValue =  false, | 
		
	
		
			
				|  |  |  |  |     required this.bottomLabelFormatter, | 
		
	
		
			
				|  |  |  |  |   this.minX, | 
		
	
		
			
				|  |  |  |  |   }); | 
		
	
	
		
			
				
					|  |  |  | @ -87,13 +96,7 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  |   Widget build(BuildContext context) { | 
		
	
		
			
				|  |  |  |  |     // var maxY = 0.0; | 
		
	
		
			
				|  |  |  |  |     double interval = 20; | 
		
	
		
			
				|  |  |  |  |     if ((maxY ?? 0) > 10 && (maxY ?? 0) <= 20) { | 
		
	
		
			
				|  |  |  |  |       interval = 2; | 
		
	
		
			
				|  |  |  |  |     } else if ((maxY ?? 0) > 5 && (maxY ?? 0) <= 10) { | 
		
	
		
			
				|  |  |  |  |       interval = 1; | 
		
	
		
			
				|  |  |  |  |     } else if ((maxY ?? 0) >= 0 && (maxY ?? 0) <= 5) { | 
		
	
		
			
				|  |  |  |  |       interval = .4; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     return Material( | 
		
	
		
			
				|  |  |  |  |         color: Colors.white, | 
		
	
		
			
				|  |  |  |  |         child: SizedBox( | 
		
	
	
		
			
				
					|  |  |  | @ -102,11 +105,11 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  |           child: LineChart( | 
		
	
		
			
				|  |  |  |  |             LineChartData( | 
		
	
		
			
				|  |  |  |  |               minY: 0, | 
		
	
		
			
				|  |  |  |  |               maxY: | 
		
	
		
			
				|  |  |  |  |                   ((maxY?.ceilToDouble() ?? 0.0) + interval).floorToDouble(), | 
		
	
		
			
				|  |  |  |  |               // maxY: ((maxY?.ceilToDouble() ?? 0.0) + interval).floorToDouble(), | 
		
	
		
			
				|  |  |  |  |               maxY: maxY, | 
		
	
		
			
				|  |  |  |  |               // minX: dataPoints.first.labelValue - 1, | 
		
	
		
			
				|  |  |  |  |               maxX: maxX, | 
		
	
		
			
				|  |  |  |  |               minX: minX ??-0.2, | 
		
	
		
			
				|  |  |  |  |               minX: minX , | 
		
	
		
			
				|  |  |  |  |               lineTouchData: LineTouchData( | 
		
	
		
			
				|  |  |  |  |                 getTouchLineEnd: (_, __) => 0, | 
		
	
		
			
				|  |  |  |  |                 getTouchedSpotIndicator: (barData, indicators) { | 
		
	
	
		
			
				
					|  |  |  | @ -140,7 +143,7 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                         return LineTooltipItem( | 
		
	
		
			
				|  |  |  |  |                           // '${dataPoint.label} ${spot.y.toStringAsFixed(2)}', | 
		
	
		
			
				|  |  |  |  |                           '${dataPoint.actualValue} ${dataPoint.displayTime}', | 
		
	
		
			
				|  |  |  |  |                           '${dataPoint.value} - ${dataPoint.actualValue} - ${dataPoint.displayTime}', | 
		
	
		
			
				|  |  |  |  |                           TextStyle( | 
		
	
		
			
				|  |  |  |  |                               color: Colors.black, | 
		
	
		
			
				|  |  |  |  |                               fontSize: 12.fSize, | 
		
	
	
		
			
				
					|  |  |  | @ -156,8 +159,8 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  |                 leftTitles: AxisTitles( | 
		
	
		
			
				|  |  |  |  |                   sideTitles: SideTitles( | 
		
	
		
			
				|  |  |  |  |                     showTitles: true, | 
		
	
		
			
				|  |  |  |  |                     reservedSize: 77, | 
		
	
		
			
				|  |  |  |  |                     interval: .1, // Let fl_chart handle it | 
		
	
		
			
				|  |  |  |  |                     reservedSize: leftLabelReservedSize??80, | 
		
	
		
			
				|  |  |  |  |                     interval: leftLabelInterval ?? .1, // Let fl_chart handle it | 
		
	
		
			
				|  |  |  |  |                     getTitlesWidget: (value, _) { | 
		
	
		
			
				|  |  |  |  |                       return leftLabelFormatter(value); | 
		
	
		
			
				|  |  |  |  |                     }, | 
		
	
	
		
			
				
					|  |  |  | @ -190,12 +193,12 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  |               gridData: FlGridData( | 
		
	
		
			
				|  |  |  |  |                 show: true, | 
		
	
		
			
				|  |  |  |  |                 drawVerticalLine: false, | 
		
	
		
			
				|  |  |  |  |                 horizontalInterval: 20, | 
		
	
		
			
				|  |  |  |  |                 // horizontalInterval: 40, | 
		
	
		
			
				|  |  |  |  |                 checkToShowHorizontalLine: (value) => | 
		
	
		
			
				|  |  |  |  |                     value >= 0 && value <= 100, | 
		
	
		
			
				|  |  |  |  |                 getDrawingHorizontalLine: (value) { | 
		
	
		
			
				|  |  |  |  |                   return FlLine( | 
		
	
		
			
				|  |  |  |  |                     color: AppColors.graphGridColor, | 
		
	
		
			
				|  |  |  |  |                     color: graphGridColor, | 
		
	
		
			
				|  |  |  |  |                     strokeWidth: 1, | 
		
	
		
			
				|  |  |  |  |                     dashArray: [5, 5], | 
		
	
		
			
				|  |  |  |  |                   ); | 
		
	
	
		
			
				
					|  |  |  | @ -208,7 +211,9 @@ class CustomGraph extends StatelessWidget { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   List<LineChartBarData> _buildColoredLineSegments(List<DataPoint> dataPoints) { | 
		
	
		
			
				|  |  |  |  |     final List<FlSpot> allSpots = dataPoints.asMap().entries.map((entry) { | 
		
	
		
			
				|  |  |  |  |       return FlSpot(entry.key.toDouble(), entry.value.value); | 
		
	
		
			
				|  |  |  |  |       double value = (makeGraphBasedOnActualValue)?double.tryParse(entry.value.actualValue)??0.0:entry.value.value; | 
		
	
		
			
				|  |  |  |  |       debugPrint("the value is $value"); | 
		
	
		
			
				|  |  |  |  |       return FlSpot(entry.key.toDouble(), value); | 
		
	
		
			
				|  |  |  |  |     }).toList(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     var data = [ | 
		
	
	
		
			
				
					|  |  |  | 
 |