From a2a85ce1511f61298119b88730c12726d259dd36 Mon Sep 17 00:00:00 2001 From: dan63047 Date: Sat, 14 Sep 2024 01:00:11 +0300 Subject: [PATCH] Yaaaaay the graaaaaaph!!! --- lib/main.dart | 2 +- lib/services/tetrio_crud.dart | 10 ++-- lib/views/main_view_tiles.dart | 84 +++++++++++++++++++++++++++++++++- 3 files changed, 89 insertions(+), 7 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index bbba219..a847a1e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,7 +16,7 @@ import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart'; import 'package:tetra_stats/gen/strings.g.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:tetra_stats/views/main_view.dart'; +import 'package:tetra_stats/views/main_view_tiles.dart'; import 'package:tetra_stats/views/settings_view.dart'; import 'package:tetra_stats/views/tracked_players_view.dart'; import 'package:tetra_stats/views/calc_view.dart'; diff --git a/lib/services/tetrio_crud.dart b/lib/services/tetrio_crud.dart index 6520bf7..4ac790a 100644 --- a/lib/services/tetrio_crud.dart +++ b/lib/services/tetrio_crud.dart @@ -554,20 +554,20 @@ class TetrioService extends DB { switch (response.statusCode) { case 200: - List> csv = const CsvToListConverter().convert(response.body)..removeAt(0); + List> csv = const CsvToListConverter().convert(response.body, eol: "\n")..removeAt(0); List history = []; for (List entry in csv){ Map tr = {}; Map glicko = {}; Map gxe = {}; for(int i = 0; i < ranks.length; i++){ - tr[ranks[ranks.length + i - ranks.length]] = entry[1 + i*3]; - glicko[ranks[ranks.length + i - ranks.length]] = entry[2 + i*3]; - glicko[ranks[ranks.length + i - ranks.length]] = entry[3 + i*3]; + tr[ranks[ranks.length - 1 - i]] = entry[1 + i*3]; + glicko[ranks[ranks.length - 1 - i]] = entry[2 + i*3]; + gxe[ranks[ranks.length - 1 - i]] = entry[3 + i*3]; } history.add( Cutoffs( - DateTime.fromMillisecondsSinceEpoch(entry[0]), + DateTime.fromMillisecondsSinceEpoch(entry[0]*1000), tr, glicko, gxe diff --git a/lib/views/main_view_tiles.dart b/lib/views/main_view_tiles.dart index 729becc..9b80ab3 100644 --- a/lib/views/main_view_tiles.dart +++ b/lib/views/main_view_tiles.dart @@ -172,6 +172,7 @@ class _MainState extends State with TickerProviderStateMixin { getDestinationButton(Icons.leaderboard, "Leaderboards"), getDestinationButton(Icons.compress, "Cutoffs"), getDestinationButton(Icons.calculate, "Calc"), + getDestinationButton(Icons.info_outline, "Information"), getDestinationButton(Icons.storage, "Saved Data"), getDestinationButton(Icons.settings, "Settings"), ], @@ -293,6 +294,7 @@ class _DestinationGraphsState extends State { late ZoomPanBehavior _zoomPanBehavior; late TooltipBehavior _historyTooltipBehavior; late TooltipBehavior _tooltipBehavior; + late TooltipBehavior _leagueTooltipBehavior; String yAxisTitle = ""; bool _smooth = false; //final List _historyShortTitles = ["TR", "Glicko", "RD", "APM", "PPS", "VS", "APP", "DS/S", "DS/P", "APP + DS/P", "VS/APM", "Cheese", "GbE", "wAPP", "Area", "eTR", "±eTR", "Opener", "Plonk", "Inf. DS", "Stride"]; @@ -356,6 +358,32 @@ class _DestinationGraphsState extends State { ); } ); + _leagueTooltipBehavior = TooltipBehavior( + color: Colors.black, + borderColor: Colors.white, + enable: true, + animationDuration: 0, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + print(point); + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + "${f4.format(point.y)} $yAxisTitle", + style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 20), + ), + ), + Text(timestamp(data.ts)) + ], + ), + ); + } + ); _zoomPanBehavior = ZoomPanBehavior( enablePinching: true, enableSelectionZooming: true, @@ -538,7 +566,61 @@ class _DestinationGraphsState extends State { } Widget getCutoffsHistory(){ - return Container(); // TODO + return FutureBuilder>( + future: teto.fetchCutoffsHistory(), + builder: (context, snapshot) { + switch (snapshot.connectionState){ + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return const Center(child: CircularProgressIndicator()); + case ConnectionState.done: + if (snapshot.hasData){ + yAxisTitle = chartsShortTitles[_Ychart]!; + return SfCartesianChart( + tooltipBehavior: _leagueTooltipBehavior, + zoomPanBehavior: _zoomPanBehavior, + primaryXAxis: _gamesPlayedInsteadOfDateAndTime ? const NumericAxis() : const DateTimeAxis(), + primaryYAxis: const NumericAxis( + rangePadding: ChartRangePadding.additional, + ), + margin: const EdgeInsets.all(0), + series: [ + for (String rank in ranks) StepLineSeries( + enableTooltip: true, + dataSource: snapshot.data, + animationDuration: 0, + //opacity: _smooth ? 0 : 1, + xValueMapper: (Cutoffs data, _) => data.ts, + yValueMapper: (Cutoffs data, _) => data.tr[rank], + color: rankColors[rank], + // trendlines:[ + // Trendline( + // isVisible: _smooth, + // period: (selectedGraph.length/175).floor(), + // type: TrendlineType.movingAverage, + // color: Theme.of(context).colorScheme.primary) + // ], + ) + ], + ); + }else{ + return Center(child: + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(snapshot.error.toString(), style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 42, fontWeight: FontWeight.bold), textAlign: TextAlign.center), + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text(snapshot.stackTrace.toString(), textAlign: TextAlign.center), + ), + ], + ) + ); + } + } + } + ); } @override