From a996a0b3560e0bef9d3bd058cb05f0e5203e51c9 Mon Sep 17 00:00:00 2001 From: dan63047 Date: Sun, 20 Aug 2023 02:20:06 +0300 Subject: [PATCH] Graph + new eTR formula + bugfix + new flutter ver --- lib/data_objects/tetrio.dart | 25 ++- lib/views/rank_averages_view.dart | 315 +++++++++++++++++------------- pubspec.lock | 42 ++-- 3 files changed, 223 insertions(+), 159 deletions(-) diff --git a/lib/data_objects/tetrio.dart b/lib/data_objects/tetrio.dart index 8453d06..cdc6c27 100644 --- a/lib/data_objects/tetrio.dart +++ b/lib/data_objects/tetrio.dart @@ -535,7 +535,30 @@ class EstTr { double temp = (1500 - estglicko) * pi; double temp2 = pow((15.9056943314 * (pow(_rd, 2)) + 3527584.25978), 0.5) as double; double temp3 = 1 + pow(10, (temp / temp2)) as double; - esttr = 25000 / temp3; + //esttr = 25000 / temp3; + double ntemp = _pps*(150+(((_vs/_apm) - 1.66)*35))+_app*290+_dsp*700; + esttr = 25000 / + ( + 1 + pow(10, ( + ( + ( + 1500-( + 0.000013*pow(ntemp, 3) - 0.0196 *pow(ntemp, 2) + (12.645*ntemp)-1005.4 + ) + )*pi + )/sqrt( + ( + ( + 3*pow(ln10, 2) + )*pow(60, 2) + )+( + 2500*( + (64*pow(pi,2))+(147*pow(ln10, 2)) + ) + ) + ) + )) + ); } } diff --git a/lib/views/rank_averages_view.dart b/lib/views/rank_averages_view.dart index 7264d09..d3eb750 100644 --- a/lib/views/rank_averages_view.dart +++ b/lib/views/rank_averages_view.dart @@ -3,15 +3,46 @@ import 'dart:math'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; +import 'package:tetra_stats/data_objects/tetrio.dart'; //import 'package:tetra_stats/data_objects/tetrio.dart'; import 'package:tetra_stats/gen/strings.g.dart'; -import 'package:tetra_stats/views/main_view.dart'; +import 'package:tetra_stats/views/main_view.dart' show MainView, f4, f2; import 'package:tetra_stats/widgets/stat_sell_num.dart'; import 'package:tetra_stats/widgets/tl_thingy.dart'; //import 'package:tetra_stats/widgets/tl_thingy.dart'; -final DateFormat dateFormat = - DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms(); +List chartsShortTitles = [ + "TR", + "Glicko", + "RD", + "GP", + "GW", + "WR%", + "APM", + "PPS", + "VS", + "APP", + "DS/S", + "DS/P", + "APP + DS/P", + "VS/APM", + "Cheese", + "GbE", + "wAPP", + "Area", + "eTR", + "±eTR", + "Opener", + "Plonk", + "Inf. DS", + "Stride", + "Stride - Plonk", + "Opener - Inf. DS" + ]; +var chartsShortTitlesDropdowns = [for (String e in chartsShortTitles) DropdownMenuItem(child: Text(e), value: e,)]; +int chartsIndexX = 0; +int chartsIndexY = 6; +//final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms(); double pfpHeight = 128; class RankView extends StatefulWidget { @@ -142,57 +173,84 @@ class RankState extends State with SingleTickerProviderStateMixin { controller: _tabController, children: [ Column( - mainAxisSize: MainAxisSize.min, children: [ - LayoutBuilder(builder: (context, constraints) { - return true ? - Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [Column( - children: [ - Row( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Text("X axis:", style: const TextStyle(fontSize: 22))), - DropdownButton( - items: chartsData, - value: chartsData[chartsIndex].value, - onChanged: (value) { - chartsIndex = chartsData.indexWhere((element) => element.value == value); - _justUpdate(); - } + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [Column( + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text("X axis:", style: const TextStyle(fontSize: 22))), + DropdownButton( + items: chartsShortTitlesDropdowns, + value: chartsShortTitlesDropdowns[chartsIndexX].value, + onChanged: (value) { + chartsIndexX = chartsShortTitlesDropdowns.indexWhere((element) => element.value == value); + _justUpdate(); + } + ), + ], + ), + ], + ),Column( + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text("Y axis:", style: const TextStyle(fontSize: 22)), + ), + DropdownButton( + items: chartsShortTitlesDropdowns, + value: chartsShortTitlesDropdowns[chartsIndexY].value, + onChanged: (value) { + chartsIndexY = chartsShortTitlesDropdowns.indexWhere((element) => element.value == value); + _justUpdate(); + } + ), + ], + ), + ], + ),],), + if(widget.rank[1]["entries"].length > 1) SizedBox( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height - 104, + child: Stack( + children: [ + Padding( + padding: bigScreen + ? const EdgeInsets.fromLTRB(40, 40, 40, 48) + : const EdgeInsets.fromLTRB(0, 40, 16, 48), + child: ScatterChart( + ScatterChartData( + scatterSpots: [ for (TetrioPlayerFromLeaderboard entry in widget.rank[1]["entries"]) MyScatterSpot(takeStat(entry, chartsShortTitles[chartsIndexX]), takeStat(entry, chartsShortTitles[chartsIndexY]), entry.userId, entry.username, color: rankColors[entry.rank])], + scatterTouchData: ScatterTouchData(touchTooltipData: ScatterTouchTooltipData( + fitInsideHorizontally: true, fitInsideVertically: true, getTooltipItems: (touchedSpot) { + touchedSpot as MyScatterSpot; + return ScatterTooltipItem("${touchedSpot.nickname}\n", textStyle: TextStyle(fontFamily: "Eurostile Round Extended"), children: [TextSpan(text: "${f4.format(touchedSpot.x)} ${chartsShortTitles[chartsIndexX]}\n${f4.format(touchedSpot.y)} ${chartsShortTitles[chartsIndexY]}", style: TextStyle(fontFamily: "Eurostile Round"))]); + }), + touchCallback:(event, response) { + if (event.runtimeType == FlTapDownEvent && response?.touchedSpot?.spot != null){ + var spot = response?.touchedSpot?.spot as MyScatterSpot; + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MainView(player: spot.nickname), + maintainState: false, ), - ], + ); + } + },), + ), + swapAnimationDuration: Duration(milliseconds: 150), // Optional + swapAnimationCurve: Curves.linear, // Optional ), - ], - ),Column( - children: [ - Row( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Text("Y axis:", style: const TextStyle(fontSize: 22)), - ), - DropdownButton( - items: chartsData, - value: chartsData[chartsIndex].value, - onChanged: (value) { - chartsIndex = chartsData.indexWhere((element) => element.value == value); - _justUpdate(); - } - ), - ], - ), - ], - ),],), - if(chartsData[chartsIndex].value!.length > 1) _ChartThigy(data: chartsData[chartsIndex].value!, title: "ss", yAxisTitle: chartsShortTitles[chartsIndex], bigScreen: bigScreen, leftSpace: bigScreen? 80 : 45, yFormat: bigScreen? f2 : NumberFormat.compact(),) - else Center(child: Text(t.notEnoughData, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28))) - ], - ) : Center(child: Text(t.noHistorySaved, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28))); - }) + ), + ], + )) + else Center(child: Text(t.notEnoughData, style: const TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28))) ], ), Column( @@ -235,7 +293,7 @@ class RankState extends State with SingleTickerProviderStateMixin { builder: (context) => MainView( player: widget .rank[1]["entries"][index] - .userId), + .username), maintainState: false, ), ); @@ -912,94 +970,69 @@ class _ListEntry extends StatelessWidget { } } -class _ChartThigy extends StatelessWidget { - final List data; - final String title; - final String yAxisTitle; - final bool bigScreen; - final double leftSpace; - final NumberFormat yFormat; - const _ChartThigy( - {required this.data, - required this.title, - required this.yAxisTitle, - required this.bigScreen, - required this.leftSpace, - required this.yFormat}); - - @override - Widget build(BuildContext context) { - double xInterval = bigScreen - ? max(1, (data.last.x - data.first.x) / 6) - : max(1, (data.last.x - data.first.x) / 3); - return SizedBox( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height - 104, - child: Stack( - children: [ - Padding( - padding: bigScreen - ? const EdgeInsets.fromLTRB(40, 40, 40, 48) - : const EdgeInsets.fromLTRB(0, 40, 16, 48), - child: LineChart(LineChartData( - lineBarsData: [LineChartBarData(spots: data)], - borderData: FlBorderData(show: false), - gridData: FlGridData(verticalInterval: xInterval), - titlesData: FlTitlesData( - topTitles: - AxisTitles(sideTitles: SideTitles(showTitles: false)), - rightTitles: - AxisTitles(sideTitles: SideTitles(showTitles: false)), - bottomTitles: AxisTitles( - sideTitles: SideTitles( - interval: xInterval, - showTitles: true, - reservedSize: 30, - getTitlesWidget: (double value, TitleMeta meta) { - return value != meta.min && value != meta.max - ? SideTitleWidget( - axisSide: meta.axisSide, - child: Text(DateFormat.yMMMd( - LocaleSettings - .currentLocale.languageCode) - .format(DateTime - .fromMillisecondsSinceEpoch( - value.floor()))), - ) - : Container(); - })), - leftTitles: AxisTitles( - sideTitles: SideTitles( - showTitles: true, - reservedSize: leftSpace, - getTitlesWidget: (double value, TitleMeta meta) { - return value != meta.min && value != meta.max - ? SideTitleWidget( - axisSide: meta.axisSide, - child: Text(yFormat.format(value)), - ) - : Container(); - }))), - lineTouchData: LineTouchData( - touchTooltipData: LineTouchTooltipData( - fitInsideHorizontally: true, - fitInsideVertically: true, - getTooltipItems: (touchedSpots) { - return [ - for (var v in touchedSpots) - LineTooltipItem("${f4.format(v.y)} $yAxisTitle \n", - const TextStyle(), - children: [ - TextSpan( - text: dateFormat.format( - DateTime.fromMillisecondsSinceEpoch( - v.x.floor()))) - ]) - ]; - }, - )))), - ), - ], - )); +double takeStat(TetrioPlayerFromLeaderboard entry, String stat) { + switch (stat) { + case "TR": + return entry.rating; + case "Glicko": + return entry.glicko; + case "RD": + return entry.rd; + case "GP": + return entry.gamesPlayed.toDouble(); + case "GW": + return entry.gamesWon.toDouble(); + case "WR%": + return entry.winrate*100; + case "APM": + return entry.apm; + case "PPS": + return entry.pps; + case "VS": + return entry.vs; + case "APP": + return entry.nerdStats.app; + case "DS/S": + return entry.nerdStats.dss; + case "DS/P": + return entry.nerdStats.dsp; + case "APP + DS/P": + return entry.nerdStats.appdsp; + case "VS/APM": + return entry.nerdStats.vsapm; + case "Cheese": + return entry.nerdStats.cheese; + case "GbE": + return entry.nerdStats.gbe; + case "wAPP": + return entry.nerdStats.nyaapp; + case "Area": + return entry.nerdStats.area; + case "eTR": + return entry.estTr.esttr; + case "±eTR": + return entry.esttracc; + case "Opener": + return entry.playstyle.opener; + case "Plonk": + return entry.playstyle.plonk; + case "Inf. DS": + return entry.playstyle.infds; + case "Stride": + return entry.playstyle.stride; + case "Stride - Plonk": + return entry.playstyle.stride - entry.playstyle.plonk; + case "Opener - Inf. DS": + return entry.playstyle.opener - entry.playstyle.infds; + default: + throw ArgumentError.value(stat, "Incorrect stat", "We don't have that stat"); } } + +class MyScatterSpot extends ScatterSpot{ + String id; + String nickname; + + MyScatterSpot(super.x, super.y, this.id, this.nickname, {super.color}); + +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index e463b34..b19d111 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.17.2" convert: dependency: transitive description: @@ -361,10 +361,10 @@ packages: dependency: "direct main" description: name: intl - sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.18.0" + version: "0.18.1" io: dependency: transitive description: @@ -417,18 +417,18 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" meta: dependency: transitive description: @@ -718,10 +718,10 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sqflite: dependency: "direct main" description: @@ -830,26 +830,26 @@ packages: dependency: transitive description: name: test - sha256: "3dac9aecf2c3991d09b9cdde4f98ded7b30804a88a0d7e4e7e1678e78d6b97f4" + sha256: "13b41f318e2a5751c3169137103b60c584297353d4b1761b66029bae6411fe46" url: "https://pub.dev" source: hosted - version: "1.24.1" + version: "1.24.3" test_api: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.0" test_core: dependency: transitive description: name: test_core - sha256: "5138dbffb77b2289ecb12b81c11ba46036590b72a64a7a90d6ffb880f1a29e93" + sha256: "99806e9e6d95c7b059b7a0fc08f07fc53fabe54a829497f0d9676299f1e8637e" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.5.3" typed_data: dependency: transitive description: @@ -946,6 +946,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + url: "https://pub.dev" + source: hosted + version: "0.1.4-beta" web_socket_channel: dependency: transitive description: @@ -995,5 +1003,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.0.0 <4.0.0" + dart: ">=3.1.0-185.0.dev <4.0.0" flutter: ">=3.10.0"