2023-08-14 21:26:20 +00:00
|
|
|
import 'dart:math';
|
|
|
|
|
|
|
|
import 'package:fl_chart/fl_chart.dart';
|
2023-07-29 18:01:49 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:intl/intl.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/widgets/stat_sell_num.dart';
|
2023-08-14 21:26:20 +00:00
|
|
|
import 'package:tetra_stats/widgets/tl_thingy.dart';
|
2023-07-29 18:01:49 +00:00
|
|
|
//import 'package:tetra_stats/widgets/tl_thingy.dart';
|
|
|
|
|
|
|
|
final DateFormat dateFormat =
|
|
|
|
DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).add_Hms();
|
|
|
|
double pfpHeight = 128;
|
|
|
|
|
|
|
|
class RankView extends StatefulWidget {
|
|
|
|
final List rank;
|
|
|
|
const RankView({Key? key, required this.rank}) : super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<StatefulWidget> createState() => RankState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class RankState extends State<RankView> with SingleTickerProviderStateMixin {
|
|
|
|
late ScrollController _scrollController;
|
|
|
|
late TabController _tabController;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
_scrollController = ScrollController();
|
|
|
|
_tabController = TabController(length: 6, vsync: this);
|
|
|
|
super.initState();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
_tabController.dispose();
|
|
|
|
_scrollController.dispose();
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
void _justUpdate() {
|
|
|
|
setState(() {});
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
final t = Translations.of(context);
|
|
|
|
bool bigScreen = MediaQuery.of(context).size.width > 768;
|
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(
|
|
|
|
title: Text(widget.rank[0].rank.toUpperCase()),
|
|
|
|
),
|
|
|
|
backgroundColor: Colors.black,
|
|
|
|
body: SafeArea(
|
|
|
|
child: NestedScrollView(
|
|
|
|
controller: _scrollController,
|
|
|
|
headerSliverBuilder: (context, value) {
|
|
|
|
return [
|
|
|
|
SliverToBoxAdapter(
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Flex(
|
|
|
|
direction: Axis.vertical,
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
Stack(
|
|
|
|
alignment: Alignment.topCenter,
|
|
|
|
children: [
|
2023-08-14 21:26:20 +00:00
|
|
|
Image.asset(
|
2023-07-29 18:01:49 +00:00
|
|
|
"res/tetrio_tl_alpha_ranks/${widget.rank[0].rank}.png",
|
|
|
|
fit: BoxFit.fitHeight,
|
|
|
|
height: 128),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
Flexible(
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
"Values for ${widget.rank[0].rank.toUpperCase()} rank",
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: "Eurostile Round Extended",
|
|
|
|
fontSize: bigScreen ? 42 : 28)),
|
|
|
|
Text(
|
|
|
|
"${widget.rank[1]["entries"].length} players",
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: "Eurostile Round Extended",
|
|
|
|
fontSize: bigScreen ? 42 : 28)),
|
|
|
|
],
|
|
|
|
)),
|
|
|
|
],
|
|
|
|
),
|
2023-08-14 21:26:20 +00:00
|
|
|
// Wrap(
|
|
|
|
// direction: Axis.horizontal,
|
|
|
|
// alignment: WrapAlignment.center,
|
|
|
|
// spacing: 25,
|
|
|
|
// crossAxisAlignment: WrapCrossAlignment.start,
|
|
|
|
// clipBehavior: Clip.hardEdge, // hard WHAT???
|
|
|
|
// children: [
|
|
|
|
// StatCellNum(
|
|
|
|
// playerStat: widget.rank[1]["totalGamesPlayed"],
|
|
|
|
// playerStatLabel: "Total games\nplayed",
|
|
|
|
// isScreenBig: bigScreen,
|
|
|
|
// higherIsBetter: true,
|
|
|
|
// ),
|
|
|
|
// StatCellNum(
|
|
|
|
// playerStat: widget.rank[1]["totalGamesWon"],
|
|
|
|
// playerStatLabel: "Total games\nwon",
|
|
|
|
// isScreenBig: bigScreen,
|
|
|
|
// higherIsBetter: true,
|
|
|
|
// ),
|
|
|
|
// StatCellNum(
|
|
|
|
// playerStat: (widget.rank[1]["totalGamesWon"] /
|
|
|
|
// widget.rank[1]["totalGamesPlayed"]) *
|
|
|
|
// 100,
|
|
|
|
// playerStatLabel: t.statCellNum.winrate,
|
|
|
|
// fractionDigits: 3,
|
|
|
|
// isScreenBig: bigScreen,
|
|
|
|
// higherIsBetter: true)
|
|
|
|
// ],
|
|
|
|
// ),
|
2023-07-29 18:01:49 +00:00
|
|
|
],
|
|
|
|
)),
|
|
|
|
SliverToBoxAdapter(
|
|
|
|
child: TabBar(
|
|
|
|
controller: _tabController,
|
|
|
|
isScrollable: true,
|
|
|
|
tabs: const [
|
|
|
|
Tab(text: "Chart"),
|
|
|
|
Tab(text: "Entries"),
|
|
|
|
Tab(text: "Minimums"),
|
|
|
|
Tab(text: "Averages"),
|
|
|
|
Tab(text: "Maximums"),
|
|
|
|
Tab(text: "Other"),
|
|
|
|
],
|
|
|
|
)),
|
|
|
|
];
|
|
|
|
},
|
|
|
|
body: TabBarView(
|
|
|
|
controller: _tabController,
|
|
|
|
children: [
|
|
|
|
Column(
|
2023-08-14 21:26:20 +00:00
|
|
|
mainAxisSize: MainAxisSize.min,
|
2023-07-29 18:01:49 +00:00
|
|
|
children: [
|
2023-08-14 21:26:20 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),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)));
|
|
|
|
})
|
2023-07-29 18:01:49 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
Column(
|
|
|
|
children: [
|
|
|
|
Text("Entries",
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: "Eurostile Round Extended",
|
|
|
|
fontSize: bigScreen ? 42 : 28)),
|
|
|
|
Expanded(
|
|
|
|
child: ListView.builder(
|
|
|
|
itemCount: widget.rank[1]["entries"]!.length,
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
bool bigScreen =
|
|
|
|
MediaQuery.of(context).size.width > 768;
|
|
|
|
return ListTile(
|
|
|
|
title: Text(
|
|
|
|
widget.rank[1]["entries"][index].username,
|
|
|
|
style: const TextStyle(
|
|
|
|
fontFamily:
|
|
|
|
"Eurostile Round Extended")),
|
|
|
|
subtitle: Text(
|
2023-08-08 19:30:24 +00:00
|
|
|
"${f2.format(widget.rank[1]["entries"][index].apm)} APM, ${f2.format(widget.rank[1]["entries"][index].pps)} PPS, ${f2.format(widget.rank[1]["entries"][index].vs)} VS, ${f2.format(widget.rank[1]["entries"][index].nerdStats.app)} APP, ${f2.format(widget.rank[1]["entries"][index].nerdStats.vsapm)} VS/APM"),
|
2023-07-29 18:01:49 +00:00
|
|
|
trailing: Row(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
"${f2.format(widget.rank[1]["entries"][index].rating)} TR",
|
|
|
|
style: bigScreen
|
|
|
|
? const TextStyle(fontSize: 28)
|
|
|
|
: null),
|
|
|
|
Image.asset(
|
|
|
|
"res/tetrio_tl_alpha_ranks/${widget.rank[1]["entries"][index].rank}.png",
|
|
|
|
height: bigScreen ? 48 : 16),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
onTap: () {
|
|
|
|
Navigator.push(
|
|
|
|
context,
|
|
|
|
MaterialPageRoute(
|
|
|
|
builder: (context) => MainView(
|
|
|
|
player: widget
|
|
|
|
.rank[1]["entries"][index]
|
|
|
|
.userId),
|
|
|
|
maintainState: false,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
Column(
|
|
|
|
children: [
|
|
|
|
Text("Lowest Values",
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: "Eurostile Round Extended",
|
|
|
|
fontSize: bigScreen ? 42 : 28)),
|
|
|
|
Expanded(
|
|
|
|
child: ListView(
|
|
|
|
children: [
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestTR"],
|
|
|
|
label: "Tetra Rating",
|
|
|
|
id: widget.rank[1]["lowestTRid"],
|
|
|
|
username: widget.rank[1]["lowestTRnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestGlicko"],
|
|
|
|
label: "Glicko",
|
|
|
|
id: widget.rank[1]["lowestGlickoID"],
|
|
|
|
username: widget.rank[1]["lowestGlickoNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
2023-08-08 19:30:24 +00:00
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestRD"],
|
|
|
|
label: "Rating Deviation",
|
|
|
|
id: widget.rank[1]["lowestRdID"],
|
|
|
|
username: widget.rank[1]["lowestRdNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-07-29 18:01:49 +00:00
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestGamesPlayed"],
|
|
|
|
label: "Games Played",
|
|
|
|
id: widget.rank[1]["lowestGamesPlayedID"],
|
|
|
|
username: widget.rank[1]
|
|
|
|
["lowestGamesPlayedNick"],
|
|
|
|
approximate: false),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestGamesWon"],
|
|
|
|
label: "Games Won",
|
|
|
|
id: widget.rank[1]["lowestGamesWonID"],
|
|
|
|
username: widget.rank[1]
|
|
|
|
["lowestGamesWonNick"],
|
|
|
|
approximate: false),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestWinrate"] * 100,
|
|
|
|
label: "Winrate Percentage",
|
|
|
|
id: widget.rank[1]["lowestWinrateID"],
|
|
|
|
username: widget.rank[1]["lowestWinrateNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestAPM"],
|
|
|
|
label: "Attack Per Minute",
|
|
|
|
id: widget.rank[1]["lowestAPMid"],
|
|
|
|
username: widget.rank[1]["lowestAPMnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestPPS"],
|
|
|
|
label: "Pieces Per Second",
|
|
|
|
id: widget.rank[1]["lowestPPSid"],
|
|
|
|
username: widget.rank[1]["lowestPPSnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestVS"],
|
|
|
|
label: "Versus Score",
|
|
|
|
id: widget.rank[1]["lowestVSid"],
|
|
|
|
username: widget.rank[1]["lowestVSnick"],
|
|
|
|
approximate: false,
|
2023-08-08 19:30:24 +00:00
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestAPP"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.app
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestAPPid"],
|
|
|
|
username: widget.rank[1]["lowestAPPnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["lowestVSAPM"],
|
|
|
|
label: "VS / APM",
|
|
|
|
id: widget.rank[1]["lowestVSAPMid"],
|
|
|
|
username: widget.rank[1]["lowestVSAPMnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestDSS"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.dss
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestDSSid"],
|
|
|
|
username: widget.rank[1]["lowestDSSnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestDSP"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.dsp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestDSPid"],
|
|
|
|
username: widget.rank[1]["lowestDSPnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestAPPDSP"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.dsp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestAPPDSPid"],
|
|
|
|
username: widget.rank[1]["lowestAPPDSPnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestCheese"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.cheese
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestCheeseID"],
|
|
|
|
username: widget.rank[1]["lowestCheeseNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestGBE"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.gbe
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestGBEid"],
|
|
|
|
username: widget.rank[1]["lowestGBEnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestNyaAPP"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.nyaapp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestNyaAPPid"],
|
|
|
|
username: widget.rank[1]["lowestNyaAPPnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestArea"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.area
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestAreaID"],
|
|
|
|
username: widget.rank[1]["lowestAreaNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 1),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestEstTR"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.estOfTR
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestEstTRid"],
|
|
|
|
username: widget.rank[1]["lowestEstTRnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestEstAcc"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.accOfEst
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["lowestEstAccID"],
|
|
|
|
username: widget.rank[1]["lowestEstAccNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestOpener"],
|
|
|
|
label: "Opener",
|
|
|
|
id: widget.rank[1]["lowestOpenerID"],
|
|
|
|
username: widget.rank[1]["lowestOpenerNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestPlonk"],
|
|
|
|
label: "Plonk",
|
|
|
|
id: widget.rank[1]["lowestPlonkID"],
|
|
|
|
username: widget.rank[1]["lowestPlonkNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestStride"],
|
|
|
|
label: "Stride",
|
|
|
|
id: widget.rank[1]["lowestStrideID"],
|
|
|
|
username: widget.rank[1]["lowestStrideNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["lowestInfDS"],
|
|
|
|
label: "InfDS",
|
|
|
|
id: widget.rank[1]["lowestInfDSid"],
|
|
|
|
username: widget.rank[1]["lowestInfDSnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3)
|
2023-07-29 18:01:49 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
Column(
|
2023-08-08 19:30:24 +00:00
|
|
|
children: [
|
|
|
|
Text("Average Values",
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: "Eurostile Round Extended",
|
|
|
|
fontSize: bigScreen ? 42 : 28)),
|
|
|
|
Expanded(
|
2023-08-14 21:26:20 +00:00
|
|
|
child: ListView(children: [
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].rating,
|
|
|
|
label: "Tetra Rating",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].glicko,
|
|
|
|
label: "Glicko",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].rd,
|
|
|
|
label: "Rating Deviation",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].gamesPlayed,
|
|
|
|
label: "Games Played",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 0),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].gamesWon,
|
|
|
|
label: "Games Won",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 0),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].winrate * 100,
|
|
|
|
label: "Winrate",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].apm,
|
|
|
|
label: "Attack per Minute",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].pps,
|
|
|
|
label: "Pieces per Second",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[0].vs,
|
|
|
|
label: "Versus Score",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgAPP"],
|
|
|
|
label: "Attack Per Piece",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgAPP"],
|
|
|
|
label: "VS / APM",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgDSS"],
|
|
|
|
label: t.statCellNum.dss
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgDSP"],
|
|
|
|
label: t.statCellNum.dsp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgAPPDSP"],
|
|
|
|
label: t.statCellNum.dsp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgCheese"],
|
|
|
|
label: t.statCellNum.cheese
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgGBE"],
|
|
|
|
label: t.statCellNum.gbe
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgNyaAPP"],
|
|
|
|
label: t.statCellNum.nyaapp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgArea"],
|
|
|
|
label: t.statCellNum.area
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 1),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgEstTR"],
|
|
|
|
label: t.statCellNum.estOfTR
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgEstAcc"],
|
|
|
|
label: t.statCellNum.accOfEst
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgOpener"],
|
|
|
|
label: "Opener",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgPlonk"],
|
|
|
|
label: "Plonk",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgStride"],
|
|
|
|
label: "Stride",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["avgInfDS"],
|
|
|
|
label: "InfDS",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
]))
|
|
|
|
],
|
2023-07-29 18:01:49 +00:00
|
|
|
),
|
|
|
|
Column(
|
|
|
|
children: [
|
|
|
|
Text("Highest Values",
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: "Eurostile Round Extended",
|
|
|
|
fontSize: bigScreen ? 42 : 28)),
|
|
|
|
Expanded(
|
|
|
|
child: ListView(
|
|
|
|
children: [
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestTR"],
|
|
|
|
label: "Tetra Rating",
|
|
|
|
id: widget.rank[1]["highestTRid"],
|
|
|
|
username: widget.rank[1]["highestTRnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestGlicko"],
|
|
|
|
label: "Glicko",
|
|
|
|
id: widget.rank[1]["highestGlickoID"],
|
|
|
|
username: widget.rank[1]["highestGlickoNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
2023-08-08 19:30:24 +00:00
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestRD"],
|
|
|
|
label: "Rating Deviation",
|
|
|
|
id: widget.rank[1]["highestRdID"],
|
|
|
|
username: widget.rank[1]["highestRdNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-07-29 18:01:49 +00:00
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestGamesPlayed"],
|
|
|
|
label: "Games Played",
|
|
|
|
id: widget.rank[1]["highestGamesPlayedID"],
|
|
|
|
username: widget.rank[1]
|
|
|
|
["highestGamesPlayedNick"],
|
|
|
|
approximate: false),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestGamesWon"],
|
|
|
|
label: "Games Won",
|
|
|
|
id: widget.rank[1]["highestGamesWonID"],
|
|
|
|
username: widget.rank[1]
|
|
|
|
["highestGamesWonNick"],
|
|
|
|
approximate: false),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestWinrate"] * 100,
|
|
|
|
label: "Winrate Percentage",
|
|
|
|
id: widget.rank[1]["highestWinrateID"],
|
|
|
|
username: widget.rank[1]
|
|
|
|
["highestWinrateNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestAPM"],
|
|
|
|
label: "Attack Per Minute",
|
|
|
|
id: widget.rank[1]["highestAPMid"],
|
|
|
|
username: widget.rank[1]["highestAPMnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestPPS"],
|
|
|
|
label: "Pieces Per Second",
|
|
|
|
id: widget.rank[1]["highestPPSid"],
|
|
|
|
username: widget.rank[1]["highestPPSnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestVS"],
|
|
|
|
label: "Versus Score",
|
|
|
|
id: widget.rank[1]["highestVSid"],
|
|
|
|
username: widget.rank[1]["highestVSnick"],
|
|
|
|
approximate: false,
|
2023-08-08 19:30:24 +00:00
|
|
|
fractionDigits: 2),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestAPP"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.app
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestAPPid"],
|
|
|
|
username: widget.rank[1]["highestAPPnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["highestVSAPM"],
|
|
|
|
label: "VS / APM",
|
|
|
|
id: widget.rank[1]["highestVSAPMid"],
|
|
|
|
username: widget.rank[1]["highestVSAPMnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestDSS"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.dss
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestDSSid"],
|
|
|
|
username: widget.rank[1]["highestDSSnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestDSP"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.dsp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestDSPid"],
|
|
|
|
username: widget.rank[1]["highestDSPnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestAPPDSP"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.dsp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestAPPDSPid"],
|
|
|
|
username: widget.rank[1]["highestAPPDSPnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestCheese"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.cheese
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestCheeseID"],
|
|
|
|
username: widget.rank[1]["highestCheeseNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestGBE"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.gbe
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestGBEid"],
|
|
|
|
username: widget.rank[1]["highestGBEnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestNyaAPP"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.nyaapp
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestNyaAPPid"],
|
|
|
|
username: widget.rank[1]["highestNyaAPPnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestArea"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.area
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestAreaID"],
|
|
|
|
username: widget.rank[1]["highestAreaNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 1),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestEstTR"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.estOfTR
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestEstTRid"],
|
|
|
|
username: widget.rank[1]["highestEstTRnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 2),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestEstAcc"],
|
2023-08-14 21:26:20 +00:00
|
|
|
label: t.statCellNum.accOfEst
|
|
|
|
.replaceAll(RegExp(r'\n'), " "),
|
2023-08-08 19:30:24 +00:00
|
|
|
id: widget.rank[1]["highestEstAccID"],
|
|
|
|
username: widget.rank[1]["highestEstAccNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestOpener"],
|
|
|
|
label: "Opener",
|
|
|
|
id: widget.rank[1]["highestOpenerID"],
|
|
|
|
username: widget.rank[1]["highestOpenerNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestPlonk"],
|
|
|
|
label: "Plonk",
|
|
|
|
id: widget.rank[1]["highestPlonkID"],
|
|
|
|
username: widget.rank[1]["highestPlonkNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestStride"],
|
|
|
|
label: "Stride",
|
|
|
|
id: widget.rank[1]["highestStrideID"],
|
|
|
|
username: widget.rank[1]["highestStrideNick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-08-14 21:26:20 +00:00
|
|
|
_ListEntry(
|
2023-08-08 19:30:24 +00:00
|
|
|
value: widget.rank[1]["highestInfDS"],
|
|
|
|
label: "InfDS",
|
|
|
|
id: widget.rank[1]["highestInfDSid"],
|
|
|
|
username: widget.rank[1]["highestInfDSnick"],
|
|
|
|
approximate: false,
|
|
|
|
fractionDigits: 3),
|
2023-07-29 18:01:49 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
Column(
|
2023-08-14 21:26:20 +00:00
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
child: ListView(
|
|
|
|
children: [
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["totalGamesPlayed"],
|
|
|
|
label: "Total Games Played",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 0),
|
|
|
|
_ListEntry(
|
|
|
|
value: widget.rank[1]["totalGamesWon"],
|
|
|
|
label: "Total Games Won",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 0),
|
|
|
|
_ListEntry(
|
|
|
|
value: (widget.rank[1]["totalGamesWon"] /
|
|
|
|
widget.rank[1]["totalGamesPlayed"]) *
|
|
|
|
100,
|
|
|
|
label: "Winrate",
|
|
|
|
id: "",
|
|
|
|
username: "",
|
|
|
|
approximate: true,
|
|
|
|
fractionDigits: 3),
|
|
|
|
Center(
|
|
|
|
child: Text("Typical TL profile",
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: "Eurostile Round Extended",
|
|
|
|
fontSize: bigScreen ? 42 : 28)),
|
|
|
|
),
|
|
|
|
SizedBox(
|
|
|
|
height: 800,
|
|
|
|
child: TLThingy(tl: widget.rank[0], userID: ""),
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
],
|
2023-07-29 18:01:49 +00:00
|
|
|
),
|
|
|
|
],
|
|
|
|
))));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class _ListEntry extends StatelessWidget {
|
|
|
|
final num value;
|
|
|
|
final String label;
|
|
|
|
final String id;
|
|
|
|
final String username;
|
|
|
|
final bool approximate;
|
|
|
|
final int? fractionDigits;
|
|
|
|
const _ListEntry(
|
|
|
|
{required this.value,
|
|
|
|
required this.label,
|
|
|
|
this.fractionDigits,
|
|
|
|
required this.id,
|
|
|
|
required this.username,
|
|
|
|
required this.approximate});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
NumberFormat f = NumberFormat.decimalPatternDigits(
|
|
|
|
locale: LocaleSettings.currentLocale.languageCode,
|
|
|
|
decimalDigits: fractionDigits ?? 0);
|
|
|
|
return ListTile(
|
|
|
|
title: Text(label),
|
|
|
|
trailing: Column(
|
2023-08-08 19:30:24 +00:00
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
2023-07-29 18:01:49 +00:00
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
Text(f.format(value),
|
|
|
|
style: const TextStyle(fontSize: 22, height: 0.9)),
|
|
|
|
if (id.isNotEmpty) Text('for player $username')
|
|
|
|
],
|
|
|
|
),
|
|
|
|
onTap: id.isNotEmpty
|
|
|
|
? () {
|
|
|
|
Navigator.push(
|
|
|
|
context,
|
|
|
|
MaterialPageRoute(
|
|
|
|
builder: (context) => MainView(player: id),
|
|
|
|
maintainState: false,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
: null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2023-08-14 21:26:20 +00:00
|
|
|
|
|
|
|
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});
|
|
|
|
|
|
|
|
@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())))
|
|
|
|
])
|
|
|
|
];
|
|
|
|
},
|
|
|
|
)))),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|