lab result added along with the available characters scroll bar #111

Merged
Haroon6138 merged 5 commits from lab-result-changes into master 2 months ago

@ -1,3 +1,4 @@
import 'dart:collection';
import 'dart:core';
import 'dart:math';
@ -39,6 +40,13 @@ class LabViewModel extends ChangeNotifier {
String labSpecialResult = "";
List<String> labOrderTests = [];
String patientLabResultReportPDFBase64 = "";
String? flagForHighReferenceRange;
double highRefrenceValue = double.negativeInfinity;
double lowRefenceValue = double.infinity;
double highTransformedReferenceValue = double.negativeInfinity;
double lowTransformedReferenceValue = double.infinity;
String? flagForLowReferenceRange;
PatientLabOrdersResponseModel? currentlySelectedPatientOrder;
@ -67,8 +75,11 @@ class LabViewModel extends ChangeNotifier {
List<String> get labSuggestions => _labSuggestionsList;
Set<TestDetails> uniqueTests = {};
List<TestDetails> uniqueTestsList = [];
List<String> indexedCharacterForUniqueTest = [];
double maxY = 0.0;
double minY = double.infinity;
double maxX = double.infinity;
LabViewModel(
@ -195,6 +206,19 @@ class LabViewModel extends ChangeNotifier {
createdOn: item.createdOn,
model: item))
};
var sortedResult = SplayTreeSet<TestDetails>.from(uniqueTests, (a, b) => a.description?[0].toUpperCase().compareTo(b.description?[0] ?? "") ?? -1);
uniqueTestsList = uniqueTests.toList();
uniqueTestsList.sort((a, b) {
return a.description!.toLowerCase().compareTo(b.description!.toLowerCase());
});
indexedCharacterForUniqueTest.clear();
for (var test in uniqueTestsList) {
String label = test.description ?? "";
if (label.isEmpty) continue;
if (indexedCharacterForUniqueTest.contains(label[0].toLowerCase())) continue;
indexedCharacterForUniqueTest.add(label[0].toLowerCase());
}
for (var element in uniqueTests) {
labOrderTests.add(element.description ?? "");
}
@ -294,7 +318,8 @@ class LabViewModel extends ChangeNotifier {
mainLabResults.clear();
filteredGraphValues.clear();
maxY = double.negativeInfinity;
minY = double.infinity;
maxX = double.infinity;
final result = await labRepo.getPatientLabResults(
laborder,
Utils.isVidaPlusProject(int.parse(laborder.projectID ?? "0")),
@ -313,7 +338,12 @@ class LabViewModel extends ChangeNotifier {
var recentThree = sort(sortedResponse);
mainLabResults = recentThree;
double counter = 1;
double highRefrenceValue = double.negativeInfinity;
String? flagForHighReferenceRange;
double lowRefenceValue = double.infinity;
String? flagForLowReferenceRange;
recentThree.reversed.forEach((element) {
try {
var dateTime =
@ -324,6 +354,17 @@ class LabViewModel extends ChangeNotifier {
maxY = resultValue;
maxX = maxY;
}
if (resultValue < minY) {
minY = resultValue;
}
if (highRefrenceValue < double.parse(element.referenceHigh ?? "0.0")) {
highRefrenceValue = double.parse(element.referenceHigh ?? "0.0");
flagForHighReferenceRange = element.calculatedResultFlag;
}
if (lowRefenceValue > double.parse(element.referenceLow ?? "0.0")) {
lowRefenceValue = double.parse(element.referenceLow ?? "0.0");
flagForLowReferenceRange = element.calculatedResultFlag;
}
filteredGraphValues.add(DataPoint(
value: transformedValue,
@ -335,9 +376,25 @@ class LabViewModel extends ChangeNotifier {
referenceValue: element.calculatedResultFlag ?? "",
));
counter++;
} catch (e) {}
});
if (flagForLowReferenceRange == null && flagForHighReferenceRange == null) {
highRefrenceValue = maxY;
lowRefenceValue = minY;
}
this.flagForHighReferenceRange = flagForHighReferenceRange;
this.flagForLowReferenceRange = flagForLowReferenceRange;
highTransformedReferenceValue = double.parse(transformValueInRange(highRefrenceValue, flagForHighReferenceRange ?? "").toStringAsFixed(1));
lowTransformedReferenceValue = double.parse(transformValueInRange(lowRefenceValue, flagForLowReferenceRange ?? "").toStringAsFixed(1));
this.highRefrenceValue = double.parse(highRefrenceValue.toStringAsFixed(1));
this.lowRefenceValue = double.parse(lowRefenceValue.toStringAsFixed(1));
if(maxY< highRefrenceValue) {
maxY = highRefrenceValue;
}
maxY += 25;
minY -= 25;
LabResult recentResult = recentThree.first;
recentResult.uOM = unitOfMeasure;
checkIfGraphShouldBeDisplayed(recentResult);

@ -250,4 +250,7 @@ class TestDetails {
data['CreatedOn'] = this.createdOn;
return data;
}
@override
String toString() { return description??"";}
}

@ -0,0 +1,235 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart' show AnimationConfiguration, SlideAnimation, FadeInAnimation;
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/debouncer.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'lab_order_by_test.dart';
class AlphabeticScroll extends StatefulWidget{
final List<String> alpahbetsAvailable;
final List<TestDetails> details;
final AppState appState;
final LabViewModel labViewModel;
final DateRangeSelectorRangeViewModel rangeViewModel;
const AlphabeticScroll({super.key, required this.alpahbetsAvailable, required this.details, required this.appState, required this.labViewModel, required this.rangeViewModel});
@override
State<AlphabeticScroll> createState() => _AlphabetScrollPageState();
}
class _AlphabetScrollPageState extends State<AlphabeticScroll> {
final ItemScrollController itemScrollController = ItemScrollController();
final ScrollOffsetController scrollOffsetController = ScrollOffsetController();
final ItemPositionsListener itemPositionsListener = ItemPositionsListener.create();
final ScrollOffsetListener scrollOffsetListener = ScrollOffsetListener.create();
final ScrollController _scrollController = ScrollController();
Map<String, List<TestDetails>> data = {};
Map<String, num> density = {};
Map<String, double> _offsetMap = {};
Map<String, GlobalKey> _offsetKeys = {};
int _activeIndex = 0; // <-- Highlighted letter
@override
void initState() {
super.initState();
scheduleMicrotask((){
for(var char in widget.alpahbetsAvailable){
data[char] = widget.details.where((element)=>element.description?.toLowerCase().startsWith(char.toLowerCase()) == true).toList();
}
setState((){});
});
itemPositionsListener.itemPositions.addListener((){
final positions = itemPositionsListener.itemPositions.value;
if (positions.isEmpty) return;
// Get FIRST visible item (top-most)
final firstVisible = positions
.where((p) => p.itemTrailingEdge > 0) // visible
.reduce((min, p) =>
p.itemLeadingEdge < min.itemLeadingEdge ? p : min);
if(_activeIndex == firstVisible.index) return ;
setState(() {
_activeIndex = firstVisible.index;
});
print("Active index = $_activeIndex");
});
}
@override
void dispose() {
itemPositionsListener.itemPositions.removeListener((){
});
super.dispose();
}
void _scrollToLetter(String letter) async {
// itemScrollController.jumpTo(index:density[letter]?.toInt()??0, );
itemScrollController.scrollTo(
index: data.keys.toList().indexOf(letter).toInt()??0,
duration: Duration(seconds: 2),
curve: Curves.easeInOutCubic);
// final key = _offsetKeys[letter];
// if (key == null) return;
//
// BuildContext? ctx = key.currentContext;
//
// // Retry until built (max 100ms)
// int retry = 0;
// while (ctx == null && retry < 5) {
// await Future.delayed(Duration(milliseconds: 20));
// ctx = key.currentContext;
// retry++;
// }
//
// if (ctx == null) {
// print("$letter still not built");
// return;
// }
//
// final renderBox = ctx.findRenderObject() as RenderBox;
// final yOffset = renderBox.localToGlobal(Offset.zero).dy;
//
// _scrollController.animateTo(
// _scrollController.offset + yOffset - 80,
// duration: Duration(milliseconds: 400),
// curve: Curves.easeInOut,
// );
}
@override
Widget build(BuildContext context) {
return
SizedBox(
width: MediaQuery.sizeOf(context).width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start, // Add this
children: [
Expanded(
child: Column(
children: [
SizedBox(
height: (MediaQuery.sizeOf(context).height),
child: _buildList(widget.alpahbetsAvailable)
),
],
),
),
SizedBox(
width: 24.w,
height: MediaQuery.sizeOf(context).height-(70.h+ kToolbarHeight+100.h),
child: Column(
mainAxisSize: MainAxisSize.max, // Add this
mainAxisAlignment: MainAxisAlignment.center, // Changed from center to start
crossAxisAlignment: CrossAxisAlignment.center,
children:List.generate(widget.alpahbetsAvailable.length, (i) {
final isActive = (i == _activeIndex);
return GestureDetector(
onTap: () {
setState(() => _activeIndex = i);
_scrollToLetter(widget.alpahbetsAvailable[i]);
},
child: TweenAnimationBuilder<double>(
tween: Tween(begin: 1.0, end: isActive ? 1.8 : 1.0),
duration: Duration(milliseconds: 120),
curve: Curves.easeOut,
builder: (_, scale, child) {
return Transform.scale(
scale: scale,
child: Opacity(
opacity: isActive ? 1.0 : 0.5,
child: widget.alpahbetsAvailable[i].toUpperCase().toText14(
color: !isActive ? AppColors.greyTextColor : AppColors.primaryRedColor
),
),
);
},
),
);
}
),
),
),
],
),
);
// );
}
Widget _buildList(List<String> alphabet) {
return ScrollablePositionedList.builder(
shrinkWrap: true,
padding: EdgeInsets.zero,
itemScrollController: itemScrollController,
scrollOffsetController: scrollOffsetController,
itemPositionsListener: itemPositionsListener,
scrollOffsetListener: scrollOffsetListener,
itemCount: data.length,
itemBuilder: (_, index) {
final letter = alphabet[index].toLowerCase();
print("the letter is $letter");
final items = data[letter]!;
return Container(
key: _offsetKeys[letter],
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:
List.generate(items.length,(itemIndex)=>
AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: LabOrderByTest(
appState: getIt<AppState>(),
onTap: () {
if (items[itemIndex].model != null) {
widget.rangeViewModel.flush();
widget.labViewModel.getPatientLabResult(items[itemIndex].model!, items[itemIndex].description!,
(widget.appState.isArabic() ? items[itemIndex].testDescriptionAr! : items[itemIndex].testDescriptionEn!),"");
}
},
tests: items[itemIndex],
index: itemIndex,
isExpanded: true)),
),
))
// ...items.indexed((item) =>
//
//
//
// )
),
);
},
);
}
}

