Skip to content

Commit

Permalink
show per-user data on game charts
Browse files Browse the repository at this point in the history
  • Loading branch information
mrosack committed Jan 4, 2024
1 parent f1b4a84 commit f208e44
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 83 deletions.
79 changes: 64 additions & 15 deletions src/app/stats/day-of-week-chart/day-of-week-chart.component.ts
@@ -1,5 +1,5 @@
import { Component, Input, OnChanges } from "@angular/core";
import { TurnData } from "pydt-shared";
import { Game, ProfileCacheService, SteamProfile, TurnData } from "pydt-shared";
import { ChartConfiguration } from "chart.js";
import { BrowserDataService } from "../../../app/shared/browser-data.service";

Expand All @@ -8,7 +8,8 @@ import { BrowserDataService } from "../../../app/shared/browser-data.service";
templateUrl: "./day-of-week-chart.component.html",
})
export class DayOfWeekChartComponent implements OnChanges {
@Input() turnData: TurnData;
@Input() turnData: TurnData | Game;
@Input() perUser = false;

public chartData: ChartConfiguration<"bar">["data"];

Expand All @@ -19,36 +20,84 @@ export class DayOfWeekChartComponent implements OnChanges {
plugins: {
title: {
display: true,
text: "Day Turn Played (in UTC), Last 100 Turns",
},
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true,
},
},
};

isBrowser = false;

