Graph + new eTR formula + bugfix + new flutter ver

This commit is contained in:
dan63047 2023-08-20 02:20:06 +03:00
parent f058919fd2
commit a996a0b356
3 changed files with 223 additions and 159 deletions

View File

@ -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))
)
)
)
))
);
}
}

View File

@ -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 = <DropdownMenuItem>[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 {
@ -141,11 +172,6 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
body: TabBarView(
controller: _tabController,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
LayoutBuilder(builder: (context, constraints) {
return true ?
Column(
children: [
Row(
@ -158,10 +184,10 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
padding: const EdgeInsets.all(8.0),
child: Text("X axis:", style: const TextStyle(fontSize: 22))),
DropdownButton(
items: chartsData,
value: chartsData[chartsIndex].value,
items: chartsShortTitlesDropdowns,
value: chartsShortTitlesDropdowns[chartsIndexX].value,
onChanged: (value) {
chartsIndex = chartsData.indexWhere((element) => element.value == value);
chartsIndexX = chartsShortTitlesDropdowns.indexWhere((element) => element.value == value);
_justUpdate();
}
),
@ -177,10 +203,10 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
child: Text("Y axis:", style: const TextStyle(fontSize: 22)),
),
DropdownButton(
items: chartsData,
value: chartsData[chartsIndex].value,
items: chartsShortTitlesDropdowns,
value: chartsShortTitlesDropdowns[chartsIndexY].value,
onChanged: (value) {
chartsIndex = chartsData.indexWhere((element) => element.value == value);
chartsIndexY = chartsShortTitlesDropdowns.indexWhere((element) => element.value == value);
_justUpdate();
}
),
@ -188,11 +214,43 @@ class RankState extends State<RankView> with SingleTickerProviderStateMixin {
),
],
),],),
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)))
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
),
),
],
) : 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<RankView> 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<FlSpot> 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});
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});
@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())))
])
];
},
)))),
),
],
));
}
}

View File

@ -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"