Skip to content

Commit

Permalink
feat: add note stats
Browse files Browse the repository at this point in the history
  • Loading branch information
st3v3nmw committed Oct 20, 2024
1 parent 73cc420 commit 7ea2bae
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 10 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"dependencies": {
"chart.js": "^4.4.4",
"clozecraft": "^0.4.0",
"gridjs": "^6.2.0",
"minimatch": "^10.0.1",
"pagerank.js": "^1.0.2",
"short-uuid": "^5.2.0"
Expand Down
15 changes: 15 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/algorithms/base/isrs-algorithm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ReviewResponse } from "src/algorithms/base/repetition-item";
import { OsrNoteGraph } from "src/algorithms/osr/osr-note-graph";
import { DueDateHistogram } from "src/due-date-histogram";
import { Note } from "src/note";
import { INoteEaseList } from "src/note-ease-list";

export enum Algorithm {
SM_2_OSR = "SM-2-OSR",
Expand All @@ -22,6 +23,7 @@ export interface ISrsAlgorithm {
response: ReviewResponse,
dueDateNoteHistogram: DueDateHistogram,
): RepItemScheduleInfo;
noteStats(): INoteEaseList;

cardGetResetSchedule(): RepItemScheduleInfo;
cardGetNewSchedule(
Expand Down
4 changes: 4 additions & 0 deletions src/algorithms/osr/srs-algorithm-osr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,8 @@ export class SrsAlgorithmOsr implements ISrsAlgorithm {
const delayBeforeReview = 0;
return new RepItemScheduleInfoOsr(dueDate, interval, ease, delayBeforeReview);
}

noteStats() {
return this.noteEaseList;
}

Check warning on line 211 in src/algorithms/osr/srs-algorithm-osr.ts

View check run for this annotation

Codecov / codecov/patch

src/algorithms/osr/srs-algorithm-osr.ts#L210-L211

Added lines #L210 - L211 were not covered by tests
}
6 changes: 0 additions & 6 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { CardDueDateHistogram, NoteDueDateHistogram } from "src/due-date-histogr
import { ISRFile, SrTFile } from "src/file";
import { FlashcardReviewMode } from "src/flashcard-review-sequencer";
import { Note } from "src/note";
import { NoteEaseList } from "src/note-ease-list";
import { NoteFileLoader } from "src/note-file-loader";
import { NoteReviewQueue } from "src/note-review-queue";
import { QuestionPostponementList } from "src/question-postponement-list";
Expand All @@ -32,7 +31,6 @@ export class OsrCore {
private dataChangedHandler: () => void;
protected osrNoteGraph: OsrNoteGraph;
private osrNoteLinkInfoFinder: IOsrVaultNoteLinkInfoFinder;
private _easeByPath: NoteEaseList;
private _questionPostponementList: QuestionPostponementList;
private _noteReviewQueue: NoteReviewQueue;

Expand Down Expand Up @@ -67,10 +65,6 @@ export class OsrCore {
return this._dueDateNoteHistogram;
}

get easeByPath(): NoteEaseList {
return this._easeByPath;
}

get cardStats(): Stats {
return this._cardStats;
}
Expand Down
2 changes: 0 additions & 2 deletions src/data-stores/notes/notes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import { RepItemScheduleInfoOsr } from "src/algorithms/osr/rep-item-schedule-inf
import { LEGACY_SCHEDULING_EXTRACTOR, MULTI_SCHEDULING_EXTRACTOR } from "src/constants";
import { IDataStore } from "src/data-stores/base/data-store";
import { RepItemStorageInfo } from "src/data-stores/base/rep-item-storage-info";
import { NoteEaseList } from "src/note-ease-list";
import { Question } from "src/question";
import { SRSettings } from "src/settings";
import { DateUtil, formatDateYYYYMMDD, globalDateProvider } from "src/utils/dates";

export class StoreInNotes implements IDataStore {
private settings: SRSettings;
app: App;
easeByPath: NoteEaseList;

constructor(settings: SRSettings) {
this.settings = settings;
Expand Down
47 changes: 46 additions & 1 deletion src/gui/statistics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ import {
Title,
Tooltip,
} from "chart.js";
import { Grid } from "gridjs";
import path from "path";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import h from "vhtml";

import { SrsAlgorithm } from "src/algorithms/base/srs-algorithm";
import { textInterval } from "src/algorithms/osr/note-scheduling";
import { OsrCore } from "src/core";
import { CardListType } from "src/deck";
import { t } from "src/lang/helpers";
import { Stats } from "src/stats";
import { getKeysPreserveType, getTypedObjectEntries } from "src/utils/types";
import { getKeysPreserveType, getTypedObjectEntries, mapRecord } from "src/utils/types";

Chart.register(
BarElement,
Expand Down Expand Up @@ -99,6 +102,10 @@ export class StatisticsView {
<canvas id="cardTypesChart"></canvas>
<br />
<span id="cardTypesChartSummary"></span>
<br />
<br />
<h1>Notes</h1>
<div id="noteStats"></div>
</div>
);

Expand Down Expand Up @@ -188,6 +195,44 @@ export class StatisticsView {
[cardStats.newCount, cardStats.youngCount, cardStats.matureCount],
t("CARD_TYPES_SUMMARY", { totalCardsCount }),
);

const noteEases = mapRecord(
SrsAlgorithm.getInstance().noteStats().dict,
(key: string, value: number): [string, number] => [
path.parse(key).name,
Math.round(value),
],
);

const grid = new Grid({
columns: [
{
name: "Note",
},
{
name: "Ease",
sort: true,
width: "200px",
},
],
search: true,
autoWidth: false,
data: Object.entries(noteEases).sort((a, b) => b[1] - a[1]),
pagination: {
limit: 10,
summary: false,
},
language: {
search: {
placeholder: "Search",
},
pagination: {
previous: "Previous",
next: "Next",
},
},
});
grid.render(document.getElementById("noteStats"));
}

destroy(): void {
Expand Down
2 changes: 2 additions & 0 deletions src/note-ease-list.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { SRSettings } from "src/settings";

export interface INoteEaseList {
dict: Record<string, number>;

hasEaseForPath(path: string): boolean;
getEaseByPath(path: string): number | null;
setEaseForPath(path: string, ease: number): void;
Expand Down
1 change: 0 additions & 1 deletion src/utils/numbers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ export class WeightedRandomNumber {
return new WeightedRandomNumber(globalRandomNumberProvider);
}

//
// weights is a dictionary:
// first number - a key that can be returned
// second number - the "bucket size" - this is a weight that influences the probability of the
Expand Down
9 changes: 9 additions & 0 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ export function getTypedObjectEntries<OBJ_T extends ObjectType>(obj: OBJ_T): Obj
export const getKeysPreserveType = Object.keys as <T extends Record<string, unknown>>(
obj: T,
) => Array<keyof T>;

export function mapRecord<T, U, V extends string | number | symbol>(
record: Record<string, T>,
transform: (key: string, value: T) => [V, U],
): Record<V, U> {
return Object.fromEntries(
Object.entries(record).map(([key, value]) => transform(key, value)),
) as Record<V, U>;
}

Check warning on line 37 in src/utils/types.ts

View check run for this annotation

Codecov / codecov/patch

src/utils/types.ts#L30-L37

Added lines #L30 - L37 were not covered by tests
Loading

0 comments on commit 7ea2bae

Please sign in to comment.