constructor(browserData: BrowserDataService) {
constructor(
browserData: BrowserDataService,
private profileCache: ProfileCacheService,
) {
this.isBrowser = browserData.isBrowser();
}

ngOnChanges(): void {
findDataSet(datasets: (typeof this.chartData)["datasets"], profile?: SteamProfile) {
if (profile) {
let ds = datasets.find(x => x.label === profile.personaname);

if (!ds) {
ds = {
data: [],
label: profile.personaname,
};

datasets.push(ds);
}

return ds;
}

if (!datasets[0]) {
datasets[0] = {
data: [],
label: "Turns Played",
backgroundColor: "#2C3E50",
borderColor: "#2C3E50",
};
}

return datasets[0];
}

async ngOnChanges() {
const labels = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const data = [];
const datasets: (typeof this.chartData)["datasets"] = [];
const profiles =
"players" in this.turnData ? await this.profileCache.getProfiles(this.turnData.players.map(x => x.steamId)) : {};

// Get UTC hours of day
for (const day of [...Array(7).keys()]) {
data.push([...this.turnData?.dayOfWeekQueue].filter(x => x === day.toString()).length);
if ("players" in this.turnData) {
for (const player of this.turnData.players) {
const dataset = this.findDataSet(datasets, this.perUser ? profiles[player.steamId] : undefined);

dataset.data[day] =
((dataset.data[day] as number) || 0) + [...player?.dayOfWeekQueue].filter(x => x === day.toString()).length;
}
} else {
const dataset = this.findDataSet(datasets);
dataset.data.push([...this.turnData?.dayOfWeekQueue].filter(x => x === day.toString()).length);
}
}

this.chartData = {
labels,
datasets: [
{
data,
label: "Turns Played",
backgroundColor: "#2C3E50",
borderColor: "#2C3E50",
},
],
datasets,
};

this.chartOptions.plugins.title.text = `Day Turn Played (in UTC), Last ${datasets.reduce(
(acc, cur) => acc + (cur.data as number[]).reduce((acc2, cur2) => acc2 + cur2, 0),
0,
)} Turns`;
}
}
16 changes: 12 additions & 4 deletions src/app/stats/display-turn-stats/display-turn-stats.component.html
Expand Up @@ -28,18 +28,26 @@
<div *ngIf="displayCharts" class="col-md-12">
<tabset>
<tab heading="Turn Length">
<pydt-turn-length-chart [turnData]="turnData"></pydt-turn-length-chart>
<pydt-turn-length-chart [turnData]="turnData" [perUser]="perUser"></pydt-turn-length-chart>
</tab>
<tab heading="Turns per Year" *ngIf="showTurnsPerYear">
<pydt-turn-year-chart [turnData]="turnData"></pydt-turn-year-chart>
<pydt-turn-year-chart [turnData]="turnData" [perUser]="perUser"></pydt-turn-year-chart>
</tab>
<tab heading="Time of Day" *ngIf="turnData.hourOfDayQueue && !hideQueueCharts">
<pydt-time-of-day-chart [turnData]="turnData"></pydt-time-of-day-chart>
<pydt-time-of-day-chart [turnData]="turnData" [perUser]="perUser"></pydt-time-of-day-chart>
</tab>
<tab heading="Day of Week" *ngIf="turnData.dayOfWeekQueue && !hideQueueCharts">
<pydt-day-of-week-chart [turnData]="turnData"></pydt-day-of-week-chart>
<pydt-day-of-week-chart [turnData]="turnData" [perUser]="perUser"></pydt-day-of-week-chart>
</tab>
</tabset>
<form *ngIf="showPerUserCheckbox" class="form-inline" style="margin-left: 28px">
<div class="checkbox">
<label>
<input type="checkbox" [(ngModel)]="perUser" [ngModelOptions]="{ standalone: true }" />
Show Per-User Data
</label>
</div>
</form>
</div>
</div>
</div>
Expand Up @@ -33,6 +33,10 @@ export class DisplayTurnStatsComponent {
return Object.keys(this.turnData.yearBuckets || {}).length > 1;
}

get showPerUserCheckbox() {
return "players" in this.turnData;
}

get averageTurnTime() {
return CountdownUtility.countdown(
0,
Expand Down
83 changes: 68 additions & 15 deletions src/app/stats/time-of-day-chart/time-of-day-chart.component.ts
@@ -1,5 +1,5 @@
import { Component, Input, OnChanges } from "@angular/core";
import { HOUR_OF_DAY_KEY, TurnData } from "pydt-shared";
import { Game, HOUR_OF_DAY_KEY, ProfileCacheService, SteamProfile, TurnData } from "pydt-shared";
import { ChartConfiguration } from "chart.js";
import { BrowserDataService } from "../../../app/shared/browser-data.service";

Expand All @@ -8,7 +8,8 @@ import { BrowserDataService } from "../../../app/shared/browser-data.service";
templateUrl: "./time-of-day-chart.component.html",
})
export class TimeOfDayChartComponent implements OnChanges {
@Input() turnData: TurnData;
@Input() turnData: TurnData | Game;
@Input() perUser = false;

public chartData: ChartConfiguration<"bar">["data"];

Expand All @@ -19,38 +20,90 @@ export class TimeOfDayChartComponent implements OnChanges {
plugins: {
title: {
display: true,
text: "Hour Turn Played (in your browser local time), Last 100 Turns",
},
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true,
},
},
};

isBrowser = false;

constructor(browserData: BrowserDataService) {
constructor(
browserData: BrowserDataService,
private profileCache: ProfileCacheService,
) {
this.isBrowser = browserData.isBrowser();
}

ngOnChanges(): void {
findDataSet(datasets: (typeof this.chartData)["datasets"], profile?: SteamProfile) {
if (profile) {
let ds = datasets.find(x => x.label === profile.personaname);

if (!ds) {
ds = {
data: [],
label: profile.personaname,
};

datasets.push(ds);
}

return ds;
}

if (!datasets[0]) {
datasets[0] = {
data: [],
label: "Turns Played",
backgroundColor: "#2C3E50",
borderColor: "#2C3E50",
};
}

return datasets[0];
}

async ngOnChanges() {
const labels = [];
const data = [];
const datasets: (typeof this.chartData)["datasets"] = [];
const profiles =
"players" in this.turnData ? await this.profileCache.getProfiles(this.turnData.players.map(x => x.steamId)) : {};

// Get UTC hours of day
for (const localHour of [...Array(24).keys()]) {
const utcHour = new Date(2000, 1, 1, localHour).getUTCHours();
labels.push(`${localHour.toString().padStart(2, "0")}:00`);
data.push([...this.turnData?.hourOfDayQueue].filter(x => HOUR_OF_DAY_KEY.indexOf(x) === utcHour).length);

if ("players" in this.turnData) {
for (const player of this.turnData.players) {
const dataset = this.findDataSet(datasets, this.perUser ? profiles[player.steamId] : undefined);
dataset.data[localHour] =
((dataset.data[localHour] as number) || 0) +
[...player?.hourOfDayQueue].filter(x => HOUR_OF_DAY_KEY.indexOf(x) === utcHour).length;
}
} else {
const dataset = this.findDataSet(datasets);

dataset.data.push(
[...this.turnData?.hourOfDayQueue].filter(x => HOUR_OF_DAY_KEY.indexOf(x) === utcHour).length,
);
}
}

this.chartData = {
labels,
datasets: [
{
data,
label: "Turns Played",
backgroundColor: "#2C3E50",
borderColor: "#2C3E50",
},
],
datasets,
};

this.chartOptions.plugins.title.text = `Hour Turn Played (in your browser local time), Last ${datasets.reduce(
(acc, cur) => acc + (cur.data as number[]).reduce((acc2, cur2) => acc2 + cur2, 0),
0,
)} Turns`;
}
}

0 comments on commit f208e44

Please sign in to comment.