Those graphs are mess but well see
This commit is contained in:
parent
974294f167
commit
5d5ac32a8b
|
@ -13,7 +13,7 @@
|
||||||
- ~~Stats Calculator~~
|
- ~~Stats Calculator~~
|
||||||
- ~~Ability to compare player with himself in past~~
|
- ~~Ability to compare player with himself in past~~
|
||||||
- ~~Tetra League matches history~~ *dev build are here*
|
- ~~Tetra League matches history~~ *dev build are here*
|
||||||
- Tetra League historic charts for tracked players (maybe even same sh*t for 40l and blitz well see)
|
- ~~Tetra League historic charts for tracked players~~ (bit mess idk)
|
||||||
- Better UI with delta and hints for stats *that will be v0.2.0*
|
- Better UI with delta and hints for stats *that will be v0.2.0*
|
||||||
- Ability to compare player with APM-PPS-VS stats
|
- Ability to compare player with APM-PPS-VS stats
|
||||||
- Ability to fetch Tetra League leaderboard
|
- Ability to fetch Tetra League leaderboard
|
||||||
|
|
|
@ -614,11 +614,11 @@ class EndContextMulti {
|
||||||
naturalOrder = json['naturalorder'];
|
naturalOrder = json['naturalorder'];
|
||||||
wins = json['wins'];
|
wins = json['wins'];
|
||||||
points = json['points']['primary'];
|
points = json['points']['primary'];
|
||||||
secondary = json['points']['secondary'];
|
secondary = json['points']['secondary'].toDouble();
|
||||||
tertiary = json['points']['tertiary'];
|
tertiary = json['points']['tertiary'].toDouble();
|
||||||
secondaryTracking = json['points']['secondaryAvgTracking'].cast<double>();
|
secondaryTracking = json['points']['secondaryAvgTracking'].cast<double>();
|
||||||
tertiaryTracking = json['points']['tertiaryAvgTracking'].cast<double>();
|
tertiaryTracking = json['points']['tertiaryAvgTracking'].cast<double>();
|
||||||
extra = json['points']['extra']['vs'];
|
extra = json['points']['extra']['vs'].toDouble();
|
||||||
extraTracking = json['points']['extraAvgTracking']['aggregatestats___vsscore'].cast<double>();
|
extraTracking = json['points']['extraAvgTracking']['aggregatestats___vsscore'].cast<double>();
|
||||||
nerdStats = NerdStats(secondary, tertiary, extra);
|
nerdStats = NerdStats(secondary, tertiary, extra);
|
||||||
estTr = EstTr(secondary, tertiary, extra, noTrRd, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);
|
estTr = EstTr(secondary, tertiary, extra, noTrRd, nerdStats.app, nerdStats.dss, nerdStats.dsp, nerdStats.gbe);
|
||||||
|
|
|
@ -136,7 +136,7 @@ class TetrioService extends DB {
|
||||||
: [];
|
: [];
|
||||||
var zen = TetrioZen.fromJson(jsonRecords['data']['zen']);
|
var zen = TetrioZen.fromJson(jsonRecords['data']['zen']);
|
||||||
Map<String, dynamic> map = {"user": userID.toLowerCase().trim(), "sprint": sprint, "blitz": blitz, "zen": zen};
|
Map<String, dynamic> map = {"user": userID.toLowerCase().trim(), "sprint": sprint, "blitz": blitz, "zen": zen};
|
||||||
developer.log("fetchRecords: $userID stream retrieved and cached", name: "services/tetrio_crud");
|
developer.log("fetchRecords: $userID records retrieved and cached", name: "services/tetrio_crud");
|
||||||
_recordsCache[jsonDecode(response.body)['cache']['cached_until'].toString()] = map;
|
_recordsCache[jsonDecode(response.body)['cache']['cached_until'].toString()] = map;
|
||||||
return map;
|
return map;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||||
|
@ -20,6 +21,7 @@ const allowedHeightForPlayerBioInPixels = 30.0;
|
||||||
const givenTextHeightByScreenPercentage = 0.3;
|
const givenTextHeightByScreenPercentage = 0.3;
|
||||||
final NumberFormat timeInSec = NumberFormat("#,###.###s.");
|
final NumberFormat timeInSec = NumberFormat("#,###.###s.");
|
||||||
final NumberFormat f2 = NumberFormat.decimalPatternDigits(decimalDigits: 2);
|
final NumberFormat f2 = NumberFormat.decimalPatternDigits(decimalDigits: 2);
|
||||||
|
final DateFormat dateFormat = DateFormat.yMMMd().add_Hms();
|
||||||
|
|
||||||
class MainView extends StatefulWidget {
|
class MainView extends StatefulWidget {
|
||||||
const MainView({Key? key}) : super(key: key);
|
const MainView({Key? key}) : super(key: key);
|
||||||
|
@ -106,10 +108,14 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
Future<List> fetch(String nickOrID) async {
|
Future<List> fetch(String nickOrID) async {
|
||||||
TetrioPlayer me = await teto.fetchPlayer(nickOrID);
|
TetrioPlayer me = await teto.fetchPlayer(nickOrID);
|
||||||
setState((){_titleNickname = me.username;});
|
setState((){_titleNickname = me.username;});
|
||||||
bool isTracking = await teto.isPlayerTracking(nickOrID);
|
bool isTracking = await teto.isPlayerTracking(me.userId);
|
||||||
if (isTracking) teto.storeState(me);
|
List<TetrioPlayer> states = [];
|
||||||
|
if (isTracking){
|
||||||
|
teto.storeState(me);
|
||||||
|
states.addAll(await teto.getPlayer(me.userId));
|
||||||
|
}
|
||||||
Map<String, dynamic> records = await teto.fetchRecords(me.userId);
|
Map<String, dynamic> records = await teto.fetchRecords(me.userId);
|
||||||
return [me, records, isTracking];
|
return [me, records, states, isTracking];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _justUpdate() {
|
void _justUpdate() {
|
||||||
|
@ -233,7 +239,7 @@ class _MainState extends State<MainView> with SingleTickerProviderStateMixin {
|
||||||
tl: snapshot.data![0].tlSeason1,
|
tl: snapshot.data![0].tlSeason1,
|
||||||
userID: snapshot.data![0].userId),
|
userID: snapshot.data![0].userId),
|
||||||
_TLRecords(userID: snapshot.data![0].userId),
|
_TLRecords(userID: snapshot.data![0].userId),
|
||||||
Text("kekwa"),
|
_TLHistory(states: snapshot.data![2]),
|
||||||
_RecordThingy(
|
_RecordThingy(
|
||||||
record: (snapshot.data![1]['sprint'].isNotEmpty)
|
record: (snapshot.data![1]['sprint'].isNotEmpty)
|
||||||
? snapshot.data![1]['sprint'][0]
|
? snapshot.data![1]['sprint'][0]
|
||||||
|
@ -415,7 +421,7 @@ class _TLRecords extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);},
|
);},
|
||||||
)]
|
)]
|
||||||
: [const Text("No records",style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28))],
|
: [const Center(child: Text("No records", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28)))],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,6 +429,77 @@ class _TLRecords extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _TLHistory extends StatelessWidget{
|
||||||
|
final List<TetrioPlayer> states;
|
||||||
|
const _TLHistory({super.key, required this.states});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
||||||
|
List<FlSpot> trData = [for (var state in states) FlSpot(state.state.millisecondsSinceEpoch.toDouble(), state.tlSeason1.rating)];
|
||||||
|
List<FlSpot> apmData = [for (var state in states) FlSpot(state.state.millisecondsSinceEpoch.toDouble(), state.tlSeason1.apm!)];
|
||||||
|
List<FlSpot> ppsData = [for (var state in states) FlSpot(state.state.millisecondsSinceEpoch.toDouble(), state.tlSeason1.pps!)];
|
||||||
|
List<FlSpot> vsData = [for (var state in states) FlSpot(state.state.millisecondsSinceEpoch.toDouble(), state.tlSeason1.vs!)];
|
||||||
|
return ListView(physics: const ClampingScrollPhysics(),
|
||||||
|
children: states.isNotEmpty ? [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
_HistoryChartThigy(data: trData, title: "Tetra Rating", yAxisTitle: "TR", bigScreen: bigScreen),
|
||||||
|
_HistoryChartThigy(data: apmData, title: "Attack Per Minute", yAxisTitle: "APM", bigScreen: bigScreen),
|
||||||
|
_HistoryChartThigy(data: ppsData, title: "Pieces Per Second", yAxisTitle: "PPS", bigScreen: bigScreen),
|
||||||
|
_HistoryChartThigy(data: vsData, title: "Versus Score", yAxisTitle: "VS", bigScreen: bigScreen),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
] : [const Center(child: Text("No history saved", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28)))]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HistoryChartThigy extends StatelessWidget{
|
||||||
|
final List<FlSpot> data;
|
||||||
|
final String title;
|
||||||
|
final String yAxisTitle;
|
||||||
|
final bool bigScreen;
|
||||||
|
const _HistoryChartThigy({super.key, required this.data, required this.title, required this.yAxisTitle, required this.bigScreen});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AspectRatio(
|
||||||
|
aspectRatio: bigScreen ? 1.9 : 1.1,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.center, children: [Text(title, style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28))]),
|
||||||
|
Padding( padding: bigScreen ? const EdgeInsets.fromLTRB(40, 80, 40, 48) : const EdgeInsets.fromLTRB(0, 80, 0, 48) ,
|
||||||
|
child: LineChart(
|
||||||
|
LineChartData(
|
||||||
|
lineBarsData: [LineChartBarData(spots: data)],
|
||||||
|
borderData: FlBorderData(show: false),
|
||||||
|
titlesData: FlTitlesData(topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||||
|
rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||||
|
bottomTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: 30, getTitlesWidget: (double value, TitleMeta meta){
|
||||||
|
return SideTitleWidget(
|
||||||
|
axisSide: meta.axisSide,
|
||||||
|
angle: 0.3,
|
||||||
|
child: Text(DateFormat(DateFormat.YEAR_ABBR_MONTH_DAY).format(DateTime.fromMillisecondsSinceEpoch(value.floor()))),
|
||||||
|
);
|
||||||
|
})),
|
||||||
|
leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, reservedSize: 80, getTitlesWidget: (double value, TitleMeta meta){
|
||||||
|
return SideTitleWidget(
|
||||||
|
axisSide: meta.axisSide,
|
||||||
|
child: Text(f2.format(value)),
|
||||||
|
);
|
||||||
|
}))),
|
||||||
|
lineTouchData: LineTouchData(touchTooltipData: LineTouchTooltipData(getTooltipItems: (touchedSpots) {
|
||||||
|
return [for (var v in touchedSpots) LineTooltipItem("${f2.format(v.y)} $yAxisTitle \n", TextStyle(), children: [TextSpan(text: "${dateFormat.format(DateTime.fromMillisecondsSinceEpoch(v.x.floor()))}")])];
|
||||||
|
},))
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _RecordThingy extends StatelessWidget {
|
class _RecordThingy extends StatelessWidget {
|
||||||
final RecordSingle? record;
|
final RecordSingle? record;
|
||||||
const _RecordThingy({Key? key, required this.record}) : super(key: key);
|
const _RecordThingy({Key? key, required this.record}) : super(key: key);
|
||||||
|
@ -736,10 +813,7 @@ class _RecordThingy extends StatelessWidget {
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
Text("No record",
|
const Text("No record", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28))
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: "Eurostile Round Extended",
|
|
||||||
fontSize: bigScreen ? 42 : 28))
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -307,7 +307,7 @@ class TLThingy extends StatelessWidget {
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
Text("That user never played Tetra League", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
const Text("That user never played Tetra League", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: 28)),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,7 +14,7 @@ publish_to: 'none'
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 0.1.0+3
|
version: 0.2.0+4
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.6 <3.0.0'
|
sdk: '>=2.19.6 <3.0.0'
|
||||||
|
|
Loading…
Reference in New Issue