diff --git a/lib/pages/analytics/modules/air_quality/widgets/air_quality_end_side_gauge_and_info.dart b/lib/pages/analytics/modules/air_quality/widgets/air_quality_end_side_gauge_and_info.dart index 8e01a99a..8693a6d2 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/air_quality_end_side_gauge_and_info.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/air_quality_end_side_gauge_and_info.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:gauge_indicator/gauge_indicator.dart'; +import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_gauge.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -26,12 +26,14 @@ class AirQualityEndSideGaugeAndInfo extends StatelessWidget { ), const Spacer(), Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - flex: 2, - child: FittedBox( + child: Padding( + padding: const EdgeInsetsDirectional.only(end: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const Spacer(), + FittedBox( + fit: BoxFit.contain, alignment: AlignmentDirectional.centerStart, child: Text( 'Air Quality:', @@ -42,10 +44,8 @@ class AirQualityEndSideGaugeAndInfo extends StatelessWidget { ), ), ), - ), - Expanded( - child: FittedBox( - fit: BoxFit.scaleDown, + FittedBox( + fit: BoxFit.contain, alignment: AlignmentDirectional.centerStart, child: Text( 'Perfect', @@ -56,9 +56,8 @@ class AirQualityEndSideGaugeAndInfo extends StatelessWidget { ), ), ), - ), - Expanded( - child: FittedBox( + const Spacer(), + FittedBox( fit: BoxFit.scaleDown, alignment: AlignmentDirectional.centerStart, child: DefaultTextStyle( @@ -79,7 +78,7 @@ class AirQualityEndSideGaugeAndInfo extends StatelessWidget { ), ), const SizedBox(width: 4), - const Text('30C'), + const Text('30°C'), const SizedBox(width: 10), SvgPicture.asset( Assets.aqiHumidity, @@ -91,148 +90,13 @@ class AirQualityEndSideGaugeAndInfo extends StatelessWidget { ), ), const SizedBox(width: 4), - const Text('30%'), + const Text('30°C'), ], ), ), ), - ), - ], - ), - ), - ], - ), - ); - } -} - -class AqiGauge extends StatelessWidget { - const AqiGauge({super.key, required this.aqi}); - - final double aqi; - - Color _getPointerColor(double value) { - if (value <= 50) { - return ColorsManager.goodGreen; - } else if (value <= 100) { - return ColorsManager.moderateYellow; - } else if (value <= 150) { - return ColorsManager.poorOrange; - } else { - if (value <= 225) { - final t = (value - 151) / (225 - 151); - return Color.lerp( - ColorsManager.unhealthyRed, - ColorsManager.severePink, - t, - )!; - } else { - final t = (value - 226) / (300 - 226); - return Color.lerp( - ColorsManager.severePink, - ColorsManager.hazardousPurple, - t, - )!; - } - } - } - - @override - Widget build(BuildContext context) { - return AnimatedRadialGauge( - value: aqi, - debug: false, - duration: const Duration(milliseconds: 200), - initialValue: 0, - alignment: Alignment.bottomCenter, - builder: (context, child, value) { - return Align( - alignment: AlignmentDirectional.bottomCenter, - child: FittedBox( - fit: BoxFit.scaleDown, - alignment: AlignmentDirectional.bottomCenter, - child: Text.rich( - TextSpan( - text: '${value.toInt()}', - style: context.textTheme.bodySmall?.copyWith( - color: ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w700, - fontSize: 30, - ), - children: [ - const TextSpan( - text: 'AQI', - style: TextStyle( - color: ColorsManager.textPrimaryColor, - fontWeight: FontWeight.w400, - fontSize: 12, - ), - ), ], ), - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center, - ), - ), - ); - }, - axis: GaugeAxis( - progressBar: const GaugeProgressBar.basic(color: Colors.transparent), - style: const GaugeAxisStyle( - cornerRadius: Radius.circular(16), - thickness: 10, - segmentSpacing: 4, - ), - min: 0, - max: 300, - pointer: GaugePointer.circle( - position: const GaugePointerPosition.surface(), - shadow: const BoxShadow( - color: ColorsManager.transparentColor, - blurRadius: 0, - offset: Offset(0, 0), - ), - radius: MediaQuery.sizeOf(context).width * 0.004, - color: ColorsManager.whiteColors, - border: GaugePointerBorder( - width: 4, - color: _getPointerColor(aqi), - ), - ), - transformer: const GaugeAxisTransformer.colorFadeIn( - background: Colors.transparent, - interval: Interval(0, 0), - ), - segments: [ - const GaugeSegment( - from: 0, - to: 50, - cornerRadius: Radius.circular(16), - color: ColorsManager.goodGreen, - ), - const GaugeSegment( - from: 51, - to: 100, - cornerRadius: Radius.circular(16), - color: ColorsManager.moderateYellow, - ), - const GaugeSegment( - from: 101, - to: 150, - cornerRadius: Radius.circular(16), - color: ColorsManager.poorOrange, - ), - const GaugeSegment( - from: 151, - to: 300, - cornerRadius: Radius.circular(16), - gradient: GaugeAxisGradient( - colorStops: [0.0, 0.5, 1.0], - colors: [ - ColorsManager.unhealthyRed, - ColorsManager.severePink, - ColorsManager.hazardousPurple, - ], ), ), ], diff --git a/lib/pages/analytics/modules/air_quality/widgets/air_quality_end_side_widget.dart b/lib/pages/analytics/modules/air_quality/widgets/air_quality_end_side_widget.dart index 03044e8d..e636d97b 100644 --- a/lib/pages/analytics/modules/air_quality/widgets/air_quality_end_side_widget.dart +++ b/lib/pages/analytics/modules/air_quality/widgets/air_quality_end_side_widget.dart @@ -102,7 +102,7 @@ class AirQualityEndSideWidget extends StatelessWidget { ), const SizedBox(height: 20), Expanded( - flex: 6, + flex: 4, child: Container( decoration: secondarySection.copyWith(boxShadow: const []), padding: const EdgeInsetsDirectional.all(20), diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_gauge.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_gauge.dart new file mode 100644 index 00000000..d36f3e00 --- /dev/null +++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_gauge.dart @@ -0,0 +1,139 @@ +import 'package:flutter/material.dart'; +import 'package:gauge_indicator/gauge_indicator.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; + +class AqiGauge extends StatelessWidget { + const AqiGauge({super.key, required this.aqi}); + + final double aqi; + + Color _getPointerColor(double value) { + if (value <= 50) { + return ColorsManager.goodGreen; + } else if (value <= 100) { + return ColorsManager.moderateYellow; + } else if (value <= 150) { + return ColorsManager.poorOrange; + } else { + if (value <= 225) { + final t = (value - 151) / (225 - 151); + return Color.lerp( + ColorsManager.unhealthyRed, + ColorsManager.severePink, + t, + )!; + } else { + final t = (value - 226) / (300 - 226); + return Color.lerp( + ColorsManager.severePink, + ColorsManager.hazardousPurple, + t, + )!; + } + } + } + + @override + Widget build(BuildContext context) { + return AnimatedRadialGauge( + value: aqi, + debug: false, + duration: const Duration(milliseconds: 200), + initialValue: 0, + alignment: Alignment.bottomCenter, + builder: (context, child, value) { + return Align( + alignment: AlignmentDirectional.bottomCenter, + child: FittedBox( + fit: BoxFit.scaleDown, + alignment: AlignmentDirectional.bottomCenter, + child: Text.rich( + TextSpan( + text: '${value.toInt()}', + style: context.textTheme.bodySmall?.copyWith( + color: ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w700, + fontSize: 30, + ), + children: [ + const TextSpan( + text: 'AQI', + style: TextStyle( + color: ColorsManager.textPrimaryColor, + fontWeight: FontWeight.w400, + fontSize: 12, + ), + ), + ], + ), + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + ), + ), + ); + }, + axis: GaugeAxis( + progressBar: const GaugeProgressBar.basic(color: Colors.transparent), + style: const GaugeAxisStyle( + cornerRadius: Radius.circular(16), + thickness: 10, + segmentSpacing: 4, + ), + min: 0, + max: 300, + pointer: GaugePointer.circle( + position: const GaugePointerPosition.surface(), + shadow: const BoxShadow( + color: ColorsManager.transparentColor, + blurRadius: 0, + offset: Offset(0, 0), + ), + radius: MediaQuery.sizeOf(context).width * 0.004, + color: ColorsManager.whiteColors, + border: GaugePointerBorder( + width: 4, + color: _getPointerColor(aqi), + ), + ), + transformer: const GaugeAxisTransformer.colorFadeIn( + background: Colors.transparent, + interval: Interval(0, 0), + ), + segments: [ + const GaugeSegment( + from: 0, + to: 50, + cornerRadius: Radius.circular(16), + color: ColorsManager.goodGreen, + ), + const GaugeSegment( + from: 51, + to: 100, + cornerRadius: Radius.circular(16), + color: ColorsManager.moderateYellow, + ), + const GaugeSegment( + from: 101, + to: 150, + cornerRadius: Radius.circular(16), + color: ColorsManager.poorOrange, + ), + const GaugeSegment( + from: 151, + to: 300, + cornerRadius: Radius.circular(16), + gradient: GaugeAxisGradient( + colorStops: [0.0, 0.5, 1.0], + colors: [ + ColorsManager.unhealthyRed, + ColorsManager.severePink, + ColorsManager.hazardousPurple, + ], + ), + ), + ], + ), + ); + } +}