let combined _charts = [ ] ;
let player _charts = [ ] ;
window . onload = create _charts ;
async function create _charts ( ) {
combined _charts . forEach ( chart => chart . destroy ( ) ) ;
combined _charts = [ ] ;
player _charts . forEach ( chart => chart . destroy ( ) ) ;
player _charts = [ ] ;
let all _dates = [ ] ; // Alle Daten für die für min. einen Spieler ein Rang gespeichert ist
let all _rank _yDatasets = [ ] ; // Datasets, also die einzelnen Linien im Graphen, beinhaltet player_points
let all _progress _yDatasets = [ ] ; // Datasets, also die einzelnen Linien im Graphen, beinhaltet die Differenz der aktuellen player_points und der start player_points
let player _points = { } ; // puuid zeigt auf eine Liste von Punkten, welche die y-Koordinaten im Graphen darstellen
let player _pointprogress = { } ; // puuid zeigt auf eine Liste von Punkten, welche die y-Koordinaten im Graphen darstellen
let player _entries = { } ; // puuid zeigt auf player entries
let player _entries _byName = { } ; // playername zeigt auf entries (damit im kombinierten Graphen die Tooltips korrekt gerendert werden können)
let player _accounts = { } ; // puuid zeigt auf player account
await fetch ( ` get.php ` , {
method : "GET" ,
} )
. then ( res => res . json ( ) )
. then ( result => {
player _entries = result [ "entries" ] ;
player _accounts = result [ "accounts" ] ;
for ( const puuid in player _entries ) {
// Alle Daten für die Spieler Einträge haben sollen in all_dates
for ( const entry _date in player _entries [ puuid ] ) {
all _dates . push ( entry _date )
}
// Hier schonmal puuids/namen auf leere Arrays setzen, damit später einfach .push verwendet werden kann
player _points [ puuid ] = [ ] ;
player _pointprogress [ puuid ] = [ ] ;
player _entries _byName [ ` ${ player _accounts [ puuid ] [ "gameName" ] } # ${ player _accounts [ puuid ] [ "tagLine" ] } ` ] = [ ] ;
}
// Daten sortieren und Duplicates entfernen
all _dates . sort ( ) ;
all _dates = [ ... new Set ( all _dates ) ] ;
let color _counter = 0 ;
for ( const puuid in player _entries ) {
let player _start _points = - 1 ;
for ( const date _string of all _dates ) {
// Für alle Player Entries Punktzahl berechnen und in player_points eintragen
// Bei der Gelegenheit auch Entries in player_entries_byName eintragen
if ( date _string in player _entries [ puuid ] ) {
const current _points = rank _to _points ( player _entries [ puuid ] [ date _string ] [ "tier" ] , player _entries [ puuid ] [ date _string ] [ "rank" ] , player _entries [ puuid ] [ date _string ] [ "points" ] ) ;
player _points [ puuid ] . push ( current _points ) ;
player _entries _byName [ ` ${ player _accounts [ puuid ] [ "gameName" ] } # ${ player _accounts [ puuid ] [ "tagLine" ] } ` ] [ date _string ] = player _entries [ puuid ] [ date _string ] ;
if ( player _start _points === - 1 ) {
player _start _points = current _points ;
player _pointprogress [ puuid ] . push ( 0 ) ;
} else {
player _pointprogress [ puuid ] . push ( current _points - player _start _points ) ;
}
} else {
player _points [ puuid ] . push ( null ) ;
player _pointprogress [ puuid ] . push ( null ) ;
}
}
// Linie für den Spieler zu Datasets des Graphen hinzufügen
all _rank _yDatasets . push ( {
label : ` ${ player _accounts [ puuid ] [ "gameName" ] } # ${ player _accounts [ puuid ] [ "tagLine" ] } ` ,
fill : false ,
borderColor : getColor ( color _counter ) ,
backgroundColor : getColor ( color _counter ) ,
data : player _points [ puuid ] ,
spanGaps : true ,
} )
all _progress _yDatasets . push ( {
label : ` ${ player _accounts [ puuid ] [ "gameName" ] } # ${ player _accounts [ puuid ] [ "tagLine" ] } ` ,
fill : false ,
borderColor : getColor ( color _counter ) ,
backgroundColor : getColor ( color _counter ) ,
data : player _pointprogress [ puuid ] ,
spanGaps : true ,
} )
color _counter ++ ;
}
// Graphen erstellen
combined _charts . push ( new Chart ( ` progress-chart-combined ` , {
type : "line" ,
data : {
labels : all _dates ,
datasets : all _rank _yDatasets ,
} ,
options : {
plugins : {
tooltip : {
callbacks : {
label : function ( context ) {
return format _rank ( player _entries _byName [ context . dataset . label ] [ context . label ] [ "tier" ] , player _entries _byName [ context . dataset . label ] [ context . label ] [ "rank" ] , player _entries _byName [ context . dataset . label ] [ context . label ] [ "points" ] )
} ,
beforeTitle : function ( context ) {
return context [ 0 ] . dataset . label ;
} ,
}
}
} ,
scales : {
y : {
display : true ,
stepSize : 100 ,
ticks : {
callback : ( value ) => {
return points _to _rankstring ( value , false ) ;
}
}
} ,
} ,
responsive : true ,
maintainAspectRatio : false ,
}
} ) ) ;
combined _charts . push ( new Chart ( ` progress-chart-combined-progress ` , {
type : "line" ,
data : {
labels : all _dates ,
datasets : all _progress _yDatasets ,
} ,
options : {
plugins : {
tooltip : {
callbacks : {
label : function ( context ) {
return format _rank ( player _entries _byName [ context . dataset . label ] [ context . label ] [ "tier" ] , player _entries _byName [ context . dataset . label ] [ context . label ] [ "rank" ] , player _entries _byName [ context . dataset . label ] [ context . label ] [ "points" ] )
} ,
beforeTitle : function ( context ) {
return context [ 0 ] . dataset . label ;
} ,
}
}
} ,
scales : {
y : {
display : true ,
} ,
} ,
responsive : true ,
maintainAspectRatio : false ,
}
} ) ) ;
} )
. catch ( e => console . error ( e ) )
const charts = document . getElementsByClassName ( "progress-chart" ) ;
for ( const chart of charts ) {
let puuid = chart . id . split ( "-" ) ;
puuid . splice ( 0 , 2 ) ;
puuid = puuid . join ( "-" ) ;
let xValues = [ ] ;
let yValues = [ ] ;
for ( const entriesKey in player _entries [ puuid ] ) {
let points = rank _to _points ( player _entries [ puuid ] [ entriesKey ] [ "tier" ] , player _entries [ puuid ] [ entriesKey ] [ "rank" ] , player _entries [ puuid ] [ entriesKey ] [ "points" ] ) ;
xValues . push ( entriesKey ) ;
yValues . push ( points ) ;
}
player _charts . push ( new Chart ( ` progress-chart- ${ puuid } ` , {
type : "line" ,
data : {
labels : xValues ,
datasets : [ {
label : ` ${ player _accounts [ puuid ] [ "gameName" ] } # ${ player _accounts [ puuid ] [ "tagLine" ] } ` ,
fill : false ,
borderColor : "rgba(150,150,175)" ,
backgroundColor : "rgba(150,150,175)" ,
data : yValues
} ]
} ,
options : {
plugins : {
legend : { display : false } ,
tooltip : {
callbacks : {
label : function ( context ) {
return format _rank ( player _entries [ puuid ] [ context . label ] [ "tier" ] , player _entries [ puuid ] [ context . label ] [ "rank" ] , player _entries [ puuid ] [ context . label ] [ "points" ] )
} ,
beforeTitle : function ( context ) {
return context [ 0 ] . dataset . label ;
} ,
}
}
} ,
scales : {
y : {
display : true ,
stepSize : 100 ,
ticks : {
callback : ( value ) => {
return points _to _rankstring ( value , false ) ;
}
}
} ,
} ,
responsive : true ,
maintainAspectRatio : false ,
}
} ) ) ;
}
}
function rank _to _points ( tier , rank , lp ) {
const apex _tiers = ( tier === "MASTER" || tier === "GRANDMASTER" || tier === "CHALLENGER" ) ;
const tiers = {
"DIAMOND" : 2400 ,
"EMERALD" : 2000 ,
"PLATINUM" : 1600 ,
"GOLD" : 1200 ,
"SILVER" : 800 ,
"BRONZE" : 400 ,
"IRON" : 0 ,
} ;
const ranks = {
"I" : 300 ,
"II" : 200 ,
"III" : 100 ,
"IV" : 0 ,
} ;
if ( apex _tiers ) {
return 2800 + lp ;
} else {
return tiers [ tier ] + ranks [ rank ] + lp ;
}
}
function points _to _rankstring ( points , include _LP = true ) {
const apex _tiers = ( points >= 2800 ) ;
let lp = ( apex _tiers ) ? points - 2800 : points % 100
let rank = ( points - lp ) % 400 ;
let tier = ( points - lp - rank ) ;
const tiers = {
2400 : "Diamond" ,
2000 : "Emerald" ,
1600 : "Platinum" ,
1200 : "Gold" ,
800 : "Silver" ,
400 : "Bronze" ,
0 : "Iron" ,
} ;
const ranks = {
300 : "I" ,
200 : "II" ,
100 : "III" ,
0 : "IV" ,
} ;
let rank _string = ( apex _tiers ) ? "Master" : tiers [ tier ] ;
if ( ! apex _tiers ) rank _string += ` ${ ranks [ rank ] } ` ;
if ( include _LP || apex _tiers ) rank _string += ` ${ lp } LP ` ;
return rank _string ;
}
function format _rank ( tier , rank , lp ) {
tier = tier . charAt ( 0 ) . toUpperCase ( ) + tier . slice ( 1 ) . toLowerCase ( ) ;
const apex _tiers = ( tier === "Master" || tier === "Grandmaster" || tier === "Challenger" ) ;
let rank _string = tier ;
if ( ! apex _tiers ) rank _string += ` ${ rank } ` ;
rank _string += ` ${ lp } LP ` ;
return rank _string ;
}
function getColor ( num ) {
const colors = [ "#33b1ff" , "#d2a106" , "#007d79" , "#8a3ffc" , "#ff7eb6" , "#ba4e00" , "#fa4d56" , "#fff1f1" , "#6fdc8c" , "#4589ff" , "#d12771" , "#08bdba" , "#bae6ff" , "#d4bbff" ] ;
return colors [ num % 9 ] ;
}
function toggle _combined _chart ( ) {
const comb _charts = this . parentNode . parentNode . querySelectorAll ( ` .leaderboard>.graph-wrapper ` ) ;
const chart = this . parentNode . parentNode . querySelector ( ` .graph-wrapper. ${ this . id } ` ) ;
if ( chart . classList . contains ( "closed" ) ) {
comb _charts . forEach ( element => element . classList . add ( "closed" ) ) ;
chart . classList . remove ( "closed" ) ;
} else {
chart . classList . add ( "closed" ) ;
}
}
function toggle _leaderboard _chart ( ) {
if ( this . classList . contains ( "closed" ) ) {
this . classList . remove ( "closed" ) ;
} else {
this . classList . add ( "closed" ) ;
}
}
document . querySelectorAll ( "button.open-general-graph" ) . forEach ( element => element . addEventListener ( "click" , toggle _combined _chart ) ) ;
document . querySelectorAll ( "button.leaderboard-element" ) . forEach ( element => element . addEventListener ( "click" , toggle _leaderboard _chart ) ) ;
async function update _leaderboard _entries ( ) {
this . disabled = true ;
this . classList . add ( "button-updating" )
let eventSource = new EventSource ( "./update.php" ) ;
eventSource . addEventListener ( "progress" , e => {
this . style . setProperty ( "--button-loading-bar-width" , ` ${ e . data * 100 } % ` ) ;
} )
eventSource . addEventListener ( "forbidden" , e => {
const currenttime = new Date ( ) ;
const updatetime = new Date ( e . data ) ;
let timediff = new Date ( currenttime - updatetime ) ;
let resttime = new Date ( 600000 - ( currenttime - updatetime ) ) ;
window . alert ( ` Das letzte Update wurde vor ${ format _time _minsec ( timediff ) } durchgeführt. Versuche es in ${ format _time _minsec ( resttime ) } noch einmal ` ) ;
reset _button ( this ) ;
eventSource . close ( ) ;
} )
eventSource . onerror = e => {
window . alert ( ` Beim Update ist ein Fehler aufgetreten. Versuche es später noch einmal ` )
reset _button ( this ) ;
eventSource . close ( ) ;
}
eventSource . addEventListener ( "done" , e => {
reset _button ( this ) ;
eventSource . close ( ) ;
update _leaderboard _elements ( ) ;
} )
function reset _button ( button ) {
button . disabled = false ;
button . style . setProperty ( "--button-loading-bar-width" , ` 0 ` ) ;
button . classList . remove ( "button-updating" ) ;
}
}
document . querySelector ( "button.update-leaderboard" ) . addEventListener ( "click" , update _leaderboard _entries ) ;
function format _time _minsec ( date ) {
let format , trenner = "" , min = "" , nullausgleich = "" ;
if ( date . getMinutes ( ) === 0 ) {
format = " Sekunden" ;
} else {
min = date . getMinutes ( ) ;
format = " Minuten" ;
trenner = ":" ;
if ( date . getSeconds ( ) < 10 ) {
nullausgleich = "0" ;
}
}
return min + trenner + nullausgleich + date . getSeconds ( ) + format ;
}
async function update _leaderboard _elements ( ) {
fetch ( ` ./leaderboard_list.php ` , {
method : "GET" ,
} )
. then ( res => res . text ( ) )
. then ( leaderboard _list => {
// replace updated Leaderboard
document . querySelector ( ".leaderboard-list" ) . outerHTML = leaderboard _list ;
// reapply EventListeners
document . querySelectorAll ( "button.leaderboard-element" ) . forEach ( element => element . addEventListener ( "click" , toggle _leaderboard _chart ) ) ;
// recreate charts
create _charts ( ) ;
} )
. catch ( e => console . error ( e ) ) ;
}