All stats for TL and werid chart is done

This commit is contained in:
dan63047 2023-06-03 22:10:28 +03:00
parent 671142702f
commit 62e77cc6aa
4 changed files with 236 additions and 53 deletions

View File

@ -600,6 +600,7 @@ class TetraLeagueAlpha {
double? get vsapm => vs! / apm!; double? get vsapm => vs! / apm!;
double? get dss => (vs! / 100) - (apm! / 60); double? get dss => (vs! / 100) - (apm! / 60);
double? get dsp => ((vs! / 100) - (apm! / 60)) / pps!; double? get dsp => ((vs! / 100) - (apm! / 60)) / pps!;
double? get appdsp => app! + dsp!;
double? get cheese => double? get cheese =>
(dsp! * 150) + (((vs! / apm!) - 2) * 50) + (0.6 - app!) * 125; (dsp! * 150) + (((vs! / apm!) - 2) * 50) + (0.6 - app!) * 125;
double? get gbe => ((app! * dss!) / pps!) * 2; double? get gbe => ((app! * dss!) / pps!) * 2;
@ -631,6 +632,8 @@ class TetraLeagueAlpha {
return 25000 / temp3; return 25000 / temp3;
} }
double? get esttracc => esttr! - rating;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
data['gamesplayed'] = gamesPlayed; data['gamesplayed'] = gamesPlayed;

View File

