diff --git a/assets/html/player/player.html b/assets/html/player/player.html index a37b2a6..3de427b 100644 --- a/assets/html/player/player.html +++ b/assets/html/player/player.html @@ -364,6 +364,7 @@

Statistics

+ @@ -545,6 +546,79 @@

Statistics

} }); + new Chart("games_played_per_role", { + type: "bar", + data: { + labels: {{ role_names }}, + datasets: [ + { + label: "Ranked Games", + data: {{ per_role_game_count_ranked }}, + backgroundColor: [ + "rgb(50, 116, 161)", + "rgb(225, 129, 44)", + "rgb(58, 146, 58)", + "rgb(192, 61, 62)", + "rgb(147, 114, 178)" + ] + }, + { + label: "Unranked Games", + data: {{ per_role_game_count_unranked }}, + backgroundColor: [ + "rgb(50, 166, 161)", + "rgb(225, 179, 44)", + "rgb(58, 196, 58)", + "rgb(192, 121, 62)", + "rgb(147, 174, 178)" + ] + } + ] + }, + options: { + responsive: true, + scales: { + yAxes: [{ + ticks: { + min: 0, + }, + stacked: true, + }], + xAxes: [{ + gridLines: { + display: false, + }, + stacked: true + }], + }, + tooltips: { + callbacks: { + label: function(tooltipItem, data) { + const index = tooltipItem["index"]; + const datasetIndex = tooltipItem["datasetIndex"]; + const label = data.datasets[datasetIndex].label; + const game_count = data.datasets[datasetIndex].data[index]; + + const all_games = data.datasets[0].data[index] + data.datasets[1].data[index]; + + return `${label}: ${game_count} / ${all_games}`; + } + } + }, + plugins: { + legend: { + labels: { + color: "rgb(255, 255, 255)" + } + }, + title: { + display: true, + text: "Number of games played per role" + } + } + } + }); + // median score vs world radar chart new Chart("avg_role_score_radar", { diff --git a/handlers/player/player.py b/handlers/player/player.py index c93ca68..235c7bd 100644 --- a/handlers/player/player.py +++ b/handlers/player/player.py @@ -18,6 +18,13 @@ from utils import render_cached_template, get_post _GAMES_PER_PAGE = 5 +_ROLES = [ + "Commander", + "Heavy", + "Scout", + "Ammo", + "Medic", +] sql = app.ctx.sql @@ -48,23 +55,14 @@ def _role_label(role: str, games: Optional[int]) -> str: # Returns a list of all roles that the player played at least once. If games_per_role is provided, also includes the # number of games played as part of the label. -async def get_role_labels_from_medians(median_role_score, games_per_role: Optional[list[int]] = None) -> list: +def get_role_labels_from_medians(median_role_score: list[int], games_per_role: Optional[list[int]] = None) -> list: labels = [] for i, role_score in enumerate(median_role_score): if role_score == 0: continue else: games = games_per_role[i] if games_per_role else None - if i == 0: - labels.append(_role_label("Commander", games)) - elif i == 1: - labels.append(_role_label("Heavy", games)) - elif i == 2: - labels.append(_role_label("Scout", games)) - elif i == 3: - labels.append(_role_label("Ammo", games)) - elif i == 4: - labels.append(_role_label("Medic", games)) + labels.append(_role_label(_ROLES[i], games)) return labels @@ -107,7 +105,9 @@ async def player_get(request: Request, id: Union[int, str]) -> str: "-start_time").limit(5).offset(_GAMES_PER_PAGE * lbpage) median_role_score = await get_median_role_score(player) - per_role_game_count = await get_per_role_game_count(player) + per_role_game_count_ranked = await get_per_role_game_count(player, ranked_only=True) + per_role_game_count_all = await get_per_role_game_count(player, ranked_only=False) + per_role_game_count_unranked = [all_games_played - per_role_game_count_ranked[i] for i, all_games_played in enumerate(per_role_game_count_all)] logger.debug("Loading team rate pies") @@ -200,9 +200,14 @@ async def player_get(request: Request, id: Union[int, str]) -> str: # role score plot (sm5) role_plot_data_player=[x for x in median_role_score if x != 0], role_plot_data_world=await Player.get_median_role_score_world(median_role_score), - role_plot_labels=await get_role_labels_from_medians(median_role_score), - role_plot_labels_with_game_count=await get_role_labels_from_medians(median_role_score, per_role_game_count), - role_plot_game_count=get_games_per_role_filtered(per_role_game_count), + role_plot_labels=get_role_labels_from_medians(median_role_score), + role_plot_labels_with_game_count=get_role_labels_from_medians(median_role_score, per_role_game_count_ranked), + role_plot_game_count=get_games_per_role_filtered(per_role_game_count_ranked), + # Games played per role + per_role_game_count_ranked=per_role_game_count_ranked, + per_role_game_count_all=per_role_game_count_all, + per_role_game_count_unranked=per_role_game_count_unranked, + role_names=_ROLES, # total number of roles that aren't 0 role_plot_total_roles=len([x for x in median_role_score if x != 0]), # stat chart diff --git a/helpers/userhelper.py b/helpers/userhelper.py index 7f101c2..a84923c 100644 --- a/helpers/userhelper.py +++ b/helpers/userhelper.py @@ -40,7 +40,7 @@ async def get_median_role_score(player: Optional[Player] = None) -> List[int]: return data -async def get_per_role_game_count(player: Player) -> List[int]: +async def get_per_role_game_count(player: Player, ranked_only: bool) -> List[int]: """ Returns the number of times a player played each role. """ @@ -48,8 +48,14 @@ async def get_per_role_game_count(player: Player) -> List[int]: for role in range(1, 6): try: - game_count = await EntityEnds.filter(entity__entity_id=player.entity_id, entity__role=IntRole(role), - entity__sm5games__ranked=True).count() + kwargs = {"entity__entity_id": player.entity_id, "entity__role": IntRole(role)} + + if ranked_only: + kwargs["entity__sm5games__ranked"]=True + else: + kwargs["sm5games__mission_name__icontains"] = "space marines" + + game_count = await EntityEnds.filter(**kwargs).count() except Exception: game_count = 0 data.append(game_count)