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; static const _minRange = 0.0; static const _goodRange = 50.0; static const _moderateRange = 100.0; static const _maxRange = 150.0; @override Widget build(BuildContext context) { final (status, statusColor) = _getStatusData(aqi); return AnimatedRadialGauge( value: aqi, debug: false, duration: const Duration(milliseconds: 500), curve: Curves.easeInOut, 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: 'Air Quality\n', style: context.textTheme.bodySmall?.copyWith( color: ColorsManager.textPrimaryColor, fontWeight: FontWeight.w400, fontSize: 12, ), children: [ TextSpan( text: status, style: context.textTheme.bodySmall?.copyWith( color: _darkenColor(statusColor), fontWeight: FontWeight.w400, fontSize: 30, ), ), ], ), textAlign: TextAlign.center, ), ), ); }, axis: GaugeAxis( progressBar: const GaugeProgressBar.basic(color: Colors.transparent), style: const GaugeAxisStyle( cornerRadius: Radius.circular(16), thickness: 14, segmentSpacing: 4, ), min: _minRange, max: _maxRange, pointer: GaugePointer.circle( position: const GaugePointerPosition.surface(), radius: MediaQuery.sizeOf(context).width * 0.004, color: ColorsManager.whiteColors, border: GaugePointerBorder( width: 6, color: statusColor, ), shadow: const BoxShadow( color: ColorsManager.blackColor, blurRadius: 6, offset: Offset(0, 2), ), ), segments: const [ GaugeSegment( from: _minRange, to: _goodRange, cornerRadius: Radius.circular(16), color: ColorsManager.goodGreen, ), GaugeSegment( from: _goodRange + 1, to: _moderateRange, cornerRadius: Radius.circular(16), color: ColorsManager.moderateYellow, ), GaugeSegment( from: _moderateRange + 1, to: _maxRange, cornerRadius: Radius.circular(16), color: ColorsManager.poorOrange, ), ], ), ); } (String status, Color color) _getStatusData(double value) { return switch (value) { <= _goodRange => ('Good', ColorsManager.goodGreen), <= _moderateRange => ('Moderate', ColorsManager.moderateYellow), _ => ('Poor', ColorsManager.poorOrange), }; } Color _darkenColor(Color color) { final black = Colors.black.withValues(alpha: 0.8); return Color.lerp(color, black, 0.4)!; } }