Houshan-Basa/lib/ui/widgets/components/chart/custome_pi_chart.dart

160 lines
5.0 KiB
Dart

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<Report> points;
const CustomePiChart({super.key, required this.points});
@override
State<CustomePiChart> createState() => _CustomePiChartState();
}
class _CustomePiChartState extends State<CustomePiChart> {
int touchedIndex = -1;
bool valid = false;
late int allPointCoinsUsage =
widget.points.fold(0, (sum, point) => sum + (point.coinUsage ?? 0));
Color getRandomColor(Set<Color> 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<Color> usedColors = {}; // Track used colors
late List<Color> 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<PieChartSectionData> 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,
),
),
);
});
}
}