import 'dart:math'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:hoshan/data/model/report_model.dart'; import 'package:hoshan/ui/theme/responsive.dart'; import 'package:hoshan/ui/theme/text.dart'; import 'package:hoshan/ui/widgets/components/chart/indocator.dart'; class CustomePiChart extends StatefulWidget { final List points; const CustomePiChart({super.key, required this.points}); @override State createState() => _CustomePiChartState(); } class _CustomePiChartState extends State { int touchedIndex = -1; bool valid = false; late int allPointCoinsUsage = widget.points.fold(0, (sum, point) => sum + (point.coinUsage ?? 0)); Color getRandomColor(Set existingColors) { Random random = Random(); Color newColor; do { newColor = Color.fromARGB( 255, // Full opacity random.nextInt(256), // Red (0-255) random.nextInt(256), // Green (0-255) random.nextInt(256), // Blue (0-255) ); } while ( existingColors.contains(newColor)); // Keep generating if color exists existingColors.add(newColor); // Add new unique color to the set return newColor; } late Set usedColors = {}; // Track used colors late List colors = List.generate( widget.points.length, (index) => getRandomColor(usedColors), ); @override void initState() { super.initState(); for (var report in widget.points) { if (report.coinUsage != null && report.coinUsage! > 0) { valid = true; } } } @override Widget build(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ valid ? AspectRatio( aspectRatio: Responsive(context).isDesktop() ? 2 : 1 / 1, child: Stack( children: [ PieChart( PieChartData( pieTouchData: PieTouchData( touchCallback: (FlTouchEvent event, pieTouchResponse) { setState(() { if (!event.isInterestedForInteractions || pieTouchResponse == null || pieTouchResponse.touchedSection == null) { touchedIndex = -1; return; } touchedIndex = pieTouchResponse .touchedSection!.touchedSectionIndex; }); }, ), borderData: FlBorderData( show: false, ), sectionsSpace: 4, centerSpaceRadius: 64, sections: showingSections(), ), ), Positioned.fill( child: Center( child: Text( 'سکه', style: AppTextStyles.headline3.copyWith( color: Theme.of(context).colorScheme.onSurface), ), )) ], ), ) : const SizedBox( height: 24, ), Directionality( textDirection: TextDirection.rtl, child: ListView.builder( itemCount: widget.points.length, shrinkWrap: true, physics: const BouncingScrollPhysics(), itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Indicator( count: '${widget.points[index].messagesCount} پیام', color: colors[index], text: widget.points[index].date ?? '', isSquare: false, ), ); }, ), ), ], ); } List showingSections() { return List.generate(widget.points.length, (index) { final isTouched = index == touchedIndex; final fontSize = isTouched ? 16.0 : 12.0; final radius = isTouched ? 60.0 : 50.0; const shadows = [Shadow(color: Colors.black, blurRadius: 2)]; final point = widget.points[index]; return PieChartSectionData( color: colors[index], value: max((point.coinUsage! * 100) / allPointCoinsUsage, 3.5), radius: radius, title: '', badgeWidget: Text( '${point.coinUsage}', textDirection: TextDirection.rtl, textAlign: TextAlign.center, style: AppTextStyles.body3.copyWith( fontSize: fontSize, fontWeight: FontWeight.bold, color: Colors.white, shadows: shadows, ), ), ); }); } }