Conflitos resolvidos: mantido o código local

This commit is contained in:
2026-03-16 22:28:41 +00:00
20 changed files with 1244 additions and 1171 deletions

View File

@@ -5,23 +5,26 @@ class PieChartWidget extends StatelessWidget {
final double victoryPercentage;
final double defeatPercentage;
final double drawPercentage;
final double sf;
final double size;
const PieChartWidget({
super.key,
required this.victoryPercentage,
required this.defeatPercentage,
this.drawPercentage = 0,
required this.sf,
this.size = 140, // Aumentado para 400x300
});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
// 👇 MAGIA ANTI-DESAPARECIMENTO 👇
// Vê o espaço real. Se por algum motivo for infinito, assume 100 para não sumir.
final double w = constraints.maxWidth.isInfinite ? 100.0 : constraints.maxWidth;
final double h = constraints.maxHeight.isInfinite ? 100.0 : constraints.maxHeight;
// Pega no menor valor para garantir que o círculo não é cortado
final double size = math.min(w, h);
return Center(
@@ -29,7 +32,7 @@ class PieChartWidget extends StatelessWidget {
width: size,
height: size,
child: CustomPaint(
painter: _DonutChartPainter(
painter: _PieChartPainter(
victoryPercentage: victoryPercentage,
defeatPercentage: defeatPercentage,
drawPercentage: drawPercentage,
@@ -45,27 +48,24 @@ class PieChartWidget extends StatelessWidget {
}
Widget _buildCenterLabels(double size) {
final bool hasGames = victoryPercentage > 0 || defeatPercentage > 0 || drawPercentage > 0;
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
// 👇 Casa decimal aplicada aqui!
hasGames ? '${(victoryPercentage * 100).toStringAsFixed(1)}%' : '---',
'${(victoryPercentage * 100).toStringAsFixed(1)}%',
style: TextStyle(
fontSize: size * (hasGames ? 0.20 : 0.15),
fontSize: size * 0.18, // O texto cresce ou encolhe com o círculo
fontWeight: FontWeight.bold,
color: hasGames ? Colors.white : Colors.white54,
color: Colors.white,
),
),
SizedBox(height: size * 0.02),
Text(
hasGames ? 'Vitórias' : 'Sem Jogos',
'Vitórias',
style: TextStyle(
fontSize: size * 0.08,
color: hasGames ? Colors.white70 : Colors.white38,
fontSize: size * 0.10,
color: Colors.white.withOpacity(0.8),
),
),
],
@@ -87,40 +87,59 @@ class _DonutChartPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = (size.width / 2) - (size.width * 0.1);
final strokeWidth = size.width * 0.2;
// Margem de 5% para a linha de fora não ser cortada
final radius = (size.width / 2) - (size.width * 0.05);
if (victoryPercentage == 0 && defeatPercentage == 0 && drawPercentage == 0) {
final bgPaint = Paint()
..color = Colors.white.withOpacity(0.05)
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth;
canvas.drawCircle(center, radius, bgPaint);
return;
}
const victoryColor = Colors.green;
const defeatColor = Colors.red;
const drawColor = Colors.amber;
double startAngle = -math.pi / 2;
const drawColor = Colors.yellow;
const borderColor = Colors.white30;
void drawDonutSector(double percentage, Color color) {
if (percentage <= 0) return;
final sweepAngle = 2 * math.pi * percentage;
final paint = Paint()
..color = color
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.butt;
canvas.drawArc(Rect.fromCircle(center: center, radius: radius), startAngle, sweepAngle, false, paint);
double startAngle = -math.pi / 2;
if (victoryPercentage > 0) {
final sweepAngle = 2 * math.pi * victoryPercentage;
_drawSector(canvas, center, radius, startAngle, sweepAngle, victoryColor, size.width);
startAngle += sweepAngle;
}
drawDonutSector(victoryPercentage, victoryColor);
drawDonutSector(drawPercentage, drawColor);
drawDonutSector(defeatPercentage, defeatColor);
if (drawPercentage > 0) {
final sweepAngle = 2 * math.pi * drawPercentage;
_drawSector(canvas, center, radius, startAngle, sweepAngle, drawColor, size.width);
startAngle += sweepAngle;
}
if (defeatPercentage > 0) {
final sweepAngle = 2 * math.pi * defeatPercentage;
_drawSector(canvas, center, radius, startAngle, sweepAngle, defeatColor, size.width);
}
final borderPaint = Paint()
..color = borderColor
..style = PaintingStyle.stroke
..strokeWidth = size.width * 0.02;
canvas.drawCircle(center, radius, borderPaint);
}
void _drawSector(Canvas canvas, Offset center, double radius, double startAngle, double sweepAngle, Color color, double totalWidth) {
final paint = Paint()
..color = color
..style = PaintingStyle.fill;
canvas.drawArc(Rect.fromCircle(center: center, radius: radius), startAngle, sweepAngle, true, paint);
if (sweepAngle < 2 * math.pi) {
final linePaint = Paint()
..color = Colors.white.withOpacity(0.5)
..style = PaintingStyle.stroke
..strokeWidth = totalWidth * 0.015;
final lineX = center.dx + radius * math.cos(startAngle);
final lineY = center.dy + radius * math.sin(startAngle);
canvas.drawLine(center, Offset(lineX, lineY), linePaint);
}
}
@override