208 lines
8.7 KiB
HTML
208 lines
8.7 KiB
HTML
<ng-container *ngIf="this.isLoading">
|
|
<div class="main term">
|
|
<div class="text-center">
|
|
Loading, please wait...
|
|
</div>
|
|
</div>
|
|
</ng-container>
|
|
<ng-container *ngIf="this.error">
|
|
<div class="main term">
|
|
<div class="text-center">
|
|
An error occured. Maybe try again in a bit?
|
|
</div>
|
|
</div>
|
|
</ng-container>
|
|
<ng-container *ngIf="this.replayData && !this.isLoading && !this.error">
|
|
<div class="main term mb-2">
|
|
<div class="fade-stuff">
|
|
<div class="image-container">
|
|
<a href="https://osu.ppy.sh/beatmaps/{{ this.replayData.beatmap_id }}?mode=osu" target="_blank">
|
|
<img ngSrc="https://assets.ppy.sh/beatmaps/{{ this.replayData.beatmap_beatmapset_id }}/covers/cover.jpg" width="260" height="72"
|
|
alt="Beatmap Cover">
|
|
<div class="overlay">
|
|
<h4>
|
|
{{ this.replayData.beatmap_title }} <span class="text-muted">by</span> {{ this.replayData.beatmap_artist }}
|
|
</h4>
|
|
★{{ this.replayData.beatmap_star_rating | number: '1.0-2' }} {{ this.replayData.beatmap_version }}
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<hr class="mt-2 mb-2">
|
|
|
|
<div class="badge-list">
|
|
<span class="badge" *ngFor="let mod of this.replayData.mods">
|
|
{{ mod }}
|
|
</span>
|
|
</div>
|
|
|
|
<h1>
|
|
{{ this.replayData.score | number }} <span style="font-size: 14px">Played at: {{ this.replayData.date }}</span>
|
|
</h1>
|
|
|
|
<div style="display: flex; justify-content: space-between;">
|
|
<div style="flex: 1; padding-right: 10px;">
|
|
<ul style="line-height: 2.2">
|
|
<li>Played by: <a [routerLink]="['/u/' + this.replayData.username]">{{ this.replayData.username }}</a> <a class="btn" style="margin-left: 5px" href="https://osu.ppy.sh/users/{{ this.replayData.user_id }}" target="_blank">osu!web</a></li>
|
|
<li>Link to score: <a class="btn" href="https://osu.ppy.sh/scores/osu/{{ this.replayData.replay_id }}" target="_blank">osu!web</a></li>
|
|
<li><a class="btn" [href]="this.buildCircleguardUrl()">Open in CircleGuard</a></li>
|
|
<li *ngIf="this.replayData.replay_id">
|
|
<a class="btn" [href]="'https://replay.nise.moe/' + this.replayData.replay_id" target="_blank">Open in Replay Viewer</a>
|
|
</li>
|
|
<li>PP: {{ this.replayData.pp }}</li>
|
|
<li>Grade: <app-osu-grade [grade]="this.replayData.rank"></app-osu-grade></li>
|
|
</ul>
|
|
</div>
|
|
<div style="flex: 1; padding-left: 10px;">
|
|
<ul>
|
|
<li>
|
|
Max combo: {{ this.replayData.max_combo }}x
|
|
<span *ngIf="this.replayData.perfect" class="badge badge-green">perfect</span>
|
|
</li>
|
|
<li>Accuracy: {{ calculateAccuracy(this.replayData) | number: '1.2-2' }}%</li>
|
|
<li>300x: {{ this.replayData.count_300 }}</li>
|
|
<li>100x: {{ this.replayData.count_100 }}</li>
|
|
<li>50x: {{ this.replayData.count_50 }}</li>
|
|
<li>Misses: {{ this.replayData.count_miss }}</li>
|
|
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="text-center mb-4 flex-container">
|
|
|
|
<div *ngIf="this.replayData.ur">
|
|
<h2 title="Converted Unstable Rate">cvUR</h2>
|
|
<div>{{ this.replayData.ur | number: '1.2-2' }}</div>
|
|
</div>
|
|
<div *ngIf="this.replayData.adjusted_ur">
|
|
<h2 title="Adjusted cvUR - filters outlier hits">Adj. cvUR</h2>
|
|
<div>{{ this.replayData.adjusted_ur | number: '1.2-2' }}</div>
|
|
</div>
|
|
<div *ngIf="this.replayData.frametime">
|
|
<h2 title="Median time between frames">Frametime</h2>
|
|
<div>{{ this.replayData.frametime | number: '1.0-2' }}ms</div>
|
|
</div>
|
|
<div *ngIf="this.replayData.hits">
|
|
<h2 title="Hits within <1px of the edge">Edge Hits</h2>
|
|
<div>{{ this.replayData.hits }}</div>
|
|
</div>
|
|
<div *ngIf="this.replayData.snaps">
|
|
<h2 title="Unusual snaps in the cursor movement">Snaps</h2>
|
|
<div>{{ this.replayData.snaps }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="alert text-center" *ngIf="this.replayData.average_ur">
|
|
<p class="bold">Heads up!</p>
|
|
<p>The average cvUR for this beatmap is <span class="bold">{{ this.replayData.average_ur | number: '1.0-2' }}</span></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="main term mb-2" *ngIf="this.replayData.similar_scores && this.replayData.similar_scores.length > 0">
|
|
<h1># similar replays</h1>
|
|
<table>
|
|
<thead>
|
|
<th class="text-center">Played by</th>
|
|
<th class="text-center">PP</th>
|
|
<th class="text-center">Date</th>
|
|
<th class="text-center">Similarity</th>
|
|
<th class="text-center">Correlation</th>
|
|
<th class="text-center"></th>
|
|
</thead>
|
|
<tbody>
|
|
<tr *ngFor="let score of this.replayData.similar_scores">
|
|
<td class="text-center">
|
|
<a [routerLink]="['/u/' + score.username]">{{ score.username }}</a>
|
|
</td>
|
|
<td class="text-center">
|
|
{{ score.pp | number: '1.2-2' }}
|
|
</td>
|
|
<td class="text-center">
|
|
{{ score.date }}
|
|
</td>
|
|
<td class="text-center">
|
|
{{ score.similarity | number: '1.2-3' }}
|
|
</td>
|
|
<td class="text-center">
|
|
{{ score.correlation | number: '1.2-4' }}
|
|
</td>
|
|
<td class="text-center">
|
|
<a class="btn" [routerLink]="['/s/' + score.replay_id]">details</a>
|
|
<a class="btn" style="margin-left: 5px" [routerLink]="['/p/' + score.replay_id + '/' + this.replayData.replay_id]">comparison</a>
|
|
</td>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="main term mb-2" *ngIf="this.replayData.mean_error">
|
|
<h1># nerd stats</h1>
|
|
<table>
|
|
<thead>
|
|
<th></th>
|
|
<th>
|
|
this replay
|
|
</th>
|
|
<th *ngIf="this.replayData.comparable_samples">
|
|
<span title="average values for this beatmap">
|
|
avg. (n={{ this.replayData.comparable_samples }})
|
|
</span>
|
|
</th>
|
|
</thead>
|
|
<tr>
|
|
<td>Mean error</td>
|
|
<td class="text-center">{{ this.replayData.mean_error | number: '1.2-2' }}</td>
|
|
<td *ngIf="this.replayData.comparable_samples" class="text-center">{{ this.replayData.comparable_mean_error | number: '1.2-2' }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Error variance</td>
|
|
<td class="text-center">{{ this.replayData.error_variance | number: '1.2-2'}}</td>
|
|
<td *ngIf="this.replayData.comparable_samples" class="text-center">{{ this.replayData.comparable_error_variance | number: '1.2-2' }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Error Std. deviation</td>
|
|
<td class="text-center">{{ this.replayData.error_standard_deviation | number: '1.2-2'}}</td>
|
|
<td *ngIf="this.replayData.comparable_samples" class="text-center">{{ this.replayData.comparable_error_standard_deviation | number: '1.2-2' }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Min/max error</td>
|
|
<td class="text-center">[{{ this.replayData.minimum_error | number: '1.0-0' }}, {{ this.replayData.maximum_error | number: '1.0-0' }}]</td>
|
|
<td *ngIf="this.replayData.comparable_samples" class="text-center">[{{ this.replayData.comparable_minimum_error | number: '1.0-0' }}, {{ this.replayData.comparable_maximum_error | number: '1.0-0' }}]</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Coefficient of variation</td>
|
|
<td class="text-center">{{ this.replayData.error_coefficient_of_variation | number: '1.2-2'}}</td>
|
|
<td *ngIf="this.replayData.comparable_samples" class="text-center">{{ this.replayData.comparable_error_coefficient_of_variation | number: '1.2-2' }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Kurtosis</td>
|
|
<td class="text-center">{{ this.replayData.error_kurtosis | number: '1.2-2'}}</td>
|
|
<td *ngIf="this.replayData.comparable_samples" class="text-center">{{ this.replayData.comparable_error_kurtosis | number: '1.2-2' }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Error skewness</td>
|
|
<td class="text-center">{{ this.replayData.error_skewness | number: '1.2-2'}}</td>
|
|
<td *ngIf="this.replayData.comparable_samples" class="text-center">{{ this.replayData.comparable_error_skewness | number: '1.2-2' }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<ng-container *ngFor="let chart of this.replayData.charts">
|
|
<app-chart [title]="chart.title" [data]="chart.data"></app-chart>
|
|
</ng-container>
|
|
|
|
<div class="main term mb-2" *ngIf="this.replayData.error_distribution && Object.keys(this.replayData.error_distribution).length > 0">
|
|
<h1># hit distribution</h1>
|
|
<canvas baseChart
|
|
[data]="barChartData"
|
|
[options]="barChartOptions"
|
|
[plugins]="barChartPlugins"
|
|
[legend]="barChartLegend"
|
|
[type]="'bar'"
|
|
class="chart">
|
|
</canvas>
|
|
</div>
|
|
</ng-container>
|