您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
(WIP) Generates a chart with the friendly league ranking and changes by round.
// ==UserScript== // @name TM Friendly League Chart by rounds // @name:pt TM Gráfico da liga amistosa por rodadas. // @version 0.1 - 13/01/2024 // @description (WIP) Generates a chart with the friendly league ranking and changes by round. // @description:pt (WIP) Gera um gráfico com a classificação da liga amistosa e alterações por rodada. // @author Irreal Madrid FC. Club ID: 4402745 // @namespace https://github.com/mayc0njr/trophyManager/spoilers/ // @include https://trophymanager.com/friendly-league/* // @license MIT // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js // ==/UserScript== (function () { const LABEL_TEXT = 'round'; const BACKGROUND_COLOR = '#ffffff'; //=================================================================== // Functional variables, used to fetch and process match data. const LEAGUE = 2; const FIXTURES = '/ajax/fixtures.ajax.php'; const TIME_REGEX = /\d{2}:\d{2}/; let now = new Date(); const TODAY = new Date(); TODAY.setUTCHours(0,0,0,0); const TEAMS_SELECTOR = '#league_table tbody td a.normal'; let endOffsetHours = 2; const CHART_HEIGHT = '600px'; const CHART_WIDTH = '530px'; function compareTeams(team1, team2) { if(team1.points != team2.points) return team1.points - team2.points; let team1Goals = team1.goalsFor - team1.goalsAgainst; let team2Goals = team2.goalsFor - team2.goalsAgainst; let goalsDifference = team1Goals - team2Goals; if(goalsDifference != 0) return goalsDifference; return team1.goalsFor - team2.goalsFor; } function getRandomColor() { return Math.floor(Math.random()*16777215).toString(16); } function generateChartHistory() { let url = $('.content_menu .calendar').attr('href').split(`/`).filter(function (el) { return el.length > 0 }); $.post(FIXTURES,{ 'type': 'friendly-league', 'var1': url[LEAGUE], 'var2': '', 'var3': '' },function(data){ if(data != null) { let historic = organizeHistoric(data); generateChart(historic); } },'json'); } function generateDataset(team) { let label = team[0].name; let positions = team.map(round => round.position); let color = getRandomColor(); return {label: label, data: positions, fill: false, borderColor: `#${color}`, tension: 0.1, backgroundColor: `#${color}`}; } function getNumberOfMatches(numberOfTeams) { return (numberOfTeams-1)*2; } function generateChart(historic) { console.log("generate chart"); let canvas = document.createElement('canvas'); $(canvas).css('backgroundColor', BACKGROUND_COLOR); $('#league_table').parent().parent().append(canvas); console.log("$('#league_table').parent().parent()"); console.log($('#league_table').parent().parent()); console.log("$('#league_table')"); console.log($('#league_table')); canvas.id = 'historyChart'; let important = ' !important'; canvas.height = CHART_HEIGHT + important; canvas.width = CHART_WIDTH + important; const ctx = canvas.getContext("2d"); let datasets=[]; let labels = []; for(let i = 1; i <= historic[0].length ; i++) { labels.push(`${LABEL_TEXT} ${i}`); } historic.forEach(team => { datasets.push(generateDataset(team)); }); console.log(labels); console.log(datasets); const numberOfTeams = historic.length; const numberOfMatches = getNumberOfMatches(numberOfTeams); const historicChart = new Chart(ctx, { type: 'line', data: { labels: labels, datasets: datasets }, options: { legend: { position: 'bottom' }, scales: { xAxis: [ { ticks: { min: 1, max: numberOfMatches, }, }], x: { ticks: { stepSize: 1, min: 1, max: numberOfMatches } }, yAxis: [ { ticks: { min: 1, max: numberOfTeams, maxTicksLimit: numberOfTeams, }, }, ], y: { beginAtZero: false, ticks: { stepSize: 1, min: 1, max: numberOfTeams } } } } }); } function filterFixtures(data) { let months = []; let matches = []; for (const key in data) { if (data.hasOwnProperty(key)) { months.push(data[key]); } } for (let index = 0; index < months.length; index++) { const thisMonth = months[index]; matches = matches.concat(thisMonth.matches.filter(function testUnPlayed(match) { return match.result != null; })); } matches.sort((m1, m2) => m1.date.localeCompare(m2.date)) return matches; } function getTeamResults(matches, team) { teamMatches = matches.filter(match => match.hometeam_name === team || match.awayteam_name === team); let results = []; let lastResult = { played: 0, name: team, points: 0, wins: 0, draws: 0, loses: 0, goalsFor: 0, goalsAgainst: 0 }; for(let index = 0; index < teamMatches.length; index++) { let thisResult = {}; const match = teamMatches[index]; let score = match.result.split('-'); score[0] = parseInt(score[0]); score[1] = parseInt(score[1]); let teamScore; let enemyScore; if(match.hometeam_name === team) { teamScore = 0; enemyScore = 1; thisResult.teamId = match.hometeam; } else if(match.awayteam_name === team) { teamScore = 1; enemyScore = 0; thisResult.teamId = match.awayteam; } else { break; } let finished = alreadyFinished(match.date); if(!finished) break; thisResult.wins = lastResult.wins; thisResult.draws = lastResult.draws; thisResult.points = lastResult.points; thisResult.loses = lastResult.loses; thisResult.name = lastResult.name; if(score[teamScore] > score[enemyScore]) { thisResult.points = lastResult.points + 3; thisResult.goalsFor = lastResult.goalsFor + score[teamScore]; thisResult.goalsAgainst = lastResult.goalsAgainst + score[enemyScore]; thisResult.wins = lastResult.wins + 1; } else if(score[teamScore] < score[enemyScore]) { thisResult.goalsFor = lastResult.goalsFor + score[teamScore]; thisResult.goalsAgainst = lastResult.goalsAgainst + score[enemyScore]; thisResult.loses = lastResult.loses + 1; } else { thisResult.points = lastResult.points + 1; thisResult.goalsFor = lastResult.goalsFor + score[teamScore]; thisResult.goalsAgainst = lastResult.goalsAgainst + score[enemyScore]; thisResult.draws = lastResult.draws + 1; } thisResult.played = lastResult.played + 1; thisResult.date = match.date; lastResult = thisResult; results.push(thisResult); } return results; } function organizeHistoric(data) { let fixtures = filterFixtures(data); let teams = $(TEAMS_SELECTOR); let resultsFull = []; teams.each(function(index, team) { if(team.text.length == 0) return; let results = getTeamResults(fixtures, team.textContent); resultsFull.push(results); }); rounds = resultsFull[0].map((_, colIndex) => resultsFull.map(row => row[colIndex])); // transposing array of rounds per team, into array of teams per round. rounds.forEach(round => { givePositionForRound(round); }); return resultsFull; } function isToday(matchDay) { //Checks if the game is today or after let date = new Date(matchDay); return date >= TODAY; } function givePositionForRound(round) { round.sort((team1, team2) => compareTeams(team2, team1)); let lastTeam = null; let position = -1; for (let x=0; x < round.length; x++) { const team = round[x]; if(!lastTeam) team.position = -1; else if(compareTeams(team, lastTeam) == 0) team.position = lastTeam.position; else team.position = position; position--; lastTeam = team; } } function getEndGameTime() { //calculates the endGameTime (gameStart + offsetHours (default 2 hours)) let startGameTime = TIME_REGEX.exec($("#next_round strong").text())[0].trim().split(":"); startGameTime[0] = Number(startGameTime[0]) + endOffsetHours; startGameTime[1] = Number(startGameTime[1]); let endGameTime = new Date(); endGameTime.setHours(startGameTime[0], startGameTime[1], 0); return endGameTime; } function alreadyFinished(matchDay) {//Checks if the game is already ended if(isToday(matchDay)) { let gameEnd = getEndGameTime(); let endTime = new Date(); endTime.setUTCHours(gameEnd.getUTCHours(), gameEnd.getUTCMinutes(), gameEnd.getUTCSeconds()); return now >= endTime; } return true; } generateChartHistory(); })();