@ -1,10 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:path/path.dart';
import 'dart:convert'; import 'dart:convert';
import 'dart:math';
import 'package:tetra_stats/data_objects/tetrio.dart'; import 'package:tetra_stats/data_objects/tetrio.dart';
import 'package:tetra_stats/services/tetrio_crud.dart'; import 'package:tetra_stats/services/tetrio_crud.dart';
import 'package:tetra_stats/services/sqlite_db_controller.dart'; import 'package:tetra_stats/services/sqlite_db_controller.dart';
import 'package:fl_chart/fl_chart.dart';
extension StringExtension on String { extension StringExtension on String {
String capitalize() { String capitalize() {
@ -32,13 +33,10 @@ class MainView extends StatefulWidget {
} }
Future<TetrioPlayer> fetchTetrioPlayer(String user) async { Future<TetrioPlayer> fetchTetrioPlayer(String user) async {
var url = Uri.https('ch.tetr.io', 'api/users/${user.toLowerCase()}'); var url = Uri.https('ch.tetr.io', 'api/users/${user.toLowerCase().trim()}');
final response = await http.get(url); final response = await http.get(url);
// final response = await http.get(Uri.parse('https://ch.tetr.io/'));
if (response.statusCode == 200) { if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return jsonDecode(response.body)['success'] return jsonDecode(response.body)['success']
? TetrioPlayer.fromJson( ? TetrioPlayer.fromJson(
jsonDecode(response.body)['data']['user'], jsonDecode(response.body)['data']['user'],
@ -47,8 +45,6 @@ Future<TetrioPlayer> fetchTetrioPlayer(String user) async {
isUtc: true)) isUtc: true))
: throw Exception("User doesn't exist"); : throw Exception("User doesn't exist");
} else { } else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to fetch player'); throw Exception('Failed to fetch player');
} }
} }
@ -57,10 +53,10 @@ class _MyHomePageState extends State<MainView>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
final bodyGlobalKey = GlobalKey(); final bodyGlobalKey = GlobalKey();
final List<Widget> myTabs = [ final List<Widget> myTabs = [
Tab(text: "Tetra League"), const Tab(text: "Tetra League"),
Tab(text: "40 Lines"), const Tab(text: "40 Lines"),
Tab(text: "Blitz"), const Tab(text: "Blitz"),
Tab(text: "Other"), const Tab(text: "Other"),
]; ];
bool _searchBoolean = false; bool _searchBoolean = false;
late TabController _tabController; late TabController _tabController;
@ -69,6 +65,8 @@ class _MyHomePageState extends State<MainView>
Widget _searchTextField() { Widget _searchTextField() {
return TextField( return TextField(
maxLength: 25,
decoration: InputDecoration(counter: Offstage()),
style: const TextStyle( style: const TextStyle(
shadows: <Shadow>[ shadows: <Shadow>[
Shadow( Shadow(
@ -116,7 +114,7 @@ class _MyHomePageState extends State<MainView>
_smoothScrollToTop() { _smoothScrollToTop() {
_scrollController.animateTo( _scrollController.animateTo(
0, 0,
duration: Duration(microseconds: 300), duration: const Duration(microseconds: 300),
curve: Curves.ease, curve: Curves.ease,
); );
@ -125,16 +123,6 @@ class _MyHomePageState extends State<MainView>
}); });
} }
_buildTabContext(int lineCount) => Container(
child: ListView.builder(
physics: const ClampingScrollPhysics(),
itemCount: lineCount,
itemBuilder: (BuildContext context, int index) {
return Text('some content');
},
),
);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -239,31 +227,33 @@ class _MyHomePageState extends State<MainView>
fontSize: bigScreen ? 42 : 28)), fontSize: bigScreen ? 42 : 28)),
if (snapshot.data!.tlSeason1.gamesPlayed >= if (snapshot.data!.tlSeason1.gamesPlayed >=
10) 10)
Center( Wrap(
child: Wrap( direction: Axis.horizontal,
direction: Axis.horizontal, alignment: WrapAlignment.spaceAround,
alignment: WrapAlignment.center, crossAxisAlignment:
crossAxisAlignment: WrapCrossAlignment.center,
WrapCrossAlignment.center, clipBehavior: Clip.hardEdge,
clipBehavior: Clip.hardEdge, children: [
children: [ Image.asset(
Image.asset( "res/tetrio_tl_alpha_ranks/${snapshot.data!.tlSeason1.rank}.png",
"res/tetrio_tl_alpha_ranks/${snapshot.data!.tlSeason1.rank}.png", height: 128,
height: bigScreen ? 256 : 128, ),
), Column(
Text( children: [
"${snapshot.data!.tlSeason1.rating.toStringAsFixed(2)} TR", Text(
style: TextStyle( "${snapshot.data!.tlSeason1.rating.toStringAsFixed(2)} TR",
fontFamily: style: TextStyle(
"Eurostile Round Extended", fontFamily:
fontSize: "Eurostile Round Extended",
bigScreen ? 42 : 28)), fontSize:
Text( bigScreen ? 42 : 28)),
"Top ${(snapshot.data!.tlSeason1.percentile * 100).toStringAsFixed(2)}% (${snapshot.data!.tlSeason1.percentileRank.toUpperCase()}) • Top Rank: ${snapshot.data!.tlSeason1.bestRank.toUpperCase()} • Glicko: ${snapshot.data!.tlSeason1.glicko?.toStringAsFixed(2)}±${snapshot.data!.tlSeason1.rd?.toStringAsFixed(2)}${snapshot.data!.tlSeason1.decaying ? ' • Decaying' : ''}", Text(
textAlign: TextAlign.center, "Top ${(snapshot.data!.tlSeason1.percentile * 100).toStringAsFixed(2)}% (${snapshot.data!.tlSeason1.percentileRank.toUpperCase()}) • Top Rank: ${snapshot.data!.tlSeason1.bestRank.toUpperCase()} • Glicko: ${snapshot.data!.tlSeason1.glicko?.toStringAsFixed(2)}±${snapshot.data!.tlSeason1.rd?.toStringAsFixed(2)}${snapshot.data!.tlSeason1.decaying ? ' • Decaying' : ''}",
), textAlign: TextAlign.center,
], ),
), ],
),
],
) )
else else
Row( Row(
@ -409,6 +399,13 @@ class _MyHomePageState extends State<MainView>
fractionDigits: 3, fractionDigits: 3,
playerStatLabel: playerStatLabel:
"Downstack\nPer Piece"), "Downstack\nPer Piece"),
_StatCellNum(
playerStat: snapshot.data!
.tlSeason1.appdsp!,
isScreenBig: bigScreen,
fractionDigits: 3,
playerStatLabel:
"APP + DS/P"),
_StatCellNum( _StatCellNum(
playerStat: snapshot.data! playerStat: snapshot.data!
.tlSeason1.cheese!, .tlSeason1.cheese!,
@ -439,7 +436,169 @@ class _MyHomePageState extends State<MainView>
]), ]),
) )
], ],
) ),
Padding(
padding:
const EdgeInsets.fromLTRB(0, 16, 0, 48),
child: SizedBox(
width: bigScreen
? MediaQuery.of(context).size.width *
0.4
: MediaQuery.of(context).size.width *
0.85,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
const Text(
"Est. of TR:",
style: TextStyle(fontSize: 24),
),
Text(
snapshot.data!.tlSeason1.esttr!
.toStringAsFixed(2),
style: const TextStyle(
fontSize: 24),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
const Text(
"Accuracy of TR Est.:",
style: TextStyle(fontSize: 24),
),
Text(
(snapshot.data!.tlSeason1
.esttracc!)
.toStringAsFixed(2),
style: const TextStyle(
fontSize: 24),
),
],
),
],
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(0, 0, 0, 48),
child: SizedBox(
height: 300,
child: RadarChart(
RadarChartData(
getTitle: (index, angle) {
bool relativeAngleMode = true;
double angleValue = 0;
final usedAngle = relativeAngleMode
? angle + angleValue
: angleValue;
switch (index) {
case 0:
return RadarChartTitle(
text: 'APM',
angle: usedAngle,
);
case 1:
return RadarChartTitle(
text: 'PPS',
angle: usedAngle,
);
case 2:
return RadarChartTitle(
text: 'VS',
angle: usedAngle);
case 3:
return RadarChartTitle(
text: 'APP',
angle: usedAngle);
case 4:
return RadarChartTitle(
text: 'DS/S',
angle: usedAngle);
case 5:
return RadarChartTitle(
text: 'DS/P',
angle: usedAngle);
case 6:
return RadarChartTitle(
text: 'APP+DS/P',
angle: usedAngle);
case 7:
return RadarChartTitle(
text: 'VS/APM',
angle: usedAngle);
case 8:
return RadarChartTitle(
text: 'Cheese',
angle: usedAngle);
case 9:
return RadarChartTitle(
text: 'Gb Eff.',
angle: usedAngle);
default:
return const RadarChartTitle(
text: '');
}
},
dataSets: [
RadarDataSet(
dataEntries: [
RadarEntry(
value: snapshot.data!
.tlSeason1.apm! *
1),
RadarEntry(
value: snapshot.data!
.tlSeason1.pps! *
45),
RadarEntry(
value: snapshot.data!
.tlSeason1.vs! *
0.444),
RadarEntry(
value: snapshot.data!
.tlSeason1.app! *
185),
RadarEntry(
value: snapshot.data!
.tlSeason1.dss! *
175),
RadarEntry(
value: snapshot.data!
.tlSeason1.dsp! *
450),
RadarEntry(
value: snapshot.data!
.tlSeason1.appdsp!),
RadarEntry(
value: snapshot.data!
.tlSeason1.vsapm!),
RadarEntry(
value: snapshot.data!
.tlSeason1.cheese!),
RadarEntry(
value: snapshot.data!
.tlSeason1.gbe! *
315),
],
)
],
),
swapAnimationDuration: const Duration(
milliseconds: 150), // Optional
swapAnimationCurve:
Curves.linear, // Optional
),
),
)
] ]
: [ : [
Text("That user never played Tetra League", Text("That user never played Tetra League",
@ -451,11 +610,15 @@ class _MyHomePageState extends State<MainView>
); );
}, },
), ),
Container( Column(
child: Text("40 Lines", children: (snapshot.data!.sprint.isNotEmpty)
style: TextStyle( ? []
fontFamily: "Eurostile Round Extended", : [
fontSize: bigScreen ? 42 : 28)), Text("That user never played 40 Lines",
style: TextStyle(
fontFamily: "Eurostile Round Extended",
fontSize: bigScreen ? 42 : 28))
],
), ),
Container( Container(
child: Text("Blitz", child: Text("Blitz",

View File

@ -49,6 +49,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.5" version: "1.0.5"
equatable:
dependency: transitive
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
url: "https://pub.dev"
source: hosted
version: "2.0.5"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -73,6 +81,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.4" version: "6.1.4"
fl_chart:
dependency: "direct main"
description:
name: fl_chart
sha256: "48a1b69be9544e2b03d9a8e843affd89e43f3194c9248776222efcb4206bb1ec"
url: "https://pub.dev"
source: hosted
version: "0.62.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter

View File

@ -34,6 +34,7 @@ dependencies:
sqflite_common_ffi: any sqflite_common_ffi: any
path_provider: ^2.0.15 path_provider: ^2.0.15
path: ^1.8.2 path: ^1.8.2
fl_chart: ^0.62.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: