Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions ftl/core/statistics.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ statistics-card-ease-title = Card Ease
statistics-card-difficulty-title = Card Difficulty
statistics-card-stability-title = Card Stability
statistics-card-stability-subtitle = The delay at which retrievability falls to 90%.
statistics-average-stability = Average stability
statistics-median-stability = Median stability
statistics-card-retrievability-title = Card Retrievability
statistics-card-ease-subtitle = The lower the ease, the more frequently a card will appear.
statistics-card-difficulty-subtitle2 = The higher the difficulty, the slower stability will increase.
Expand Down Expand Up @@ -261,7 +261,7 @@ statistics-total = Total
statistics-days-studied = Days studied
statistics-average-answer-time-label = Average answer time
statistics-average = Average
statistics-average-interval = Average interval
statistics-median-interval = Median interval
statistics-due-tomorrow = Due tomorrow
# This string, ‘Daily load,’ appears in the ‘Future due’ table and represents a
# forecasted estimate of the number of cards expected to be reviewed daily in
Expand All @@ -287,11 +287,19 @@ statistics-cards-per-day =
[one] { $count } card/day
*[other] { $count } cards/day
}
statistics-average-ease = Average ease
statistics-average-difficulty = Average difficulty
statistics-median-ease = Median ease
statistics-median-difficulty = Median difficulty
statistics-average-retrievability = Average retrievability
statistics-estimated-total-knowledge = Estimated total knowledge
statistics-save-pdf = Save PDF
statistics-saved = Saved.
statistics-stats = stats
statistics-title = Statistics

## These strings are no longer used - you do not need to translate them if they
## are not already translated.

statistics-average-stability = Average stability
statistics-average-interval = Average interval
statistics-average-ease = Average ease
statistics-average-difficulty = Average difficulty
33 changes: 21 additions & 12 deletions rslib/src/stats/graphs/eases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,46 @@ 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 ease_values = Vec::new();
let mut difficulty = Eases::default();
let mut card_with_difficulty_count: usize = 0;
let mut difficulty_values = Vec::new();
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;
difficulty_values.push(state.difficulty());
} 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;
ease_values.push(card.ease_factor as f32);
}
}
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.average = median(&mut ease_values) / 10.0;
difficulty.average = median(&mut difficulty_values) * 100.0;

(eases, difficulty)
}
}

/// Helper function to calculate the median of a vector
fn median(data: &mut [f32]) -> f32 {
if data.is_empty() {
return 0.0;
}
data.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mid = data.len() / 2;
if data.len() % 2 == 0 {
(data[mid - 1] + data[mid]) / 2.0
} else {
data[mid]
}
}

/// Bins the number into a bin of 0, 5, .. 95
pub(super) fn percent_to_bin(x: f32) -> u32 {
if x == 100.0 {
Expand Down
2 changes: 1 addition & 1 deletion ts/routes/graphs/difficulty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export function prepareData(
const xTickFormat = (num: number): string => localizedNumber(num, 0) + "%";
const tableData = [
{
label: tr.statisticsAverageDifficulty(),
label: tr.statisticsMedianDifficulty(),
value: xTickFormat(data.average),
},
];
Expand Down
4 changes: 2 additions & 2 deletions ts/routes/graphs/ease.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ export function prepareData(
const xTickFormat = (num: number): string => localizedNumber(num, 0) + "%";
const tableData = [
{
label: tr.statisticsAverageEase(),
value: xTickFormat(sum(Array.from(allEases.entries()).map(([k, v]) => (k + 2.5) * v)) / total),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was most likely omitted by mistake in #3406 by @abdnh.

label: tr.statisticsMedianEase(),
value: xTickFormat(data.average),
},
];

Expand Down
10 changes: 5 additions & 5 deletions ts/routes/graphs/intervals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as tr from "@generated/ftl";
import { localizedNumber } from "@tslib/i18n";
import { timeSpan } from "@tslib/time";
import type { Bin } from "d3";
import { bin, extent, interpolateBlues, mean, quantile, scaleLinear, scaleSequential, sum } from "d3";
import { bin, extent, interpolateBlues, quantile, scaleLinear, scaleSequential, sum } from "d3";

import type { SearchDispatch, TableDatum } from "./graph-helpers";
import { numericMap } from "./graph-helpers";
Expand Down Expand Up @@ -168,12 +168,12 @@ export function prepareIntervalData(
dispatch("search", { query });
}

const meanInterval = Math.round(mean(allIntervals) ?? 0);
const meanIntervalString = timeSpan(meanInterval * 86400, false);
const medianInterval = Math.round(quantile(allIntervals, 0.5) ?? 0);
const medianIntervalString = timeSpan(medianInterval * 86400, false);
const tableData = [
{
label: fsrs ? tr.statisticsAverageStability() : tr.statisticsAverageInterval(),
value: meanIntervalString,
label: fsrs ? tr.statisticsMedianStability() : tr.statisticsMedianInterval(),
value: medianIntervalString,
},
];

Expand Down