You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

364 lines
11 KiB

let combined_charts = [];
let player_charts = [];
const x_scale = {
display: true,
type: "timeseries",
time: {
parser: "dd.MM.yy HH:mm",
tooltipFormat: "dd.MM.yy HH:mm",
unit: "day",
unitStepSize: 1,
displayFormats: {
"day": "dd.MM.yy",
}
},
ticks: {
callback: (value, index, ticks) => {
let tickdate = new Date(value);
if (index === 0) return `${tickdate.getDate()}.${month_names[tickdate.getMonth()]}`;
let prev_tickdate = new Date(ticks[index-1].value);
if (prev_tickdate.getDate() === tickdate.getDate()) {
return null;
}
return `${tickdate.getDate()}.${month_names[tickdate.getMonth()]}`;
}
}
}
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 player_rank_values = {};
let player_progress_values = {};
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"];
let all_rank_yDatasets = []; // Datasets, also die einzelnen Linien im Graphen, beinhaltet player_rank_values
let all_progress_yDatasets = []; // Datasets, also die einzelnen Linien im Graphen, beinhaltet player_progress_values
let color_counter = 0;
for (const puuid in player_entries) {
player_rank_values[puuid] = [];
player_progress_values[puuid] = [];
player_entries_byName[`${player_accounts[puuid]["gameName"]}#${player_accounts[puuid]["tagLine"]}`] = [];
let player_start_points = -1;
for (const timestamp in player_entries[puuid]) {
// Für alle Player Entries Punktzahl und Punktedifferenz berechnen
// Bei der Gelegenheit auch Entries in player_entries_byName eintragen
const current_points = rank_to_points(player_entries[puuid][timestamp]["tier"], player_entries[puuid][timestamp]["rank"], player_entries[puuid][timestamp]["points"]);
player_rank_values[puuid].push({x: parseInt(timestamp) * 1000, y: current_points});
player_entries_byName[`${player_accounts[puuid]["gameName"]}#${player_accounts[puuid]["tagLine"]}`][timestamp] = player_entries[puuid][timestamp];
if (player_start_points === -1) {
player_start_points = current_points;
player_progress_values[puuid].push({x: parseInt(timestamp) * 1000, y: 0});
} else {
player_progress_values[puuid].push({x: parseInt(timestamp) * 1000, y: current_points - player_start_points});
}
}
// 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_rank_values[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_progress_values[puuid],
spanGaps: true,
})
color_counter++;
}
// Graphen erstellen
combined_charts.push(new Chart(`progress-chart-combined`, {
type: "line",
data: {
datasets: all_rank_yDatasets,
},
options: {
plugins: {
tooltip: {
callbacks: {
label: function(context) {
return format_rank(player_entries_byName[context.dataset.label][context.parsed.x/1000]["tier"],player_entries_byName[context.dataset.label][context.parsed.x/1000]["rank"],player_entries_byName[context.dataset.label][context.parsed.x/1000]["points"])
},
beforeTitle: function (context) {
return context[0].dataset.label;
},
}
}
},
scales: {
x: x_scale,
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: {
datasets: all_progress_yDatasets,
},
options: {
plugins: {
tooltip: {
callbacks: {
label: function(context) {
return format_rank(player_entries_byName[context.dataset.label][context.parsed.x/1000]["tier"],player_entries_byName[context.dataset.label][context.parsed.x/1000]["rank"],player_entries_byName[context.dataset.label][context.parsed.x/1000]["points"])
},
beforeTitle: function (context) {
return context[0].dataset.label;
},
}
}
},
scales: {
x: x_scale,
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 values = [];
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"]);
values.push({x: parseInt(entriesKey)*1000, y: points});
}
player_charts.push(new Chart(`progress-chart-${puuid}`, {
type: "line",
data: {
datasets: [{
label: `${player_accounts[puuid]["gameName"]}#${player_accounts[puuid]["tagLine"]}`,
fill: false,
borderColor: "rgba(150,150,175)",
backgroundColor: "rgba(150,150,175)",
data: values
}]
},
options: {
plugins: {
legend: {display: false},
tooltip: {
callbacks: {
label: function(context) {
return format_rank(player_entries[puuid][context.parsed.x/1000]["tier"],player_entries[puuid][context.parsed.x/1000]["rank"],player_entries[puuid][context.parsed.x/1000]["points"])
},
beforeTitle: function (context) {
return context[0].dataset.label;
},
}
}
},
scales: {
x: x_scale,
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;
}
const month_names = ["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"];
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));
}