diff --git a/ts/routes/graphs/DifficultyGraph.svelte b/ts/routes/graphs/DifficultyGraph.svelte index 5d05dc6fe..f71ae794a 100644 --- a/ts/routes/graphs/DifficultyGraph.svelte +++ b/ts/routes/graphs/DifficultyGraph.svelte @@ -7,14 +7,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import * as tr from "@generated/ftl"; import { createEventDispatcher } from "svelte"; - import { DifficultyRange, gatherData, prepareData } from "./difficulty"; + import { gatherData, prepareData } from "./difficulty"; import Graph from "./Graph.svelte"; import type { GraphPrefs } from "./graph-helpers"; import type { SearchEventMap, TableDatum } from "./graph-helpers"; import type { HistogramData } from "./histogram-graph"; import HistogramGraph from "./HistogramGraph.svelte"; import TableData from "./TableData.svelte"; - import InputBox from "./InputBox.svelte"; + import PercentageRange from "./PercentageRange.svelte"; + import { PercentageRangeEnum, PercentageRangeToQuantile } from "./percentageRange"; export let sourceData: GraphsResponse | null = null; export let prefs: GraphPrefs; @@ -23,13 +24,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html let histogramData: HistogramData | null = null; let tableData: TableDatum[] = []; - let range = DifficultyRange.All; - - $: percentile = { - [DifficultyRange.Percentile50]: 0.5, - [DifficultyRange.Percentile95]: 0.95, - [DifficultyRange.All]: 1, - }[range]; + let range = PercentageRangeEnum.All; $: if (sourceData) { const data = gatherData(sourceData); @@ -40,7 +35,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html data, dispatch, $prefs.browserLinksSupported, - 1 - percentile, + PercentageRangeToQuantile(range), ); } @@ -50,28 +45,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html {#if sourceData?.fsrs} - - - - - + diff --git a/ts/routes/graphs/PercentageRange.svelte b/ts/routes/graphs/PercentageRange.svelte new file mode 100644 index 000000000..250d45d99 --- /dev/null +++ b/ts/routes/graphs/PercentageRange.svelte @@ -0,0 +1,42 @@ + + + + + + + + + diff --git a/ts/routes/graphs/difficulty.ts b/ts/routes/graphs/difficulty.ts index 96aff05f9..aefeb9bd2 100644 --- a/ts/routes/graphs/difficulty.ts +++ b/ts/routes/graphs/difficulty.ts @@ -9,18 +9,12 @@ import type { GraphsResponse } from "@generated/anki/stats_pb"; import * as tr from "@generated/ftl"; import { localizedNumber } from "@tslib/i18n"; import type { Bin, ScaleLinear } from "d3"; -import { bin, interpolateRdYlGn, quantile, scaleLinear, scaleSequential, sum } from "d3"; +import { bin, interpolateRdYlGn, scaleLinear, scaleSequential, sum } from "d3"; import type { SearchDispatch, TableDatum } from "./graph-helpers"; import { getNumericMapBinValue, numericMap } from "./graph-helpers"; import type { HistogramData } from "./histogram-graph"; -export enum DifficultyRange { - All = 0, - Percentile50 = 1, - Percentile95 = 2, -} - export interface GraphData { eases: Map; average: number; @@ -63,19 +57,29 @@ function getAdjustedScaleAndTicks( ]; } +export function easeQuantile(data: Map, 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( data: GraphData, dispatch: SearchDispatch, browserLinksSupported: boolean, - lowerQuantile: number = 0 + quantile?: number, ): [HistogramData | null, TableDatum[]] { // get min/max const allEases = data.eases; if (!allEases.size) { return [null, []]; } - const xMin = quantile(Array.from(allEases.keys()), lowerQuantile) ?? 0; - const xMax = 100 + const xMin = quantile ? easeQuantile(allEases, 1 - quantile) ?? 0 : 0; + const xMax = quantile ? easeQuantile(allEases, quantile) ?? 0 : 100; const desiredBars = 20; const [scale, ticks] = getAdjustedScaleAndTicks(xMin, xMax, desiredBars); diff --git a/ts/routes/graphs/percentageRange.ts b/ts/routes/graphs/percentageRange.ts new file mode 100644 index 000000000..38ebc0dfd --- /dev/null +++ b/ts/routes/graphs/percentageRange.ts @@ -0,0 +1,17 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +export enum PercentageRangeEnum { + All = 0, + Percentile100 = 1, + Percentile95 = 2, + Percentile50 = 3, +} + +export function PercentageRangeToQuantile(range: PercentageRangeEnum) { + return ({ + [PercentageRangeEnum.Percentile100]: 1, + [PercentageRangeEnum.Percentile95]: 0.95, + [PercentageRangeEnum.Percentile50]: 0.5, + [PercentageRangeEnum.All]: undefined, + })[range]; +}