Show similar scores in scores page

This commit is contained in:
nise.moe 2024-02-25 23:49:38 +01:00
parent 37e90e4194
commit c2f20d8636
6 changed files with 98 additions and 2 deletions

View File

@ -84,6 +84,16 @@ data class ReplayDataChart(
val data: List<Double> val data: List<Double>
) )
data class ReplayDataSimilarScore(
val replay_id: Long,
val user_id: Int,
val username: String,
val date: String,
val pp: Double,
val similarity: Double,
val correlation: Double
)
data class ReplayData( data class ReplayData(
val replay_id: Long, val replay_id: Long,
val user_id: Int, val user_id: Int,
@ -136,6 +146,7 @@ data class ReplayData(
val count_50: Int, val count_50: Int,
val count_miss: Int, val count_miss: Int,
val similar_scores: List<ReplayDataSimilarScore>,
val error_distribution: Map<Int, DistributionEntry>, val error_distribution: Map<Int, DistributionEntry>,
val charts: List<ReplayDataChart> val charts: List<ReplayDataChart>
) { ) {

View File

@ -129,7 +129,8 @@ class ScoreService(
error_coefficient_of_variation = result.get(SCORES.ERROR_COEFFICIENT_OF_VARIATION, Double::class.java), error_coefficient_of_variation = result.get(SCORES.ERROR_COEFFICIENT_OF_VARIATION, Double::class.java),
error_kurtosis = result.get(SCORES.ERROR_KURTOSIS, Double::class.java), error_kurtosis = result.get(SCORES.ERROR_KURTOSIS, Double::class.java),
error_skewness = result.get(SCORES.ERROR_SKEWNESS, Double::class.java), error_skewness = result.get(SCORES.ERROR_SKEWNESS, Double::class.java),
charts = charts charts = charts,
similar_scores = this.getSimilarScores(replayId)
) )
this.loadComparableReplayData(replayData) this.loadComparableReplayData(replayData)
return replayData return replayData
@ -328,6 +329,45 @@ class ScoreService(
"$smallerId-$largerId" "$smallerId-$largerId"
}.sortedWith(compareBy({ it.replay_date_2 }, { it.similarity })).reversed() }.sortedWith(compareBy({ it.replay_date_2 }, { it.similarity })).reversed()
fun getSimilarScores(scoreId: Long): List<ReplayDataSimilarScore> {
val similarScores = dslContext.select(SCORES_SIMILARITY.REPLAY_ID_1, SCORES_SIMILARITY.REPLAY_ID_2, SCORES_SIMILARITY.SIMILARITY, SCORES_SIMILARITY.CORRELATION)
.from(SCORES_SIMILARITY)
.where(SCORES_SIMILARITY.REPLAY_ID_1.eq(scoreId).or(SCORES_SIMILARITY.REPLAY_ID_2.eq(scoreId)))
.fetch()
// Collect all score ids (either replay_id_1 or replay_id_2) that aren't scoreId
val otherScoreIds = similarScores.flatMap {
listOf(it.get(SCORES_SIMILARITY.REPLAY_ID_1, Long::class.java), it.get(SCORES_SIMILARITY.REPLAY_ID_2, Long::class.java))
}.filter { it != scoreId }
// Fetch the replay data for the other score ids
val replayData = dslContext.select(
SCORES.REPLAY_ID,
SCORES.USER_ID,
USERS.USERNAME,
SCORES.DATE,
SCORES.PP,
SCORES.BEATMAP_ID
)
.from(SCORES)
.join(USERS).on(SCORES.USER_ID.eq(USERS.USER_ID))
.where(SCORES.REPLAY_ID.`in`(otherScoreIds))
.fetch()
// Map the replay data to ReplayDataSimilarScore
return replayData.map {
ReplayDataSimilarScore(
replay_id = it.get(SCORES.REPLAY_ID, Long::class.java),
user_id = it.get(SCORES.USER_ID, Int::class.java),
username = it.get(USERS.USERNAME, String::class.java),
date = Format.formatLocalDateTime(it.get(SCORES.DATE, LocalDateTime::class.java)),
pp = it.get(SCORES.PP, Double::class.java),
similarity = similarScores.firstOrNull { score -> score.get(SCORES_SIMILARITY.REPLAY_ID_1, Long::class.java) == it.get(SCORES.REPLAY_ID, Long::class.java) || score.get(SCORES_SIMILARITY.REPLAY_ID_2, Long::class.java) == it.get(SCORES.REPLAY_ID, Long::class.java) }?.get(SCORES_SIMILARITY.SIMILARITY, Double::class.java) ?: 0.0,
correlation = similarScores.firstOrNull { score -> score.get(SCORES_SIMILARITY.REPLAY_ID_1, Long::class.java) == it.get(SCORES.REPLAY_ID, Long::class.java) || score.get(SCORES_SIMILARITY.REPLAY_ID_2, Long::class.java) == it.get(SCORES.REPLAY_ID, Long::class.java) }?.get(SCORES_SIMILARITY.CORRELATION, Double::class.java) ?: 0.0
)
}
}
fun loadComparableReplayData(replayData: ReplayData) { fun loadComparableReplayData(replayData: ReplayData) {
// Total samples // Total samples
val totalSamples = dslContext.fetchCount( val totalSamples = dslContext.fetchCount(

View File

@ -1,7 +1,10 @@
FROM nginx:latest FROM openresty/openresty:focal
RUN rm -rf /usr/share/nginx/html/* RUN rm -rf /usr/share/nginx/html/*
RUN /usr/local/openresty/luajit/bin/luarocks install luaxml
RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-http
COPY dist/nise-frontend /usr/share/nginx/html COPY dist/nise-frontend /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d/default.conf

View File

@ -8,6 +8,9 @@ server {
listen 80; listen 80;
resolver local=on ipv6=off;
resolver_timeout 5s;
root /usr/share/nginx/html; root /usr/share/nginx/html;
location ~ /index.html { location ~ /index.html {

View File

@ -3,6 +3,16 @@ export interface ReplayDataChart {
data: number[]; data: number[];
} }
export interface ReplayDataSimilarScore {
replay_id: number;
user_id: number;
date: string;
pp: number;
username: string;
similarity: number;
correlation: number;
}
export interface ReplayData { export interface ReplayData {
replay_id: number; replay_id: number;
user_id: number; user_id: number;
@ -55,6 +65,7 @@ export interface ReplayData {
count_50: number, count_50: number,
count_miss: number; count_miss: number;
similar_scores: ReplayDataSimilarScore[];
error_distribution: ErrorDistribution; error_distribution: ErrorDistribution;
charts: ReplayDataChart[]; charts: ReplayDataChart[];
} }

View File

@ -98,6 +98,34 @@
</div> </div>
</div> </div>
<div class="main term mb-2" *ngIf="this.replayData.similar_scores.length > 0">
<h1># similar replays</h1>
<table>
<thead>
<th class="text-center">Played by</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.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"> <div class="main term mb-2" *ngIf="this.replayData.mean_error">
<h1># nerd stats</h1> <h1># nerd stats</h1>
<table> <table>