fix: persist pie slice selection on tap

This commit is contained in:
2025-05-04 14:39:18 +03:00
parent 034c405a29
commit 187fcf4abf
+28 -13
View File
@@ -69,23 +69,23 @@ class SpendingPieChart extends StatelessWidget {
PieChartData(
// Handle touch events on the pie chart
pieTouchData: PieTouchData(
touchCallback: (FlTouchEvent event, pieTouchResponse) {
// Ignore events not related to interaction
if (!event.isInterestedForInteractions ||
pieTouchResponse == null ||
pieTouchResponse.touchedSection == null) {
// If touch ends outside a section, deselect
if (event is FlPanEndEvent || event is FlTapUpEvent) {
touchCallback: (FlTouchEvent event, PieTouchResponse? pieTouchResponse) {
// We are only interested in TapUp events to trigger selection changes
if (event is FlTapUpEvent) {
final section = pieTouchResponse?.touchedSection;
if (section != null) {
// Tap occurred ON a section
final touchedIndex = section.touchedSectionIndex;
// Toggle selection: if tapped section is already selected, deselect (-1), otherwise select it.
onSelectPieCategory(touchedIndex == selectedPieIndex ? -1 : touchedIndex);
} else {
// Tap occurred OUTSIDE any section
// Deselect if something was selected
if (selectedPieIndex != -1) {
onSelectPieCategory(-1); // Deselect
onSelectPieCategory(-1);
}
}
return;
}
// Get the index of the touched section
final touchedIndex = pieTouchResponse.touchedSection!.touchedSectionIndex;
// Call the callback, toggling selection if the same slice is touched again
onSelectPieCategory(touchedIndex == selectedPieIndex ? -1 : touchedIndex);
},
),
borderData: FlBorderData(show: false), // No border around the chart
@@ -130,6 +130,11 @@ class SpendingPieChart extends StatelessWidget {
// Builds the text displayed in the center when a slice is selected
Widget _buildCenterText(BuildContext context, NumberFormat formatter) {
final theme = Theme.of(context);
// Check if selectedPieIndex is valid before accessing categories
if (selectedPieIndex < 0 || selectedPieIndex >= categories.length) {
// Return an empty container or default text if index is invalid
return _buildDefaultCenterText(context, formatter);
}
final selectedCategory = categories[selectedPieIndex];
return Column(
mainAxisAlignment: MainAxisAlignment.center,
@@ -189,6 +194,10 @@ class SpendingPieChart extends StatelessWidget {
final isDark = Theme.of(context).brightness == Brightness.dark;
final theme = Theme.of(context);
final isSelected = index == selectedPieIndex; // Check if this item is selected
// Check if index is valid before accessing categories
if (index < 0 || index >= categories.length) {
return const SizedBox.shrink(); // Return empty if index is invalid
}
final category = categories[index];
// Calculate percentage, handle totalExpenses being zero
final percentage = totalExpenses > 0 ? (category.amount / totalExpenses * 100) : 0.0;
@@ -256,6 +265,12 @@ class SpendingPieChart extends StatelessWidget {
final isDark = Theme.of(context).brightness == Brightness.dark;
return List.generate(categories.length, (i) {
// Check if index is valid before accessing categories
if (i < 0 || i >= categories.length) {
// This should ideally not happen if List.generate is used correctly,
// but adding a safeguard.
return PieChartSectionData(); // Return an empty section
}
final isTouched = i == selectedPieIndex; // Check if this slice is selected
// Make selected slice slightly larger
final double radius = isTouched ? 65 : 55;