import 'dart:math'; import 'package:flutter/material.dart'; class TargetProgressChart extends StatelessWidget { final double percent; final double size; const TargetProgressChart({ super.key, required this.percent, this.size = 110, }); // Format persentase: tampilkan desimal hanya jika tidak bulat // Contoh: 100.0 → "100%", 5.01 → "5.01%", 50.5 → "50.5%" String get _percentLabel { if (percent == percent.roundToDouble()) { return '${percent.toInt()}%'; } // Hilangkan trailing zero: 5.10 → "5.1", 5.01 → "5.01" final formatted = percent.toStringAsFixed(2); final trimmed = formatted.replaceAll(RegExp(r'0+$'), ''); return '$trimmed%'; } @override Widget build(BuildContext context) { return SizedBox( width: size, height: size, child: CustomPaint( painter: _PieChartPainter(percent: percent), child: Center( child: Text( _percentLabel, style: TextStyle( color: Colors.white, // Sedikit lebih kecil agar teks desimal muat fontSize: size * 0.15, fontWeight: FontWeight.bold, ), ), ), ), ); } } class _PieChartPainter extends CustomPainter { final double percent; _PieChartPainter({required this.percent}); @override void paint(Canvas canvas, Size size) { final center = Offset(size.width / 2, size.height / 2); final radius = size.width / 2; final bgPaint = Paint() ..color = Colors.white.withOpacity(0.2) ..style = PaintingStyle.fill; canvas.drawCircle(center, radius, bgPaint); final progressPaint = Paint() ..color = Colors.white.withOpacity(0.5) ..style = PaintingStyle.fill; final sweepAngle = 2 * pi * (percent / 100); canvas.drawArc( Rect.fromCircle(center: center, radius: radius), -pi / 2, sweepAngle, true, progressPaint, ); final innerPaint = Paint() ..color = const Color(0xFF5B9BD5) ..style = PaintingStyle.fill; canvas.drawCircle(center, radius * 0.55, innerPaint); } @override bool shouldRepaint(covariant _PieChartPainter old) => old.percent != percent; }