TKK_E32230211/lib/app/widgets/target_progress_chart.dart

85 lines
2.2 KiB
Dart

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;
}