2023-06-17 21:50:52 +00:00
import ' package:flutter/material.dart ' ;
import ' package:intl/intl.dart ' ;
import ' package:tetra_stats/data_objects/tetrio.dart ' ;
import ' package:fl_chart/fl_chart.dart ' ;
2023-06-27 20:55:59 +00:00
import ' package:syncfusion_flutter_gauges/gauges.dart ' ;
2023-06-17 21:50:52 +00:00
import ' package:tetra_stats/widgets/stat_sell_num.dart ' ;
var fDiff = NumberFormat ( " +#,###.###;-#,###.### " ) ;
final NumberFormat f2 = NumberFormat . decimalPatternDigits ( decimalDigits: 2 ) ;
2023-06-27 20:55:59 +00:00
final NumberFormat f3 = NumberFormat . decimalPatternDigits ( decimalDigits: 3 ) ;
2023-06-17 21:50:52 +00:00
class TLThingy extends StatelessWidget {
final TetraLeagueAlpha tl ;
final String userID ;
2023-06-28 16:50:40 +00:00
final TetraLeagueAlpha ? oldTl ;
const TLThingy ( { Key ? key , required this . tl , required this . userID , this . oldTl } ) : super ( key: key ) ;
2023-06-17 21:50:52 +00:00
@ override
Widget build ( BuildContext context ) {
return LayoutBuilder ( builder: ( context , constraints ) {
bool bigScreen = constraints . maxWidth > 768 ;
return ListView . builder (
physics: const ClampingScrollPhysics ( ) ,
itemCount: 1 ,
itemBuilder: ( BuildContext context , int index ) {
return Column (
children: ( tl . gamesPlayed > 0 )
? [
Text ( " Tetra League " , style: TextStyle ( fontFamily: " Eurostile Round Extended " , fontSize: bigScreen ? 42 : 28 ) ) ,
2023-06-28 16:50:40 +00:00
if ( oldTl ! = null ) Text ( " Comparing with data from ${ DateFormat . yMMMd ( ) . add_Hms ( ) . format ( oldTl ! . timestamp ) } " ) ,
2023-06-17 21:50:52 +00:00
if ( tl . gamesPlayed > = 10 )
Wrap (
direction: Axis . horizontal ,
alignment: WrapAlignment . spaceAround ,
crossAxisAlignment: WrapCrossAlignment . center ,
clipBehavior: Clip . hardEdge ,
children: [
userID = = " 5e32fc85ab319c2ab1beb07c " // he love her so much, you can't even imagine
? Image . asset ( " res/icons/kagari.png " , height: 128 ) // Btw why she wearing Kazamatsuri high school uniform?
: Image . asset ( " res/tetrio_tl_alpha_ranks/ ${ tl . rank } .png " , height: 128 ) ,
Column (
children: [
Text ( " ${ f2 . format ( tl . rating ) } TR " , style: TextStyle ( fontFamily: " Eurostile Round Extended " , fontSize: bigScreen ? 42 : 28 ) ) ,
2023-06-28 16:50:40 +00:00
if ( oldTl ! = null ) Text (
" ${ fDiff . format ( tl . rating - oldTl ! . rating ) } TR " ,
textAlign: TextAlign . center ,
style: TextStyle (
color: tl . rating - oldTl ! . rating < 0 ?
Colors . red :
Colors . green
) ,
) ,
2023-06-17 21:50:52 +00:00
Text (
" Top ${ f2 . format ( tl . percentile * 100 ) } % ( ${ tl . percentileRank . toUpperCase ( ) } ) • Top Rank: ${ tl . bestRank . toUpperCase ( ) } • Glicko: ${ f2 . format ( tl . glicko ! ) } ± ${ f2 . format ( tl . rd ! ) } ${ tl . decaying ? ' • Decaying ' : ' ' } " ,
textAlign: TextAlign . center ,
) ,
] ,
) ,
] ,
2023-06-27 20:55:59 +00:00
) ,
if ( tl . gamesPlayed > = 10 & & tl . rd ! < 100 ) Padding (
padding: const EdgeInsets . all ( 8.0 ) ,
child: SfLinearGauge (
minimum: tl . nextAt . toDouble ( ) ,
maximum: tl . prevAt . toDouble ( ) ,
interval: tl . prevAt . toDouble ( ) - tl . nextAt . toDouble ( ) ,
ranges: [ LinearGaugeRange ( startValue: tl . standing . toDouble ( ) , endValue: tl . prevAt . toDouble ( ) , color: Colors . cyanAccent , ) ] ,
//barPointers: [LinearBarPointer(value: 80)],
isAxisInversed: true ,
isMirrored: true ,
showTicks: true ,
showLabels: true
) ,
) ,
if ( tl . gamesPlayed < 10 )
2023-06-17 21:50:52 +00:00
Text ( " ${ 10 - tl . gamesPlayed } games until being ranked " ,
softWrap: true ,
textAlign: TextAlign . center ,
style: TextStyle (
fontFamily: " Eurostile Round Extended " ,
fontSize: bigScreen ? 42 : 28 ,
overflow: TextOverflow . visible ,
) ) ,
Padding (
padding: const EdgeInsets . fromLTRB ( 0 , 16 , 0 , 48 ) ,
child: Wrap (
direction: Axis . horizontal ,
alignment: WrapAlignment . center ,
spacing: 25 ,
crossAxisAlignment: WrapCrossAlignment . start ,
clipBehavior: Clip . hardEdge ,
children: [
2023-06-28 21:33:58 +00:00
if ( tl . apm ! = null ) StatCellNum ( playerStat: tl . apm ! , isScreenBig: bigScreen , fractionDigits: 2 , playerStatLabel: " Attack \n Per Minute " , higherIsBetter: true , oldPlayerStat: oldTl ? . apm ) ,
if ( tl . pps ! = null ) StatCellNum ( playerStat: tl . pps ! , isScreenBig: bigScreen , fractionDigits: 2 , playerStatLabel: " Pieces \n Per Second " , higherIsBetter: true , oldPlayerStat: oldTl ? . pps ) ,
2023-06-28 16:50:40 +00:00
if ( tl . vs ! = null ) StatCellNum ( playerStat: tl . vs ! , isScreenBig: bigScreen , fractionDigits: 2 , playerStatLabel: " Versus \n Score " , higherIsBetter: true , oldPlayerStat: oldTl ? . vs ) ,
if ( tl . standing > 0 ) StatCellNum ( playerStat: tl . standing , isScreenBig: bigScreen , playerStatLabel: " Leaderboard \n placement " , higherIsBetter: false , oldPlayerStat: oldTl ? . standing ) ,
if ( tl . standingLocal > 0 ) StatCellNum ( playerStat: tl . standingLocal , isScreenBig: bigScreen , playerStatLabel: " Country LB \n placement " , higherIsBetter: false , oldPlayerStat: oldTl ? . standingLocal ) ,
StatCellNum ( playerStat: tl . gamesPlayed , isScreenBig: bigScreen , playerStatLabel: " Games \n played " , higherIsBetter: true , oldPlayerStat: oldTl ? . gamesPlayed ) ,
StatCellNum ( playerStat: tl . gamesWon , isScreenBig: bigScreen , playerStatLabel: " Games \n won " , higherIsBetter: true , oldPlayerStat: oldTl ? . gamesWon ) ,
StatCellNum ( playerStat: tl . winrate * 100 , isScreenBig: bigScreen , fractionDigits: 2 , playerStatLabel: " Winrate \n precentage " , higherIsBetter: true , oldPlayerStat: oldTl ! = null ? oldTl ! . winrate * 100 : null ) ,
2023-06-17 21:50:52 +00:00
] ,
) ,
) ,
if ( tl . nerdStats ! = null )
Column (
children: [
Text ( " Nerd Stats " , style: TextStyle ( fontFamily: " Eurostile Round Extended " , fontSize: bigScreen ? 42 : 28 ) ) ,
Padding (
2023-06-27 20:55:59 +00:00
padding: const EdgeInsets . fromLTRB ( 0 , 40 , 0 , 0 ) ,
2023-06-17 21:50:52 +00:00
child: Wrap (
direction: Axis . horizontal ,
alignment: WrapAlignment . center ,
2023-06-27 20:55:59 +00:00
spacing: 35 ,
2023-06-17 21:50:52 +00:00
crossAxisAlignment: WrapCrossAlignment . start ,
clipBehavior: Clip . hardEdge ,
children: [
2023-06-27 20:55:59 +00:00
SizedBox (
width: 200 ,
height: 120 ,
child: SfRadialGauge (
title: const GaugeTitle ( text: " Attack Per Piece " ) ,
axes: [ RadialAxis (
startAngle: 180 ,
endAngle: 360 ,
showLabels: false ,
showTicks: false ,
radiusFactor: 2.1 ,
2023-06-28 16:50:40 +00:00
centerY: 0.4 ,
2023-06-27 20:55:59 +00:00
minimum: 0 ,
maximum: 1 ,
ranges: [
GaugeRange ( startValue: 0 , endValue: 0.2 , color: Colors . red ) ,
GaugeRange ( startValue: 0.2 , endValue: 0.4 , color: Colors . yellow ) ,
GaugeRange ( startValue: 0.4 , endValue: 0.6 , color: Colors . green ) ,
GaugeRange ( startValue: 0.6 , endValue: 0.8 , color: Colors . blue ) ,
GaugeRange ( startValue: 0.8 , endValue: 1 , color: Colors . purple ) ,
] ,
pointers: [
NeedlePointer (
value: tl . nerdStats ! . app ,
enableAnimation: true ,
needleLength: 0.9 ,
needleStartWidth: 2 ,
needleEndWidth: 15 ,
knobStyle: const KnobStyle ( color: Colors . transparent ) ,
gradient: const LinearGradient ( colors: [ Colors . transparent , Colors . white ] , begin: Alignment . bottomCenter , end: Alignment . topCenter , stops: [ 0.5 , 1 ] ) , )
] ,
2023-06-28 16:50:40 +00:00
annotations: [ GaugeAnnotation (
widget: TextButton ( child: Text ( f3 . format ( tl . nerdStats ! . app ) ,
style: const TextStyle ( fontFamily: " Eurostile Round Extended " , fontSize: 36 , color: Colors . white ) ) ,
onPressed: ( ) {
showDialog (
context: context ,
builder: ( BuildContext context ) = > AlertDialog (
title: const Text ( " Attack Per Piece " ,
style: TextStyle (
fontFamily: " Eurostile Round Extended " ) ) ,
content: SingleChildScrollView (
child: ListBody ( children: [
const Text ( " Main efficiency metric. Tells how many attack you producing per piece " ) ,
Text ( " Raw value: ${ tl . nerdStats ! . app } " )
] ) ,
) ,
actions: < Widget > [
TextButton (
child: const Text ( ' OK ' ) ,
onPressed: ( ) {
Navigator . of ( context ) . pop ( ) ;
} ,
)
] ,
) ) ;
} , ) , verticalAlignment: GaugeAlignment . far , positionFactor: 0.05 , ) ,
if ( oldTl ! = null ) GaugeAnnotation ( widget: Text ( fDiff . format ( tl . nerdStats ! . app - oldTl ! . nerdStats ! . app ) , style: TextStyle (
color: tl . nerdStats ! . app - oldTl ! . nerdStats ! . app < 0 ?
Colors . red :
Colors . green
) , ) , positionFactor: 0.05 , ) ] ,
2023-06-27 20:55:59 +00:00
) ] , ) ,
) ,
SizedBox (
width: 200 ,
height: 120 ,
child: SfRadialGauge (
title: const GaugeTitle ( text: " VS / APM " ) ,
axes: [ RadialAxis (
startAngle: 180 ,
endAngle: 360 ,
showTicks: false ,
showLabels: false ,
radiusFactor: 2.1 ,
2023-06-28 16:50:40 +00:00
centerY: 0.4 ,
2023-06-27 20:55:59 +00:00
minimum: 1.8 ,
maximum: 2.4 ,
ranges: [
GaugeRange ( startValue: 1.8 , endValue: 2.0 , color: Colors . green ) ,
GaugeRange ( startValue: 2.0 , endValue: 2.2 , color: Colors . blue ) ,
GaugeRange ( startValue: 2.2 , endValue: 2.4 , color: Colors . purple ) ,
] ,
pointers: [
NeedlePointer (
value: tl . nerdStats ! . vsapm ,
enableAnimation: true ,
needleLength: 0.9 ,
needleStartWidth: 2 ,
needleEndWidth: 15 ,
knobStyle: const KnobStyle ( color: Colors . transparent ) ,
gradient: const LinearGradient ( colors: [ Colors . transparent , Colors . white ] , begin: Alignment . bottomCenter , end: Alignment . topCenter , stops: [ 0.5 , 1 ] ) , )
] ,
2023-06-28 16:50:40 +00:00
annotations: [ GaugeAnnotation (
widget: TextButton ( child: Text ( f3 . format ( tl . nerdStats ! . vsapm ) ,
style: const TextStyle ( fontFamily: " Eurostile Round Extended " , fontSize: 36 , color: Colors . white ) ) ,
onPressed: ( ) {
showDialog (
context: context ,
builder: ( BuildContext context ) = > AlertDialog (
title: const Text ( " VS / APM " ,
style: TextStyle (
fontFamily: " Eurostile Round Extended " ) ) ,
2023-06-28 21:33:58 +00:00
content: SingleChildScrollView (
2023-06-28 16:50:40 +00:00
child: ListBody ( children: [
2023-06-28 21:33:58 +00:00
const Text ( " Basically, tells how much and how efficient you using garbage in your attacks " ) ,
Text ( " Raw value: ${ tl . nerdStats ! . vsapm } " )
2023-06-28 16:50:40 +00:00
] ) ,
) ,
actions: < Widget > [
TextButton (
child: const Text ( ' OK ' ) ,
onPressed: ( ) {
Navigator . of ( context ) . pop ( ) ;
} ,
)
] ,
) ) ;
} , ) , verticalAlignment: GaugeAlignment . far , positionFactor: 0.05 , ) ,
if ( oldTl ! = null ) GaugeAnnotation ( widget: Text ( fDiff . format ( tl . nerdStats ! . vsapm - oldTl ! . nerdStats ! . vsapm ) , style: TextStyle (
color: tl . nerdStats ! . vsapm - oldTl ! . nerdStats ! . vsapm < 0 ?
Colors . red :
Colors . green
) , ) , positionFactor: 0.05 , ) ] ,
2023-06-27 20:55:59 +00:00
) ] , ) ,
) , ] ) ,
) ,
Wrap (
direction: Axis . horizontal ,
alignment: WrapAlignment . center ,
spacing: 25 ,
crossAxisAlignment: WrapCrossAlignment . start ,
clipBehavior: Clip . hardEdge ,
children: [
StatCellNum ( playerStat: tl . nerdStats ! . dss , isScreenBig: bigScreen , fractionDigits: 3 , playerStatLabel: " Downstack \n Per Second " ,
alertWidgets: [ const Text ( " Downstack per Second measures how many garbage lines you clear in a second. " ) ,
const Text ( " Formula: (VS / 100) - (APM / 60) " ) ,
2023-06-28 16:50:40 +00:00
Text ( " Raw value: ${ tl . nerdStats ! . dss } " ) , ] ,
higherIsBetter: true ,
oldPlayerStat: oldTl ? . nerdStats ? . dss , ) ,
2023-06-27 20:55:59 +00:00
StatCellNum ( playerStat: tl . nerdStats ! . dsp , isScreenBig: bigScreen , fractionDigits: 3 , playerStatLabel: " Downstack \n Per Piece " ,
alertWidgets: [ const Text ( " Downstack per Piece measures how many garbage lines you clear per piece. " ) ,
const Text ( " Formula: DS/S / PPS " ) ,
2023-06-28 16:50:40 +00:00
Text ( " Raw value: ${ tl . nerdStats ! . dsp } " ) , ] ,
higherIsBetter: true ,
oldPlayerStat: oldTl ? . nerdStats ? . dsp , ) ,
2023-06-27 20:55:59 +00:00
StatCellNum ( playerStat: tl . nerdStats ! . appdsp , isScreenBig: bigScreen , fractionDigits: 3 , playerStatLabel: " APP + DS/P " ,
alertWidgets: [ const Text ( " Just a sum of Attack per Piece and Downstack per Piece. " ) ,
const Text ( " Formula: APP + DS/P " ) ,
2023-06-28 16:50:40 +00:00
Text ( " Raw value: ${ tl . nerdStats ! . appdsp } " ) , ] ,
higherIsBetter: true ,
oldPlayerStat: oldTl ? . nerdStats ? . appdsp , ) ,
2023-06-27 20:55:59 +00:00
StatCellNum ( playerStat: tl . nerdStats ! . cheese , isScreenBig: bigScreen , fractionDigits: 2 , playerStatLabel: " Cheese \n Index " ,
alertWidgets: [ const Text ( " Cheese Index is an approximation how much clean / cheese garbage player sends. Lower = more clean. Higher = more cheese. \n Invented by kerrmunism " ) ,
const Text ( " Formula: (DS/P * 150) + ((VS/APM - 2) * 50) + (0.6 - APP) * 125 " ) ,
2023-06-28 16:50:40 +00:00
Text ( " Raw value: ${ tl . nerdStats ! . cheese } " ) , ] ,
higherIsBetter: true ,
oldPlayerStat: oldTl ? . nerdStats ? . cheese , ) ,
2023-06-27 20:55:59 +00:00
StatCellNum ( playerStat: tl . nerdStats ! . gbe , isScreenBig: bigScreen , fractionDigits: 3 , playerStatLabel: " Garbage \n Efficiency " ,
alertWidgets: [ const Text ( " Garbage Efficiency measures how well player uses their garbage. Higher = better or they use their garbage more. Lower = they mostly send their garbage back at cheese or rarely clear garbage. \n Invented by Zepheniah and Dragonboy. " ) ,
const Text ( " Formula: ((APP * DS/S) / PPS) * 2 " ) ,
2023-06-28 16:50:40 +00:00
Text ( " Raw value: ${ tl . nerdStats ! . gbe } " ) , ] ,
higherIsBetter: true ,
oldPlayerStat: oldTl ? . nerdStats ? . gbe , ) ,
2023-06-27 20:55:59 +00:00
StatCellNum ( playerStat: tl . nerdStats ! . nyaapp , isScreenBig: bigScreen , fractionDigits: 3 , playerStatLabel: " Weighted \n APP " ,
alertWidgets: [ const Text ( " Essentially, a measure of your ability to send cheese while still maintaining a high APP. \n Invented by Wertj. " ) ,
const Text ( " Formula: APP - 5 * tan(radians((Cheese Index / -30) + 1)) " ) ,
2023-06-28 16:50:40 +00:00
Text ( " Raw value: ${ tl . nerdStats ! . nyaapp } " ) , ] ,
higherIsBetter: true ,
oldPlayerStat: oldTl ? . nerdStats ? . nyaapp , ) ,
2023-06-27 20:55:59 +00:00
StatCellNum ( playerStat: tl . nerdStats ! . area , isScreenBig: bigScreen , fractionDigits: 1 , playerStatLabel: " Area " ,
alertWidgets: [ const Text ( " How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections " ) ,
const Text ( " Formula: APM * 1 + PPS * 45 + VS * 0.444 + APP * 185 + DS/S * 175 + DS/P * 450 + Garbage Effi * 315 " ) ,
2023-06-28 16:50:40 +00:00
Text ( " Raw value: ${ tl . nerdStats ! . area } " ) , ] ,
higherIsBetter: true ,
oldPlayerStat: oldTl ? . nerdStats ? . area , )
2023-06-27 20:55:59 +00:00
] )
2023-06-17 21:50:52 +00:00
] ,
) ,
if ( tl . estTr ! = null )
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 (
f2 . format ( tl . estTr ! . esttr ) ,
style: const TextStyle ( fontSize: 24 ) ,
) ,
] ,
) ,
if ( tl . rating > = 0 )
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
const Text (
" Accuracy: " ,
style: TextStyle ( fontSize: 24 ) ,
) ,
Text (
fDiff . format ( tl . esttracc ! ) ,
style: const TextStyle ( fontSize: 24 ) ,
) ,
] ,
) ,
] ,
) ,
) ,
) ,
if ( tl . nerdStats ! = null )
Wrap (
direction: Axis . horizontal ,
alignment: WrapAlignment . spaceAround ,
spacing: 25 ,
crossAxisAlignment: WrapCrossAlignment . start ,
clipBehavior: Clip . hardEdge ,
children: [
Padding (
padding: const EdgeInsets . fromLTRB ( 20 , 0 , 20 , 48 ) ,
child: SizedBox (
height: 300 ,
width: 300 ,
child: RadarChart (
RadarChartData (
radarShape: RadarShape . polygon ,
tickCount: 4 ,
ticksTextStyle: const TextStyle ( color: Colors . transparent , fontSize: 10 ) ,
radarBorderData: const BorderSide ( color: Colors . transparent , width: 1 ) ,
gridBorderData: const BorderSide ( color: Colors . white24 , width: 1 ) ,
tickBorderData: const BorderSide ( color: Colors . transparent , width: 1 ) ,
getTitle: ( index , angle ) {
switch ( index ) {
case 0 :
return RadarChartTitle (
text: ' APM ' ,
angle: angle ,
) ;
case 1 :
return RadarChartTitle (
text: ' PPS ' ,
angle: angle ,
) ;
case 2 :
return RadarChartTitle ( text: ' VS ' , angle: angle ) ;
case 3 :
return RadarChartTitle ( text: ' APP ' , angle: angle + 180 ) ;
case 4 :
return RadarChartTitle ( text: ' DS/S ' , angle: angle + 180 ) ;
case 5 :
return RadarChartTitle ( text: ' DS/P ' , angle: angle + 180 ) ;
case 6 :
return RadarChartTitle ( text: ' APP+DS/P ' , angle: angle + 180 ) ;
case 7 :
return RadarChartTitle ( text: ' VS/APM ' , angle: angle + 180 ) ;
case 8 :
return RadarChartTitle ( text: ' Cheese ' , angle: angle ) ;
case 9 :
return RadarChartTitle ( text: ' Gb Eff. ' , angle: angle ) ;
default :
return const RadarChartTitle ( text: ' ' ) ;
}
} ,
dataSets: [
RadarDataSet (
dataEntries: [
2023-06-21 19:17:39 +00:00
RadarEntry ( value: tl . apm ! * apmWeight ) ,
RadarEntry ( value: tl . pps ! * ppsWeight ) ,
RadarEntry ( value: tl . vs ! * vsWeight ) ,
RadarEntry ( value: tl . nerdStats ! . app * appWeight ) ,
RadarEntry ( value: tl . nerdStats ! . dss * dssWeight ) ,
RadarEntry ( value: tl . nerdStats ! . dsp * dspWeight ) ,
RadarEntry ( value: tl . nerdStats ! . appdsp * appdspWeight ) ,
2023-06-23 18:38:15 +00:00
RadarEntry ( value: tl . nerdStats ! . vsapm * vsapmWeight ) ,
2023-06-21 19:17:39 +00:00
RadarEntry ( value: tl . nerdStats ! . cheese * cheeseWeight ) ,
RadarEntry ( value: tl . nerdStats ! . gbe * gbeWeight ) ,
2023-06-17 21:50:52 +00:00
] ,
) ,
RadarDataSet (
fillColor: Colors . transparent ,
borderColor: Colors . transparent ,
dataEntries: [
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
] ,
)
] ,
) ,
swapAnimationDuration: const Duration ( milliseconds: 150 ) , // Optional
swapAnimationCurve: Curves . linear , // Optional
) ,
) ,
) ,
Padding (
padding: const EdgeInsets . fromLTRB ( 20 , 0 , 20 , 48 ) ,
child: SizedBox (
height: 300 ,
width: 300 ,
child: RadarChart (
RadarChartData (
radarShape: RadarShape . polygon ,
tickCount: 4 ,
ticksTextStyle: const TextStyle ( color: Colors . transparent , fontSize: 10 ) ,
radarBorderData: const BorderSide ( color: Colors . transparent , width: 1 ) ,
gridBorderData: const BorderSide ( color: Colors . white24 , width: 1 ) ,
tickBorderData: const BorderSide ( color: Colors . transparent , width: 1 ) ,
getTitle: ( index , angle ) {
switch ( index ) {
case 0 :
return RadarChartTitle (
text: ' Opener ' ,
angle: angle ,
) ;
case 1 :
return RadarChartTitle (
text: ' Stride ' ,
angle: angle ,
) ;
case 2 :
return RadarChartTitle ( text: ' Inf Ds ' , angle: angle + 180 ) ;
case 3 :
return RadarChartTitle ( text: ' Plonk ' , angle: angle ) ;
default :
return const RadarChartTitle ( text: ' ' ) ;
}
} ,
dataSets: [
RadarDataSet (
dataEntries: [
RadarEntry ( value: tl . playstyle ! . opener ) ,
RadarEntry ( value: tl . playstyle ! . stride ) ,
RadarEntry ( value: tl . playstyle ! . infds ) ,
RadarEntry ( value: tl . playstyle ! . plonk ) ,
] ,
) ,
RadarDataSet (
fillColor: Colors . transparent ,
borderColor: Colors . transparent ,
dataEntries: [
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
const RadarEntry ( value: 0 ) ,
] ,
) ,
RadarDataSet (
fillColor: Colors . transparent ,
borderColor: Colors . transparent ,
dataEntries: [
const RadarEntry ( value: 1 ) ,
const RadarEntry ( value: 1 ) ,
const RadarEntry ( value: 1 ) ,
const RadarEntry ( value: 1 ) ,
] ,
)
] ,
) ,
swapAnimationDuration: const Duration ( milliseconds: 150 ) , // Optional
swapAnimationCurve: Curves . linear , // Optional
) ,
) ,
) ,
] ,
)
]
: [
2023-06-22 19:02:49 +00:00
const Text ( " That user never played Tetra League " , style: TextStyle ( fontFamily: " Eurostile Round Extended " , fontSize: 28 ) ) ,
2023-06-17 21:50:52 +00:00
] ,
) ;
} ,
) ;
} ) ;
}
}