@ -27,6 +27,7 @@ class LabOrderByTest extends StatelessWidget {
@override
build(BuildContext context) {
return AnimatedContainer(
key:key,
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
margin: EdgeInsets.symmetric(vertical: 8.h),

File diff suppressed because one or more lines are too long

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
@ -236,29 +237,41 @@ class LabResultDetails extends StatelessWidget {
dataPoints: labmodel.filteredGraphValues,
makeGraphBasedOnActualValue: true,
leftLabelReservedSize: 40,
showGridLines: true,
leftLabelInterval: getInterval(labmodel),
maxY: (labmodel.maxY)+(getInterval(labmodel)??0)/2,
// maxY: (labmodel.maxY)+(getInterval(labmodel)??0)/2,
maxY: (labmodel.maxY),
minY: labmodel.minY,
maxX: labmodel.filteredGraphValues.length.toDouble()-.75,
horizontalInterval: .1,
getDrawingHorizontalLine: (value){
value = double.parse(value.toStringAsFixed(1));
if(value == labmodel.highRefrenceValue ||value== labmodel.lowRefenceValue) {
return FlLine(
color: AppColors.bgGreenColor.withOpacity(0.6),
strokeWidth: 1,
// dashArray: [5, 5],
);
}
return FlLine(
color: Colors.transparent,
strokeWidth: 1,
);;
},
leftLabelFormatter: (value) {
return leftLabels(value.toStringAsFixed(2));
// switch (value.toInt()) {
// case 10:
// return leftLabels("Critical Low".needTranslation);
// case 30:
// return leftLabels("Low".needTranslation);
// case 50:
// return leftLabels("Normal".needTranslation);
// case 70:
// return leftLabels("High".needTranslation);
// case 90:
// return leftLabels(
// "Critical High".needTranslation);
// default:
// return SizedBox.shrink();
value = double.parse(value.toStringAsFixed(1));
// return leftLabels(value.toStringAsFixed(2));
if(value == labmodel.highRefrenceValue)
return leftLabels("High".needTranslation);
if(value== labmodel.lowRefenceValue)
return leftLabels("Low".needTranslation);
return SizedBox.shrink();
// }
},
graphColor:graphColor ,
graphShadowColor: graphColor.withOpacity(.1),
graphColor:AppColors.blackColor,
graphShadowColor: Colors.transparent,
graphGridColor: graphColor.withOpacity(.4),
bottomLabelFormatter: (value, data) {
if(data.isEmpty) return SizedBox.shrink();
@ -273,6 +286,9 @@ class LabResultDetails extends StatelessWidget {
}
return SizedBox.shrink();
},
rangeAnnotations: RangeAnnotations(
horizontalRangeAnnotations: _buildRangeShades(labmodel)
),
minX:(labmodel.filteredGraphValues.length == 1)?null : -.2,
scrollDirection: Axis.horizontal,
height: 180.h);
@ -281,6 +297,29 @@ class LabResultDetails extends StatelessWidget {
}
}
List<HorizontalRangeAnnotation> _buildRangeShades( LabViewModel model,) {
List<HorizontalRangeAnnotation> ranges = [];
ranges.add(HorizontalRangeAnnotation(
y1:model.minY,
y2: model.lowRefenceValue,
color: AppColors.highAndLow.withOpacity(0.05),
));
ranges.add(HorizontalRangeAnnotation(
y1:model.lowRefenceValue,
y2: model.highRefrenceValue,
color: AppColors.bgGreenColor.withOpacity(0.05),
));
ranges.add(HorizontalRangeAnnotation(
y1:model.highRefrenceValue,
y2: model.maxY,
color: AppColors.criticalLowAndHigh.withOpacity(0.05),
));
return ranges;
}
Widget labHistoryList(LabViewModel labmodel) {
return SizedBox(
height: labmodel.filteredGraphValues.length<3?labmodel.filteredGraphValues.length*64:180.h,
@ -304,14 +343,15 @@ class LabResultDetails extends StatelessWidget {
}
double? getInterval(LabViewModel labmodel) {
var maxX = labmodel.maxY;
if(maxX<1) return .5;
if(maxX >1 && maxX < 5) return 1;
if(maxX >5 && maxX < 10) return 5;
if(maxX >10 && maxX < 50) return 10;
if(maxX >50 && maxX < 100) return 20;
if(maxX >100 && maxX < 200) return 30;
return 50;
return .1;
// var maxX = labmodel.maxY;
// if(maxX<1) return .5;
// if(maxX >1 && maxX < 5) return 1;
// if(maxX >5 && maxX < 10) return 5;
// if(maxX >10 && maxX < 50) return 10;
// if(maxX >50 && maxX < 100) return 20;
// if(maxX >100 && maxX < 200) return 30;
// return 50;
}
Widget getLabDescription(BuildContext context) {

@ -0,0 +1,205 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import '../../core/dependencies.dart';
class CollapsingToolbar extends StatefulWidget {
final String title;
Widget child;
VoidCallback? search;
VoidCallback? report;
VoidCallback? logout;
VoidCallback? history;
VoidCallback? instructions;
VoidCallback? requests;
Widget? bottomChild;
Widget? trailing;
bool isClose;
bool isLeading;
CollapsingToolbar({
super.key,
required this.title,
required this.child,
this.search,
this.isClose = false,
this.bottomChild,
this.report,
this.logout,
this.history,
this.instructions,
this.requests,
this.isLeading = true,
this.trailing,
});
@override
State<CollapsingToolbar> createState() => _CollapsingToolbarState();
}
class _CollapsingToolbarState extends State<CollapsingToolbar> {
bool isCollapsed = false;
final ScrollController _controller = ScrollController();
double expandedHeight = 0;
double get maxCollapseOffset => expandedHeight - kToolbarHeight;
@override
void initState() {
super.initState();
_controller.addListener(() {
// If scrolling UP beyond collapsed point force stop
print("the height is $maxCollapseOffset");
if (_controller.offset > maxCollapseOffset) {
_controller.jumpTo(maxCollapseOffset);
}
});
}
@override
Widget build(BuildContext context) {
expandedHeight = MediaQuery.of(context).size.height * 0.11.h;
AppState appState = getIt.get<AppState>();
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body:
// Column(
// children: [
NestedScrollView(
controller: _controller,
floatHeaderSlivers: true,
physics: isCollapsed?NeverScrollableScrollPhysics():BouncingScrollPhysics(),
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverAppBar(
automaticallyImplyLeading: false,
pinned: true,
expandedHeight: MediaQuery.of(context).size.height * 0.11.h,
stretch: true,
systemOverlayStyle: SystemUiOverlayStyle(statusBarBrightness: Brightness.light),
surfaceTintColor: Colors.transparent,
backgroundColor: AppColors.bgScaffoldColor,
leading: widget.isLeading
? Transform.flip(
flipX: appState.isArabic(),
child: IconButton(
icon: Utils.buildSvgWithAssets(icon: widget.isClose ? AppAssets.closeBottomNav : AppAssets.arrow_back, width: 32.h, height: 32.h),
padding: EdgeInsets.only(left: 12),
onPressed: () => Navigator.pop(context),
highlightColor: Colors.transparent,
),
)
: SizedBox.shrink(),
flexibleSpace: LayoutBuilder(
builder: (context, constraints) {
final double maxHeight = 100.h;
final double minHeight = kToolbarHeight;
double t = (constraints.maxHeight - minHeight) / (maxHeight - minHeight);
t = t - 1;
if (t < 0.7) t = 0.7;
t = t.clamp(0.0, 1.0);
final double fontSize = lerpDouble(14, 18, t)!;
final double bottomPadding = lerpDouble(0, 0, t)!;
final double leftPadding = lerpDouble(150, 24, t)!;
return Stack(
children: [
Align(
alignment: Alignment.lerp(
Alignment.center,
Alignment.bottomLeft,
t,
)!,
child: Padding(
padding: EdgeInsets.only(left: appState.isArabic() ? 0 : leftPadding, right: appState.isArabic() ? leftPadding : 0, bottom: bottomPadding),
child: Row(
spacing: 4.h,
children: [
Text(
widget.title,
maxLines: 1,
style: TextStyle(
fontSize: (27 - (5 * (2 - t))).f,
fontWeight: FontWeight.lerp(
FontWeight.w300,
FontWeight.w600,
t,
)!,
color: AppColors.blackColor,
letterSpacing: -0.5),
).expanded,
if (widget.logout != null) actionButton(context, t, title: "Logout".needTranslation, icon: AppAssets.logout).onPress(widget.logout!),
if (widget.report != null) actionButton(context, t, title: "Report".needTranslation, icon: AppAssets.report_icon).onPress(widget.report!),
if (widget.history != null) actionButton(context, t, title: "History".needTranslation, icon: AppAssets.insurance_history_icon).onPress(widget.history!),
if (widget.instructions != null) actionButton(context, t, title: "Instructions".needTranslation, icon: AppAssets.requests).onPress(widget.instructions!),
if (widget.requests != null) actionButton(context, t, title: "Requests".needTranslation, icon: AppAssets.insurance_history_icon).onPress(widget.requests!),
if (widget.search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(widget.search!).paddingOnly(right: 24),
if (widget.trailing != null) widget.trailing!,
],
)),
),
],
);
},
),
),
];
},
body: widget.child,
),
// ],
// ),
);
}
Widget actionButton(BuildContext context, double t, {required String title, required String icon}) {
return AnimatedSize(
duration: Duration(milliseconds: 150),
child: Container(
height: 40.h,
padding: EdgeInsets.all(8.w),
margin: EdgeInsets.only(right: 24.w),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.secondaryLightRedColor,
borderRadius: 10.r,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
spacing: 8.h,
children: [
Utils.buildSvgWithAssets(icon: icon, iconColor: AppColors.primaryRedColor),
if (t == 1)
Text(
title,
style: context.dynamicTextStyle(
color: AppColors.primaryRedColor,
letterSpacing: -0.4,
fontSize: (14 - (2 * (1 - t))).f,
fontWeight: FontWeight.lerp(
FontWeight.w300,
FontWeight.w500,
t,
)!,
),
),
],
),
),
);
}
}

@ -56,6 +56,12 @@ class CustomGraph extends StatelessWidget {
final FontWeight? bottomLabelFontWeight;
final double? leftLabelInterval;
final double? leftLabelReservedSize;
final bool? showGridLines;
final GetDrawingGridLine? getDrawingHorizontalLine;
final double? horizontalInterval;
final double? minY;
final bool showShadow;
final RangeAnnotations? rangeAnnotations;
///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;
@ -89,14 +95,17 @@ class CustomGraph extends StatelessWidget {
this.leftLabelReservedSize,
this.makeGraphBasedOnActualValue = false,
required this.bottomLabelFormatter,
this.minX,
this.minX,
this.showGridLines = false,
this.getDrawingHorizontalLine,
this.horizontalInterval,
this.minY,
this.showShadow = false,
this.rangeAnnotations
});
@override
Widget build(BuildContext context) {
// var maxY = 0.0;
double interval = 20;
return Material(
color: Colors.white,
child: SizedBox(
@ -104,10 +113,8 @@ class CustomGraph extends StatelessWidget {
height: height,
child: LineChart(
LineChartData(
minY: 0,
// maxY: ((maxY?.ceilToDouble() ?? 0.0) + interval).floorToDouble(),
minY: minY??0,
maxY: maxY,
// minX: dataPoints.first.labelValue - 1,
maxX: maxX,
minX: minX ,
lineTouchData: LineTouchData(
@ -190,12 +197,12 @@ class CustomGraph extends StatelessWidget {
),
lineBarsData: _buildColoredLineSegments(dataPoints),
gridData: FlGridData(
show: true,
show: showGridLines??true,
drawVerticalLine: false,
// horizontalInterval: 40,
checkToShowHorizontalLine: (value) =>
value >= 0 && value <= 100,
getDrawingHorizontalLine: (value) {
horizontalInterval:horizontalInterval,
// checkToShowHorizontalLine: (value) =>
// value >= 0 && value <= 100,
getDrawingHorizontalLine: getDrawingHorizontalLine??(value) {
return FlLine(
color: graphGridColor,
strokeWidth: 1,
@ -203,15 +210,17 @@ class CustomGraph extends StatelessWidget {
);
},
),
rangeAnnotations: rangeAnnotations
),
),
));
),
);
}
List<LineChartBarData> _buildColoredLineSegments(List<DataPoint> dataPoints) {
final List<FlSpot> allSpots = dataPoints.asMap().entries.map((entry) {
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();
@ -221,7 +230,7 @@ class CustomGraph extends StatelessWidget {
isCurved: true,
isStrokeCapRound: true,
isStrokeJoinRound: true,
barWidth: 4,
barWidth: 2,
gradient: LinearGradient(
colors: [graphColor, graphColor],
begin: Alignment.centerLeft,
@ -231,7 +240,7 @@ class CustomGraph extends StatelessWidget {
show: false,
),
belowBarData: BarAreaData(
show: true,
show: showShadow,
gradient: LinearGradient(
colors: [
graphShadowColor,
@ -246,33 +255,4 @@ class CustomGraph extends StatelessWidget {
return data;
}
// Widget buildLabel(String label) {
// return Padding(
// padding: const EdgeInsets.only(right: 8),
// child: Text(
// label,
// style: TextStyle(
// fontSize: leftLabelSize ?? 8.fSize, color: leftLabelColor),
// textAlign: TextAlign.right,
// ),
// );
// }
}
// final List<DataPoint> sampleData = [
// DataPoint(
// value: 20,
// label: 'Jan 2024',
// ),
// DataPoint(
// value: 36,
// label: 'Feb 2024',
// ),
// DataPoint(
// value: 80,
// label: 'This result',
// ),
// ];
}

@ -93,6 +93,8 @@ dependencies:
url: https://github.com/fleoparra/hms-flutter-plugin.git
path: flutter-hms-map
scrollable_positioned_list: ^0.3.8
dev_dependencies:
flutter_test:
sdk: flutter

Loading…
Cancel
Save