From 880c7d366c6dc946471eb9d8ed31cdc23d680970 Mon Sep 17 00:00:00 2001 From: Abdo Date: Tue, 10 Sep 2024 22:18:53 +0300 Subject: [PATCH] Fix graph averages (#3406) * Fix graph averages * Fix formatting --- proto/anki/stats.proto | 2 ++ rslib/src/stats/graphs/eases.rs | 13 +++++++++++++ rslib/src/stats/graphs/retrievability.rs | 8 ++++++++ ts/routes/graphs/difficulty.ts | 5 +++-- ts/routes/graphs/ease.ts | 3 ++- ts/routes/graphs/retrievability.ts | 5 +++-- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/proto/anki/stats.proto b/proto/anki/stats.proto index b5ec04ba8..994e17836 100644 --- a/proto/anki/stats.proto +++ b/proto/anki/stats.proto @@ -74,9 +74,11 @@ message GraphsResponse { } message Eases { map eases = 1; + float average = 2; } message Retrievability { map retrievability = 1; + float average = 2; } message FutureDue { map future_due = 1; diff --git a/rslib/src/stats/graphs/eases.rs b/rslib/src/stats/graphs/eases.rs index f4a5092f5..d70be4e7c 100644 --- a/rslib/src/stats/graphs/eases.rs +++ b/rslib/src/stats/graphs/eases.rs @@ -10,20 +10,33 @@ impl GraphsContext { /// (SM-2, FSRS) pub(super) fn eases(&self) -> (Eases, Eases) { let mut eases = Eases::default(); + let mut card_with_ease_count: usize = 0; let mut difficulty = Eases::default(); + let mut card_with_difficulty_count: usize = 0; for card in &self.cards { if let Some(state) = card.memory_state { *difficulty .eases .entry(percent_to_bin(state.difficulty() * 100.0)) .or_insert_with(Default::default) += 1; + difficulty.average += state.difficulty(); + card_with_difficulty_count += 1; } else if matches!(card.ctype, CardType::Review | CardType::Relearn) { *eases .eases .entry((card.ease_factor / 10) as u32) .or_insert_with(Default::default) += 1; + eases.average += card.ease_factor as f32; + card_with_ease_count += 1; } } + if card_with_ease_count != 0 { + eases.average = eases.average / 10.0 / card_with_ease_count as f32; + } + if card_with_difficulty_count != 0 { + difficulty.average = difficulty.average * 100.0 / card_with_difficulty_count as f32; + } + (eases, difficulty) } } diff --git a/rslib/src/stats/graphs/retrievability.rs b/rslib/src/stats/graphs/retrievability.rs index 7356b95c3..99b16e309 100644 --- a/rslib/src/stats/graphs/retrievability.rs +++ b/rslib/src/stats/graphs/retrievability.rs @@ -12,6 +12,7 @@ impl GraphsContext { /// (SM-2, FSRS) pub(super) fn retrievability(&self) -> Retrievability { let mut retrievability = Retrievability::default(); + let mut card_with_retrievability_count: usize = 0; let timing = SchedTimingToday { days_elapsed: self.days_elapsed, now: Default::default(), @@ -28,8 +29,15 @@ impl GraphsContext { .retrievability .entry(percent_to_bin(r * 100.0)) .or_insert_with(Default::default) += 1; + retrievability.average += r; + card_with_retrievability_count += 1; } } + if card_with_retrievability_count != 0 { + retrievability.average = + retrievability.average * 100.0 / card_with_retrievability_count as f32; + } + retrievability } } diff --git a/ts/routes/graphs/difficulty.ts b/ts/routes/graphs/difficulty.ts index 8b7c777ff..91f8aa634 100644 --- a/ts/routes/graphs/difficulty.ts +++ b/ts/routes/graphs/difficulty.ts @@ -17,10 +17,11 @@ import type { HistogramData } from "./histogram-graph"; export interface GraphData { eases: Map; + average: number; } export function gatherData(data: GraphsResponse): GraphData { - return { eases: numericMap(data.difficulty!.eases) }; + return { eases: numericMap(data.difficulty!.eases), average: data.difficulty!.average }; } function makeQuery(start: number, end: number): string { @@ -101,7 +102,7 @@ export function prepareData( const tableData = [ { label: tr.statisticsAverageDifficulty(), - value: xTickFormat(sum(Array.from(allEases.entries()).map(([k, v]) => (k + 2.5) * v)) / total), + value: xTickFormat(data.average), }, ]; diff --git a/ts/routes/graphs/ease.ts b/ts/routes/graphs/ease.ts index ede27ae4c..c0cf06252 100644 --- a/ts/routes/graphs/ease.ts +++ b/ts/routes/graphs/ease.ts @@ -17,10 +17,11 @@ import type { HistogramData } from "./histogram-graph"; export interface GraphData { eases: Map; + average: number; } export function gatherData(data: GraphsResponse): GraphData { - return { eases: numericMap(data.eases!.eases) }; + return { eases: numericMap(data.eases!.eases), average: data.eases!.average }; } function makeQuery(start: number, end: number): string { diff --git a/ts/routes/graphs/retrievability.ts b/ts/routes/graphs/retrievability.ts index f2b520fa8..22ac67989 100644 --- a/ts/routes/graphs/retrievability.ts +++ b/ts/routes/graphs/retrievability.ts @@ -17,10 +17,11 @@ import type { HistogramData } from "./histogram-graph"; export interface GraphData { retrievability: Map; + average: number; } export function gatherData(data: GraphsResponse): GraphData { - return { retrievability: numericMap(data.retrievability!.retrievability) }; + return { retrievability: numericMap(data.retrievability!.retrievability), average: data.retrievability!.average }; } function makeQuery(start: number, end: number): string { @@ -101,7 +102,7 @@ export function prepareData( const tableData = [ { label: tr.statisticsAverageRetrievability(), - value: xTickFormat(sum(Array.from(allEases.entries()).map(([k, v]) => (k + 2.5) * v)) / total), + value: xTickFormat(data.average), }, ];