From b3c70f711ad98be4f8a37c4aadfdb99c55d93c66 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Fri, 11 Jul 2025 10:18:29 +0200 Subject: [PATCH 1/6] Implemented empty builder for GraphView --- lib/l10n/arb/app_de.arb | 1 + lib/l10n/arb/app_en.arb | 6 ++- lib/l10n/generated/app_localizations.dart | 6 +++ lib/l10n/generated/app_localizations_de.dart | 4 ++ lib/l10n/generated/app_localizations_en.dart | 8 +++- lib/presentation/views/graph_view.dart | 46 ++++++++++++++------ pubspec.yaml | 2 +- 7 files changed, 54 insertions(+), 19 deletions(-) diff --git a/lib/l10n/arb/app_de.arb b/lib/l10n/arb/app_de.arb index d89399b..acff3c1 100644 --- a/lib/l10n/arb/app_de.arb +++ b/lib/l10n/arb/app_de.arb @@ -85,6 +85,7 @@ "end_game_message": "Möchtest du das Spiel beenden? Das Spiel wird als beendet markiert und kann nicht fortgeführt werden.", "game_process": "Spielverlauf", + "empty_graph_text": "Du musst mindestens zwei Runden spielen, damit der Graph des Spielverlaufes angezeigt werden kann.", "settings": "Einstellungen", "cabo_penalty": "Cabo-Strafe", diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index e01e242..4a0735a 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -74,18 +74,20 @@ "done": "Done", "next_round": "Next Round", + "statistics": "Statistics", "end_game": "End Game", "delete_game": "Delete Game", "new_game_same_settings": "New Game with same Settings", "export_game": "Export Game", - - "game_process": "Spielverlauf", "id_error_title": "ID Error", "id_error_message": "The game has not yet been assigned an ID. If you want to delete the game, please do so via the main menu. All newly created games have an ID.", "end_game_title": "End the game?", "end_game_message": "Do you want to end the game? The game gets marked as finished and cannot be continued.", + "game_process": "Scoring History", + "empty_graph_text": "You must play at least two rounds for the game progress graph to be displayed.", + "settings": "Settings", "cabo_penalty": "Cabo Penalty", "cabo_penalty_subtitle": "... for falsely calling Cabo.", diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index af778ae..c139891 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -476,6 +476,12 @@ abstract class AppLocalizations { /// **'Spielverlauf'** String get game_process; + /// No description provided for @empty_graph_text. + /// + /// In de, this message translates to: + /// **'Du musst mindestens zwei Runden spielen, damit der Graph des Spielverlaufes angezeigt werden kann.'** + String get empty_graph_text; + /// No description provided for @settings. /// /// In de, this message translates to: diff --git a/lib/l10n/generated/app_localizations_de.dart b/lib/l10n/generated/app_localizations_de.dart index afe558f..b61feb0 100644 --- a/lib/l10n/generated/app_localizations_de.dart +++ b/lib/l10n/generated/app_localizations_de.dart @@ -210,6 +210,10 @@ class AppLocalizationsDe extends AppLocalizations { @override String get game_process => 'Spielverlauf'; + @override + String get empty_graph_text => + 'Du musst mindestens zwei Runden spielen, damit der Graph des Spielverlaufes angezeigt werden kann.'; + @override String get settings => 'Einstellungen'; diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index a986058..fcfd494 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -92,7 +92,7 @@ class AppLocalizationsEn extends AppLocalizations { 'If you are not satisfied with the app, please let me know before leaving a bad rating. I will try to fix the issue as soon as possible.'; @override - String get contact_email => 'Contac via E-Mail'; + String get contact_email => 'Contact via E-Mail'; @override String get email_subject => 'Feedback: Cabo Counter App'; @@ -205,7 +205,11 @@ class AppLocalizationsEn extends AppLocalizations { 'Do you want to end the game? The game gets marked as finished and cannot be continued.'; @override - String get game_process => 'Spielverlauf'; + String get game_process => 'Scoring History'; + + @override + String get empty_graph_text => + 'You must play at least two rounds for the game progress graph to be displayed.'; @override String get settings => 'Settings'; diff --git a/lib/presentation/views/graph_view.dart b/lib/presentation/views/graph_view.dart index 1007007..9ee0bbc 100644 --- a/lib/presentation/views/graph_view.dart +++ b/lib/presentation/views/graph_view.dart @@ -26,21 +26,39 @@ class _GraphViewState extends State { @override Widget build(BuildContext context) { return CupertinoPageScaffold( - navigationBar: CupertinoNavigationBar( - middle: Text(AppLocalizations.of(context).game_process), - previousPageTitle: AppLocalizations.of(context).back, - ), - child: Padding( - padding: const EdgeInsets.fromLTRB(0, 100, 0, 0), - child: SfCartesianChart( - legend: - const Legend(isVisible: true, position: LegendPosition.bottom), - primaryXAxis: const NumericAxis(), - primaryYAxis: const NumericAxis(), - series: getCumulativeScores(), + navigationBar: CupertinoNavigationBar( + middle: Text(AppLocalizations.of(context).game_process), + previousPageTitle: AppLocalizations.of(context).back, ), - ), - ); + child: widget.gameSession.roundNumber > 2 + ? Padding( + padding: const EdgeInsets.fromLTRB(0, 100, 0, 0), + child: SfCartesianChart( + legend: const Legend( + isVisible: true, position: LegendPosition.bottom), + primaryXAxis: const NumericAxis(), + primaryYAxis: const NumericAxis(), + series: getCumulativeScores(), + ), + ) + : Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Center( + child: Icon(CupertinoIcons.chart_bar_alt_fill, size: 60), + ), + const SizedBox(height: 10), // Abstand von oben + Padding( + padding: const EdgeInsets.symmetric(horizontal: 40), + child: Text( + AppLocalizations.of(context).empty_graph_text, + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 16), + ), + ), + ], + )); } /// Returns a list of LineSeries representing the cumulative scores of each player. diff --git a/pubspec.yaml b/pubspec.yaml index 31146e6..802d487 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: cabo_counter description: "Mobile app for the card game Cabo" publish_to: 'none' -version: 0.4.0+467 +version: 0.4.0+470 environment: sdk: ^3.5.4 From 668328300ad4c4821529b1b17da7320af3ee91bc Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Fri, 11 Jul 2025 10:34:39 +0200 Subject: [PATCH 2/6] Added jitterStip to prevent the graphs overlaying each other --- lib/core/custom_theme.dart | 7 ++++++ lib/presentation/views/graph_view.dart | 34 ++++++++++++++++---------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/lib/core/custom_theme.dart b/lib/core/custom_theme.dart index 77a2f5b..259d5fd 100644 --- a/lib/core/custom_theme.dart +++ b/lib/core/custom_theme.dart @@ -6,6 +6,13 @@ class CustomTheme { static Color backgroundColor = const Color(0xFF101010); static Color backgroundTintColor = CupertinoColors.darkBackgroundGray; + // graph colors + static const Color graphColor1 = Color(0xFFF44336); + static const Color graphColor2 = Color(0xFF2196F3); //FF2196F3 + static const Color graphColor3 = Color(0xFFFFA726); //FFFFA726 + static const Color graphColor4 = Color(0xFF9C27B0); //9C27B0 + static final Color graphColor5 = primaryColor; + static TextStyle modeTitle = TextStyle( color: primaryColor, fontSize: 20, diff --git a/lib/presentation/views/graph_view.dart b/lib/presentation/views/graph_view.dart index 9ee0bbc..1e91a98 100644 --- a/lib/presentation/views/graph_view.dart +++ b/lib/presentation/views/graph_view.dart @@ -1,7 +1,7 @@ +import 'package:cabo_counter/core/custom_theme.dart'; import 'package:cabo_counter/data/game_session.dart'; import 'package:cabo_counter/l10n/generated/app_localizations.dart'; import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; class GraphView extends StatefulWidget { @@ -15,12 +15,12 @@ class GraphView extends StatefulWidget { class _GraphViewState extends State { /// List of colors for the graph lines. - List lineColors = [ - Colors.red, - Colors.blue, - Colors.orange.shade400, - Colors.purple, - Colors.green, + final List lineColors = [ + CustomTheme.graphColor1, + CustomTheme.graphColor2, + CustomTheme.graphColor3, + CustomTheme.graphColor4, + CustomTheme.graphColor5 ]; @override @@ -36,7 +36,10 @@ class _GraphViewState extends State { child: SfCartesianChart( legend: const Legend( isVisible: true, position: LegendPosition.bottom), - primaryXAxis: const NumericAxis(), + primaryXAxis: const NumericAxis( + interval: 1, + decimalPlaces: 0, + ), primaryYAxis: const NumericAxis(), series: getCumulativeScores(), ), @@ -64,7 +67,7 @@ class _GraphViewState extends State { /// Returns a list of LineSeries representing the cumulative scores of each player. /// Each series contains data points for each round, showing the cumulative score up to that round. /// The x-axis represents the round number, and the y-axis represents the cumulative score. - List> getCumulativeScores() { + List> getCumulativeScores() { final rounds = widget.gameSession.roundList; final playerCount = widget.gameSession.players.length; final playerNames = widget.gameSession.players; @@ -79,21 +82,26 @@ class _GraphViewState extends State { } } + const double jitterStep = 0.15; + /// Create a list of LineSeries for each player /// Each series contains data points for each round return List.generate(playerCount, (i) { final data = List.generate( cumulativeScores[i].length, - (j) => (j + 1, cumulativeScores[i][j]), // (round, score) + (j) => ( + j + 1, + cumulativeScores[i][j] + (i - playerCount ~/ 2) * jitterStep + ), ); /// Create a LineSeries for the player /// The xValueMapper maps the round number, and the yValueMapper maps the cumulative score. - return LineSeries<(int, int), int>( + return LineSeries<(int, num), int>( name: playerNames[i], dataSource: data, - xValueMapper: (record, _) => record.$1, // Runde - yValueMapper: (record, _) => record.$2, // Punktestand + xValueMapper: (record, _) => record.$1, + yValueMapper: (record, _) => record.$2, markerSettings: const MarkerSettings(isVisible: true), color: lineColors[i], ); From 4448fd2c39df7a01f3f50f5a8e54351de8bf8580 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Fri, 11 Jul 2025 10:44:21 +0200 Subject: [PATCH 3/6] Removed german comments --- lib/presentation/views/graph_view.dart | 2 +- lib/presentation/views/main_menu_view.dart | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/presentation/views/graph_view.dart b/lib/presentation/views/graph_view.dart index 1e91a98..50fb12a 100644 --- a/lib/presentation/views/graph_view.dart +++ b/lib/presentation/views/graph_view.dart @@ -51,7 +51,7 @@ class _GraphViewState extends State { const Center( child: Icon(CupertinoIcons.chart_bar_alt_fill, size: 60), ), - const SizedBox(height: 10), // Abstand von oben + const SizedBox(height: 10), Padding( padding: const EdgeInsets.symmetric(horizontal: 40), child: Text( diff --git a/lib/presentation/views/main_menu_view.dart b/lib/presentation/views/main_menu_view.dart index 1f8b5d0..fa537c6 100644 --- a/lib/presentation/views/main_menu_view.dart +++ b/lib/presentation/views/main_menu_view.dart @@ -88,10 +88,9 @@ class _MainMenuViewState extends State { ? const Center(child: CupertinoActivityIndicator()) : gameManager.gameList.isEmpty ? Column( - mainAxisAlignment: - MainAxisAlignment.center, // Oben ausrichten + mainAxisAlignment: MainAxisAlignment.center, children: [ - const SizedBox(height: 30), // Abstand von oben + const SizedBox(height: 30), Center( child: GestureDetector( onTap: () => Navigator.push( @@ -107,7 +106,7 @@ class _MainMenuViewState extends State { color: CustomTheme.primaryColor, ), )), - const SizedBox(height: 10), // Abstand von oben + const SizedBox(height: 10), Padding( padding: const EdgeInsets.symmetric(horizontal: 70), From 5fa8d1fa3de4ce8fb186a65c1dc8255b6f5d77d7 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Fri, 11 Jul 2025 10:49:19 +0200 Subject: [PATCH 4/6] Added comment to jitter calculation --- lib/presentation/views/graph_view.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/presentation/views/graph_view.dart b/lib/presentation/views/graph_view.dart index 50fb12a..7736bb1 100644 --- a/lib/presentation/views/graph_view.dart +++ b/lib/presentation/views/graph_view.dart @@ -91,6 +91,9 @@ class _GraphViewState extends State { cumulativeScores[i].length, (j) => ( j + 1, + + // Add a small jitter to the cumulative scores to prevent overlapping data points in the graph. + // The jitter is centered around zero by subtracting playerCount ~/ 2 from the player index i. cumulativeScores[i][j] + (i - playerCount ~/ 2) * jitterStep ), ); From 1494cb08a5943af1e36c2918d94798a1d901a18e Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Fri, 11 Jul 2025 10:50:11 +0200 Subject: [PATCH 5/6] Overhauled comments in CustomTheme --- lib/core/custom_theme.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/core/custom_theme.dart b/lib/core/custom_theme.dart index 259d5fd..a00340b 100644 --- a/lib/core/custom_theme.dart +++ b/lib/core/custom_theme.dart @@ -6,11 +6,11 @@ class CustomTheme { static Color backgroundColor = const Color(0xFF101010); static Color backgroundTintColor = CupertinoColors.darkBackgroundGray; - // graph colors + // Line Colors for GraphView static const Color graphColor1 = Color(0xFFF44336); - static const Color graphColor2 = Color(0xFF2196F3); //FF2196F3 - static const Color graphColor3 = Color(0xFFFFA726); //FFFFA726 - static const Color graphColor4 = Color(0xFF9C27B0); //9C27B0 + static const Color graphColor2 = Color(0xFF2196F3); + static const Color graphColor3 = Color(0xFFFFA726); + static const Color graphColor4 = Color(0xFF9C27B0); static final Color graphColor5 = primaryColor; static TextStyle modeTitle = TextStyle( From ebe3dd6954506cc25f06e0dd2b73198f2a269b44 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Fri, 11 Jul 2025 10:52:47 +0200 Subject: [PATCH 6/6] Updated version --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 802d487..fbacd1e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: cabo_counter description: "Mobile app for the card game Cabo" publish_to: 'none' -version: 0.4.0+470 +version: 0.4.1+470 environment: sdk: ^3.5.4