import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; class CircleChart extends StatefulWidget { const CircleChart({super.key, required this.humidityPercentage}); final double humidityPercentage; @override State createState() => _CircleChartState(); } class _CircleChartState extends State { double currentPercentage = 0; @override void initState() { super.initState(); Future.delayed(Duration.zero, () async { for (double i = 0; i <= widget.humidityPercentage; i++) { await Future.delayed(const Duration(milliseconds: 25), () { setState(() { currentPercentage = i; }); }); } }); } @override Widget build(BuildContext context) { return Center( child: Stack( alignment: Alignment.center, children: [ ShaderMask( shaderCallback: (Rect bounds) { return RadialGradient( center: Alignment.center, radius: 0.6, colors: [ Colors.white, _getAnimatedColor(currentPercentage) ], tileMode: TileMode.mirror, ).createShader(bounds); }, child: PieChart( PieChartData( sections: _createSections(currentPercentage), centerSpaceRadius: MediaQuery.of(context).size.width * 0.25, sectionsSpace: 0, startDegreeOffset: 270, borderData: FlBorderData(show: false), ), ), ), TweenAnimationBuilder( tween: Tween(begin: 0, end: currentPercentage), duration: const Duration(milliseconds: 300), builder: (context, value, child) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(BootstrapIcons.droplet_fill, size: 32, color: _getAnimatedColor(value)), Text( '${value.toStringAsFixed(0)}%', // Animated percentage text style: const TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Colors.black, ), ), ], ); }, ), ], ), ); } List _createSections(double humidityPercentage) { return [ PieChartSectionData( color: Colors.white, value: humidityPercentage, title: '', radius: 50, // Size of the pie slice titleStyle: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, ), ), PieChartSectionData( color: Colors.white24, value: 100 - humidityPercentage, title: '', radius: 50, ), ]; } Color _getAnimatedColor(double percentage) { return Color.lerp( Colors.green, Colors.blue, percentage / widget.humidityPercentage)!; } }