File tree 7 files changed +159
-4
lines changed
7 files changed +159
-4
lines changed Original file line number Diff line number Diff line change @@ -14,7 +14,7 @@ const domain = new URL(data.url).hostname
14
14
{
15
15
data .metadata ?.external ? (
16
16
<>
17
- { domain } <span class = " *:w-3 *:h-3 *:inline-block ml-1 text-gray-400 " set :html = { externalIcon } />
17
+ { domain } <span class = " ml-1 text-gray-400 *:inline-block *:h-3 *:w-3 " set :html = { externalIcon } />
18
18
</>
19
19
) : (
20
20
" Made by Stormgate World"
Original file line number Diff line number Diff line change
1
+ // @ts -nocheck
2
+
3
+ import { onMount } from "solid-js"
4
+ import {
5
+ Chart ,
6
+ Title ,
7
+ Tooltip ,
8
+ Legend ,
9
+ Colors ,
10
+ type ChartOptions ,
11
+ type ChartData ,
12
+ type ScriptableContext ,
13
+ type ChartArea ,
14
+ } from "chart.js"
15
+ import { DefaultChart } from "solid-chartjs"
16
+
17
+ type GameLengthProps = {
18
+ data : Array [ ]
19
+ }
20
+
21
+ const prettyLabels = {
22
+ "0-120" : "<2m" ,
23
+ "121-240" : "2-4m" ,
24
+ "241-360" : "4-8m" ,
25
+ "361-480" : "8-10m" ,
26
+ "481-600" : "10-12m" ,
27
+ "601-720" : "12-14m" ,
28
+ "721-840" : "14-16m" ,
29
+ "841-960" : "16-18m" ,
30
+ "961-1080" : "18-20m" ,
31
+ "1081-1200" : "20-22m" ,
32
+ "1320+" : "22m+" ,
33
+ }
34
+
35
+ export function GameLengthChart ( props : GameLengthChartProps ) {
36
+ var labels = [ ]
37
+ var wins = [ ]
38
+ var losses = [ ]
39
+ var games = [ ]
40
+ props . data . map ( ( period ) => labels . push ( prettyLabels [ period . match_length_range ] ) )
41
+ props . data . map ( ( period ) => wins . push ( period . wins_count ) )
42
+ props . data . map ( ( period ) => losses . push ( period . losses_count ) )
43
+ props . data . map ( ( period ) => games . push ( period . matches_count ) )
44
+ let canvas : HTMLCanvasElement
45
+ onMount ( ( ) => {
46
+ Chart . register ( Title , Tooltip , Colors )
47
+ } )
48
+
49
+ const min = 0
50
+ const max = Math . max ( ...games )
51
+
52
+ const chartData : ChartData = {
53
+ labels : labels ,
54
+ datasets : [
55
+ {
56
+ label : "Wins" ,
57
+ data : wins ,
58
+ backgroundColor : "green" ,
59
+ } ,
60
+ {
61
+ label : "Losses" ,
62
+ data : losses ,
63
+ backgroundColor : "red" ,
64
+ } ,
65
+ ] ,
66
+ }
67
+
68
+ const chartOptions : ChartOptions = {
69
+ responsive : true ,
70
+ maintainAspectRatio : true ,
71
+ interaction : {
72
+ intersect : false ,
73
+ mode : "index" ,
74
+ } ,
75
+ plugins : {
76
+ title : {
77
+ display : false ,
78
+ } ,
79
+ } ,
80
+ scales : {
81
+ x : {
82
+ stacked : true ,
83
+ } ,
84
+ y : {
85
+ stacked : true ,
86
+ } ,
87
+ } ,
88
+ }
89
+
90
+ return (
91
+ < div class = "relative w-full overflow-hidden" >
92
+ < DefaultChart
93
+ type = "bar"
94
+ data = { chartData }
95
+ options = { chartOptions }
96
+ height = { 100 }
97
+ width = { 300 }
98
+ ref = { ( c ) => ( canvas = c ) }
99
+ />
100
+ </ div >
101
+ )
102
+ }
Original file line number Diff line number Diff line change
1
+ ---
2
+ import { Race , type PlayerMatchupsStats } from " ../../lib/api"
3
+ import Widget from " ../Widget.astro"
4
+ import { classes , styles } from " ../../lib/theme"
5
+ import { Image } from " astro:assets"
6
+ import infernals from " ../../assets/game/factions/infernals-small.png"
7
+ import vanguard from " ../../assets/game/factions/vanguard-small.png"
8
+ import { GameLengthChart } from " ./GameLengthChart"
9
+
10
+ type Theme = keyof typeof styles .badges
11
+ interface Props {
12
+ playerMatchupStats: PlayerMatchupsStats
13
+ }
14
+
15
+ const { playerMatchupStats } = Astro .props
16
+ const matchupsSortedByRace = playerMatchupStats .matchups .sort ((a , b ) => a .race .localeCompare (b .race ))
17
+ ---
18
+
19
+ <Widget title =" Game Length" >
20
+ <table class =" mx-auto w-full table-auto whitespace-nowrap text-left text-sm transition-opacity" >
21
+ <tbody >
22
+ {
23
+ matchupsSortedByRace .map ((matchup ) => (
24
+ <>
25
+ <tr class = " border-b border-gray-700/50 last:border-b-0" >
26
+ <td class = " flex w-full gap-2 truncate p-2 font-semibold text-gray-50" >
27
+ <Image src = { matchup .race === " infernals" ? infernals : vanguard } alt = { matchup .race } class = " size-6" />
28
+ vs
29
+ <Image
30
+ src = { matchup .opponent_race === " infernals" ? infernals : vanguard }
31
+ alt = { matchup .opponent_race }
32
+ class = " size-6"
33
+ />
34
+ </td >
35
+ </tr >
36
+ <tr >
37
+ <td class = " pr-2 text-right text-sm text-gray-100" >
38
+ <GameLengthChart data = { matchup .match_length } client :idle />
39
+ </td >
40
+ </tr >
41
+ </>
42
+ ))
43
+ }
44
+ </tbody >
45
+ </table >
46
+ </Widget >
Original file line number Diff line number Diff line change @@ -15,7 +15,7 @@ const { playerMatchupStats } = Astro.props
15
15
const matchupsSortedByRace = playerMatchupStats .matchups .sort ((a , b ) => a .race .localeCompare (b .race ))
16
16
---
17
17
18
- <Widget title =" Winrates by matchup " >
18
+ <Widget title =" Winrates By Matchup " >
19
19
<table class =" mx-auto w-full table-auto whitespace-nowrap text-left text-sm transition-opacity" >
20
20
<tbody >
21
21
{
Original file line number Diff line number Diff line change @@ -11,7 +11,7 @@ interface Props {
11
11
const { opponents } = Astro .props
12
12
---
13
13
14
- <Widget title =" Top opponents " >
14
+ <Widget title =" Top Opponents " >
15
15
<table class ={ classes (" mx-auto w-full table-auto whitespace-nowrap text-left transition-opacity" )} >
16
16
<tbody >
17
17
{
Original file line number Diff line number Diff line change @@ -104,7 +104,7 @@ export type RedditData = {
104
104
}
105
105
106
106
export type ToolData = {
107
- tags : string [ ] ,
107
+ tags : string [ ]
108
108
external : boolean
109
109
}
110
110
Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ import { PlayersApi } from "../../lib/api"
10
10
import { RankedBadge } from " ../../components/ui/RankedBadge"
11
11
import PlayerActivity from " ../../components/widgets/PlayerActivity.astro"
12
12
import PlayerMatchupStats from " ../../components/widgets/PlayerMatchupStats.astro"
13
+ import PlayerGameLengthStats from " ../../components/widgets/PlayerGameLengthStats.astro"
13
14
import PlayerOpponents from " ../../components/widgets/PlayerOpponents.astro"
14
15
import { styles } from " ../../lib/theme"
15
16
@@ -102,6 +103,9 @@ const highestLeague = player?.leaderboard_entries?.reduce(
102
103
<div class =" hidden lg:block" >
103
104
{ playerMatchupStats .matchups .length > 0 && <PlayerMatchupStats playerMatchupStats = { playerMatchupStats } />}
104
105
</div >
106
+ <div class =" hidden lg:block" >
107
+ { playerMatchupStats .matchups .length > 0 && <PlayerGameLengthStats playerMatchupStats = { playerMatchupStats } />}
108
+ </div >
105
109
<div class =" hidden lg:block" >
106
110
{ playerOpponents .opponents .length > 0 && <PlayerOpponents opponents = { playerOpponents } />}
107
111
</div >
@@ -112,6 +116,9 @@ const highestLeague = player?.leaderboard_entries?.reduce(
112
116
<div class =" lg:hidden" >
113
117
{ playerMatchupStats .matchups .length > 0 && <PlayerMatchupStats playerMatchupStats = { playerMatchupStats } />}
114
118
</div >
119
+ <div class =" lg:hidden" >
120
+ { playerMatchupStats .matchups .length > 0 && <PlayerGameLengthStats playerMatchupStats = { playerMatchupStats } />}
121
+ </div >
115
122
<div class =" lg:hidden" >
116
123
{ playerOpponents .opponents .length > 0 && <PlayerOpponents opponents = { playerOpponents } />}
117
124
</div >
You can’t perform that action at this time.
0 commit comments