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:
OuOu2021 2024-12-14 18:59:00 +08:00 committed by GitHub
parent 1fb5e99efc
commit 008edbba28
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 11 deletions

View file

@ -461,6 +461,12 @@ deck-config-answer-hard = Answer Hard
deck-config-answer-good = Answer Good
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-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.

View file

@ -293,8 +293,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let tableData: TableDatum[] = [] as any;
const bounds = defaultGraphBounds();
bounds.marginLeft += 8;
let svg = null as HTMLElement | SVGElement | null;
const title = tr.statisticsReviewsTitle();
let simulationNumber = 0;
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">
<details>
<summary>FSRS simulator (experimental)</summary>
<summary>{tr.deckConfigFsrsSimulatorExperimental()}</summary>
<SpinBoxRow
bind:value={simulateFsrsRequest.daysToSimulate}
@ -512,7 +512,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
max={100000}
>
<SettingTitle on:click={() => openHelpModal("simulateFsrsReview")}>
Additional new cards to simulate
{tr.deckConfigAdditionalNewCardsToSimulate()}
</SettingTitle>
</SpinBoxRow>
@ -554,7 +554,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
disabled={computing}
on:click={() => simulateFsrs()}
>
{"Simulate"}
{tr.deckConfigSimulate()}
</button>
<button
@ -562,11 +562,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
disabled={computing}
on:click={() => clearSimulation()}
>
{"Clear last simulation"}
{tr.deckConfigClearLastSimulate()}
</button>
<div>{simulateProgressString}</div>
<Graph {title}>
<Graph>
<InputBox>
<label>
<input type="checkbox" bind:checked={showTime} />

View file

@ -5,18 +5,28 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<script lang="ts">
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;
</script>
<TitledContainer class="d-flex flex-column" {title}>
{#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>
</TitledContainer>
{:else}
<TitledContainer class="d-flex flex-column" {title}>
<div class="graph d-flex flex-grow-1 flex-column justify-content-center">
{#if subtitle}
<div class="subtitle">{subtitle}</div>
{/if}
<slot />
</div>
</TitledContainer>
{/if}
<style lang="scss">
@use "$lib/sass/elevation" as *;

View file

@ -91,10 +91,15 @@ export function renderSimulationChart(
.attr("transform", "rotate(-90)")
.attr("y", 0 - bounds.marginLeft)
.attr("x", 0 - (bounds.height / 2))
.attr("dy", "1em")
.attr("font-size", "1rem")
.attr("dy", "1.1em")
.attr("fill", "currentColor")
.style("text-anchor", "middle")
.text(showTime ? "Review Time per day" : "Review Count per day");
.text(`${
showTime
? tr.deckConfigFsrsSimulatorYAxisTitleTime()
: tr.deckConfigFsrsSimulatorYAxisTitleCount()
}`);
// x lines
const points = convertedData.map((d) => [x(d.date), y(showTime ? d.timeCost : d.count), d.label]);