mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
I18n: Improve i18n and multi-platform display of FSRS Simulator (#3611)
* Improve i18n and multi-platform display of FSRS Simulator * Tweak the graph bounds to avoid overlapping of the y-axis tick values and the y-axis title * Update CONTRIBUTORS * I18n for 4 more strings * Reduce TitledContainer wrapper of fsrs simulator graph to maximize content display area * Clean unused variables * Update ftl/core/deck-config.ftl * Update ftl/core/deck-config.ftl
This commit is contained in:
parent
1fb5e99efc
commit
008edbba28
4 changed files with 32 additions and 11 deletions
|
@ -461,6 +461,12 @@ deck-config-answer-hard = Answer Hard
|
||||||
deck-config-answer-good = Answer Good
|
deck-config-answer-good = Answer Good
|
||||||
deck-config-days-to-simulate = Days to simulate
|
deck-config-days-to-simulate = Days to simulate
|
||||||
deck-config-desired-retention-below-optimal = Your desired retention is below optimal. Increasing it is recommended.
|
deck-config-desired-retention-below-optimal = Your desired retention is below optimal. Increasing it is recommended.
|
||||||
|
deck-config-fsrs-simulator-y-axis-title-time = Review Time/Day
|
||||||
|
deck-config-fsrs-simulator-y-axis-title-count = Review Count/Day
|
||||||
|
deck-config-fsrs-simulator-experimental = FSRS simulator (experimental)
|
||||||
|
deck-config-additional-new-cards-to-simulate = Additional new cards to simulate
|
||||||
|
deck-config-simulate = Simulate
|
||||||
|
deck-config-clear-last-simulate = Clear last simulation
|
||||||
|
|
||||||
## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future.
|
## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future.
|
||||||
|
|
||||||
|
|
|
@ -293,8 +293,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
let tableData: TableDatum[] = [] as any;
|
let tableData: TableDatum[] = [] as any;
|
||||||
const bounds = defaultGraphBounds();
|
const bounds = defaultGraphBounds();
|
||||||
|
bounds.marginLeft += 8;
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg = null as HTMLElement | SVGElement | null;
|
||||||
const title = tr.statisticsReviewsTitle();
|
|
||||||
let simulationNumber = 0;
|
let simulationNumber = 0;
|
||||||
|
|
||||||
let points: Point[] = [];
|
let points: Point[] = [];
|
||||||
|
@ -492,7 +492,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
<div class="m-2">
|
<div class="m-2">
|
||||||
<details>
|
<details>
|
||||||
<summary>FSRS simulator (experimental)</summary>
|
<summary>{tr.deckConfigFsrsSimulatorExperimental()}</summary>
|
||||||
|
|
||||||
<SpinBoxRow
|
<SpinBoxRow
|
||||||
bind:value={simulateFsrsRequest.daysToSimulate}
|
bind:value={simulateFsrsRequest.daysToSimulate}
|
||||||
|
@ -512,7 +512,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
max={100000}
|
max={100000}
|
||||||
>
|
>
|
||||||
<SettingTitle on:click={() => openHelpModal("simulateFsrsReview")}>
|
<SettingTitle on:click={() => openHelpModal("simulateFsrsReview")}>
|
||||||
Additional new cards to simulate
|
{tr.deckConfigAdditionalNewCardsToSimulate()}
|
||||||
</SettingTitle>
|
</SettingTitle>
|
||||||
</SpinBoxRow>
|
</SpinBoxRow>
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
disabled={computing}
|
disabled={computing}
|
||||||
on:click={() => simulateFsrs()}
|
on:click={() => simulateFsrs()}
|
||||||
>
|
>
|
||||||
{"Simulate"}
|
{tr.deckConfigSimulate()}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -562,11 +562,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
disabled={computing}
|
disabled={computing}
|
||||||
on:click={() => clearSimulation()}
|
on:click={() => clearSimulation()}
|
||||||
>
|
>
|
||||||
{"Clear last simulation"}
|
{tr.deckConfigClearLastSimulate()}
|
||||||
</button>
|
</button>
|
||||||
<div>{simulateProgressString}</div>
|
<div>{simulateProgressString}</div>
|
||||||
|
|
||||||
<Graph {title}>
|
<Graph>
|
||||||
<InputBox>
|
<InputBox>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" bind:checked={showTime} />
|
<input type="checkbox" bind:checked={showTime} />
|
||||||
|
|
|
@ -5,10 +5,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import TitledContainer from "$lib/components/TitledContainer.svelte";
|
import TitledContainer from "$lib/components/TitledContainer.svelte";
|
||||||
|
|
||||||
export let title: string;
|
// When title is null (default), the graph is inlined, not having TitledContainer wrapper.
|
||||||
|
export let title: string | null = null;
|
||||||
export let subtitle: string | null = null;
|
export let subtitle: string | null = null;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{#if title == null}
|
||||||
|
<div class="graph d-flex flex-grow-1 flex-column justify-content-center">
|
||||||
|
{#if subtitle}
|
||||||
|
<div class="subtitle">{subtitle}</div>
|
||||||
|
{/if}
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
<TitledContainer class="d-flex flex-column" {title}>
|
<TitledContainer class="d-flex flex-column" {title}>
|
||||||
<div class="graph d-flex flex-grow-1 flex-column justify-content-center">
|
<div class="graph d-flex flex-grow-1 flex-column justify-content-center">
|
||||||
{#if subtitle}
|
{#if subtitle}
|
||||||
|
@ -17,6 +26,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</TitledContainer>
|
</TitledContainer>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@use "$lib/sass/elevation" as *;
|
@use "$lib/sass/elevation" as *;
|
||||||
|
|
|
@ -91,10 +91,15 @@ export function renderSimulationChart(
|
||||||
.attr("transform", "rotate(-90)")
|
.attr("transform", "rotate(-90)")
|
||||||
.attr("y", 0 - bounds.marginLeft)
|
.attr("y", 0 - bounds.marginLeft)
|
||||||
.attr("x", 0 - (bounds.height / 2))
|
.attr("x", 0 - (bounds.height / 2))
|
||||||
.attr("dy", "1em")
|
.attr("font-size", "1rem")
|
||||||
|
.attr("dy", "1.1em")
|
||||||
.attr("fill", "currentColor")
|
.attr("fill", "currentColor")
|
||||||
.style("text-anchor", "middle")
|
.style("text-anchor", "middle")
|
||||||
.text(showTime ? "Review Time per day" : "Review Count per day");
|
.text(`${
|
||||||
|
showTime
|
||||||
|
? tr.deckConfigFsrsSimulatorYAxisTitleTime()
|
||||||
|
: tr.deckConfigFsrsSimulatorYAxisTitleCount()
|
||||||
|
}`);
|
||||||
|
|
||||||
// x lines
|
// x lines
|
||||||
const points = convertedData.map((d) => [x(d.date), y(showTime ? d.timeCost : d.count), d.label]);
|
const points = convertedData.map((d) => [x(d.date), y(showTime ? d.timeCost : d.count), d.label]);
|
||||||
|
|
Loading…
Reference in a new issue