mirror of
https://github.com/ankitects/anki.git
synced 2026-01-10 12:33:55 -05:00
Add to retrievability graph
This commit is contained in:
parent
c3f29fad0b
commit
13caf85f26
4 changed files with 31 additions and 14 deletions
|
|
@ -14,6 +14,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import HistogramGraph from "./HistogramGraph.svelte";
|
import HistogramGraph from "./HistogramGraph.svelte";
|
||||||
import { gatherData, prepareData } from "./retrievability";
|
import { gatherData, prepareData } from "./retrievability";
|
||||||
import TableData from "./TableData.svelte";
|
import TableData from "./TableData.svelte";
|
||||||
|
import PercentageRange from "./PercentageRange.svelte";
|
||||||
|
import { PercentageRangeEnum, PercentageRangeToQuantile } from "./percentageRange";
|
||||||
|
|
||||||
export let sourceData: GraphsResponse | null = null;
|
export let sourceData: GraphsResponse | null = null;
|
||||||
export let prefs: GraphPrefs;
|
export let prefs: GraphPrefs;
|
||||||
|
|
@ -22,12 +24,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
let histogramData: HistogramData | null = null;
|
let histogramData: HistogramData | null = null;
|
||||||
let tableData: TableDatum[] = [];
|
let tableData: TableDatum[] = [];
|
||||||
|
let range = PercentageRangeEnum.All;
|
||||||
|
|
||||||
$: if (sourceData) {
|
$: if (sourceData) {
|
||||||
[histogramData, tableData] = prepareData(
|
[histogramData, tableData] = prepareData(
|
||||||
gatherData(sourceData),
|
gatherData(sourceData),
|
||||||
dispatch,
|
dispatch,
|
||||||
$prefs.browserLinksSupported,
|
$prefs.browserLinksSupported,
|
||||||
|
PercentageRangeToQuantile(range),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,6 +41,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
{#if sourceData?.fsrs}
|
{#if sourceData?.fsrs}
|
||||||
<Graph {title} {subtitle}>
|
<Graph {title} {subtitle}>
|
||||||
|
<PercentageRange bind:range />
|
||||||
|
|
||||||
<HistogramGraph data={histogramData} />
|
<HistogramGraph data={histogramData} />
|
||||||
|
|
||||||
<TableData {tableData} />
|
<TableData {tableData} />
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import { bin, interpolateRdYlGn, scaleLinear, scaleSequential, sum } from "d3";
|
||||||
import type { SearchDispatch, TableDatum } from "./graph-helpers";
|
import type { SearchDispatch, TableDatum } from "./graph-helpers";
|
||||||
import { getNumericMapBinValue, numericMap } from "./graph-helpers";
|
import { getNumericMapBinValue, numericMap } from "./graph-helpers";
|
||||||
import type { HistogramData } from "./histogram-graph";
|
import type { HistogramData } from "./histogram-graph";
|
||||||
|
import { percentageRangeMinMax } from "./percentageRange";
|
||||||
|
|
||||||
export interface GraphData {
|
export interface GraphData {
|
||||||
eases: Map<number, number>;
|
eases: Map<number, number>;
|
||||||
|
|
@ -57,16 +58,6 @@ function getAdjustedScaleAndTicks(
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function easeQuantile(data: Map<number, number>, quantile: number) {
|
|
||||||
let count = sum(data.values()) * quantile;
|
|
||||||
for (const [key, value] of data.entries()) {
|
|
||||||
count -= value;
|
|
||||||
if (count <= 0) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function prepareData(
|
export function prepareData(
|
||||||
data: GraphData,
|
data: GraphData,
|
||||||
dispatch: SearchDispatch,
|
dispatch: SearchDispatch,
|
||||||
|
|
@ -78,8 +69,7 @@ export function prepareData(
|
||||||
if (!allEases.size) {
|
if (!allEases.size) {
|
||||||
return [null, []];
|
return [null, []];
|
||||||
}
|
}
|
||||||
const xMin = quantile ? easeQuantile(allEases, 1 - quantile) ?? 0 : 0;
|
const [xMin, xMax] = percentageRangeMinMax(allEases, quantile);
|
||||||
const xMax = quantile ? easeQuantile(allEases, quantile) ?? 0 : 100;
|
|
||||||
const desiredBars = 20;
|
const desiredBars = 20;
|
||||||
|
|
||||||
const [scale, ticks] = getAdjustedScaleAndTicks(xMin, xMax, desiredBars);
|
const [scale, ticks] = getAdjustedScaleAndTicks(xMin, xMax, desiredBars);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
// Copyright: Ankitects Pty Ltd and contributors
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
|
||||||
|
import { sum } from "d3";
|
||||||
|
|
||||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
export enum PercentageRangeEnum {
|
export enum PercentageRangeEnum {
|
||||||
All = 0,
|
All = 0,
|
||||||
|
|
@ -15,3 +18,20 @@ export function PercentageRangeToQuantile(range: PercentageRangeEnum) {
|
||||||
[PercentageRangeEnum.All]: undefined,
|
[PercentageRangeEnum.All]: undefined,
|
||||||
})[range];
|
})[range];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function easeQuantile(data: Map<number, number>, quantile: number) {
|
||||||
|
let count = sum(data.values()) * quantile;
|
||||||
|
for (const [key, value] of data.entries()) {
|
||||||
|
count -= value;
|
||||||
|
if (count <= 0) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function percentageRangeMinMax(data: Map<number, number>, range: number | undefined) {
|
||||||
|
const xMin = range ? easeQuantile(data, 1 - range) ?? 0 : 0;
|
||||||
|
const xMax = range ? easeQuantile(data, range) ?? 0 : 100;
|
||||||
|
|
||||||
|
return [xMin, xMax];
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import { bin, interpolateRdYlGn, scaleLinear, scaleSequential, sum } from "d3";
|
||||||
import type { SearchDispatch, TableDatum } from "./graph-helpers";
|
import type { SearchDispatch, TableDatum } from "./graph-helpers";
|
||||||
import { getNumericMapBinValue, numericMap } from "./graph-helpers";
|
import { getNumericMapBinValue, numericMap } from "./graph-helpers";
|
||||||
import type { HistogramData } from "./histogram-graph";
|
import type { HistogramData } from "./histogram-graph";
|
||||||
|
import { percentageRangeMinMax } from "./percentageRange";
|
||||||
|
|
||||||
export interface GraphData {
|
export interface GraphData {
|
||||||
retrievability: Map<number, number>;
|
retrievability: Map<number, number>;
|
||||||
|
|
@ -68,14 +69,14 @@ export function prepareData(
|
||||||
data: GraphData,
|
data: GraphData,
|
||||||
dispatch: SearchDispatch,
|
dispatch: SearchDispatch,
|
||||||
browserLinksSupported: boolean,
|
browserLinksSupported: boolean,
|
||||||
|
quantile?: number,
|
||||||
): [HistogramData | null, TableDatum[]] {
|
): [HistogramData | null, TableDatum[]] {
|
||||||
// get min/max
|
// get min/max
|
||||||
const allEases = data.retrievability;
|
const allEases = data.retrievability;
|
||||||
if (!allEases.size) {
|
if (!allEases.size) {
|
||||||
return [null, []];
|
return [null, []];
|
||||||
}
|
}
|
||||||
const xMin = 0;
|
const [xMin, xMax] = percentageRangeMinMax(allEases, quantile);
|
||||||
const xMax = 100;
|
|
||||||
const desiredBars = 20;
|
const desiredBars = 20;
|
||||||
|
|
||||||
const [scale, ticks] = getAdjustedScaleAndTicks(xMin, xMax, desiredBars);
|
const [scale, ticks] = getAdjustedScaleAndTicks(xMin, xMax, desiredBars);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue