From 7e0bdb990cb508c2f5aba2bb6d3b86b2b53930d7 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 28 Jun 2020 15:23:36 +1000 Subject: [PATCH] i18n some axis labels, and support vertical CJK text --- rslib/ftl/statistics.ftl | 3 +++ ts/src/i18n.ts | 9 +++++++++ ts/src/stats/AddedGraph.svelte | 5 ++--- ts/src/stats/AxisLabels.svelte | 11 ++++++++++- ts/src/stats/ButtonsGraph.svelte | 5 ++--- ts/src/stats/CardCounts.svelte | 1 - ts/src/stats/EaseGraph.svelte | 4 ++-- ts/src/stats/FutureDue.svelte | 12 ++++++------ ts/src/stats/HistogramGraph.svelte | 4 +++- ts/src/stats/HourGraph.svelte | 5 ++--- ts/src/stats/IntervalsGraph.svelte | 8 ++------ ts/src/stats/ReviewsGraph.svelte | 16 +++++++++++----- ts/src/stats/graphs.css | 3 +-- ts/src/stats/reviews.ts | 16 +++++++++++++++- 14 files changed, 68 insertions(+), 34 deletions(-) diff --git a/rslib/ftl/statistics.ftl b/rslib/ftl/statistics.ftl index 5bd8baee7..d93fbdd28 100644 --- a/rslib/ftl/statistics.ftl +++ b/rslib/ftl/statistics.ftl @@ -95,3 +95,6 @@ statistics-answer-buttons-title = Answer Buttons statistics-hours-title = Hourly Breakdown statistics-added-title = Added statistics-card-ease-title = Card Ease +statistics-axis-label-answer-count = Answers +statistics-axis-label-card-count = Cards +statistics-axis-label-review-time = Review Time diff --git a/ts/src/i18n.ts b/ts/src/i18n.ts index ee209272b..78c36ccf6 100644 --- a/ts/src/i18n.ts +++ b/ts/src/i18n.ts @@ -36,6 +36,15 @@ export class I18n { return `missing key: ${key}`; } + supportsVerticalText(): boolean { + const firstLang = this.bundles[0].locales[0]; + return ( + firstLang.startsWith("ja") || + firstLang.startsWith("zh") || + firstLang.startsWith("ko") + ); + } + private keyName(msg: pb.BackendProto.FluentString): string { return this.TR[msg].toLowerCase().replace(/_/g, "-"); } diff --git a/ts/src/stats/AddedGraph.svelte b/ts/src/stats/AddedGraph.svelte index 1bd07faae..e7d66d364 100644 --- a/ts/src/stats/AddedGraph.svelte +++ b/ts/src/stats/AddedGraph.svelte @@ -15,12 +15,10 @@ let addedData: GraphData | null = null; $: if (sourceData) { - console.log("gathering data"); addedData = gatherData(sourceData); } $: if (addedData) { - console.log("preparing data"); histogramData = buildHistogram(addedData, range); } @@ -29,6 +27,7 @@ const month3 = timeSpan(i18n, 3 * MONTH); const year = timeSpan(i18n, 1 * YEAR); const all = i18n.tr(i18n.TR.STATISTICS_RANGE_ALL_TIME); + const yText = i18n.tr(i18n.TR.STATISTICS_AXIS_LABEL_CARD_COUNT); {#if histogramData} @@ -54,6 +53,6 @@ - + {/if} diff --git a/ts/src/stats/AxisLabels.svelte b/ts/src/stats/AxisLabels.svelte index d59cb6436..80e4c1fc7 100644 --- a/ts/src/stats/AxisLabels.svelte +++ b/ts/src/stats/AxisLabels.svelte @@ -1,8 +1,16 @@ + transform={`translate(${bounds.marginLeft / 3}, ${(bounds.height - bounds.marginBottom) / 2 + bounds.marginTop}) + rotate(${yRotate} 0 0)`}> {yText} diff --git a/ts/src/stats/ButtonsGraph.svelte b/ts/src/stats/ButtonsGraph.svelte index 6d06671d0..59060b829 100644 --- a/ts/src/stats/ButtonsGraph.svelte +++ b/ts/src/stats/ButtonsGraph.svelte @@ -11,16 +11,15 @@ const bounds = defaultGraphBounds(); const xText = ""; - const yText = "Times pressed"; let svg = null as HTMLElement | SVGElement | null; $: if (sourceData) { - console.log("gathering data"); renderButtons(svg as SVGElement, bounds, gatherData(sourceData)); } const title = i18n.tr(i18n.TR.STATISTICS_ANSWER_BUTTONS_TITLE); + const yText = i18n.tr(i18n.TR.STATISTICS_AXIS_LABEL_ANSWER_COUNT);
@@ -30,6 +29,6 @@ - +
diff --git a/ts/src/stats/CardCounts.svelte b/ts/src/stats/CardCounts.svelte index bd9666841..bc86fd41d 100644 --- a/ts/src/stats/CardCounts.svelte +++ b/ts/src/stats/CardCounts.svelte @@ -8,7 +8,6 @@ let cardCounts: CardCounts | null = null; $: if (sourceData) { - console.log("gathering data"); cardCounts = gatherData(sourceData, i18n); } diff --git a/ts/src/stats/EaseGraph.svelte b/ts/src/stats/EaseGraph.svelte index 2e9ed0676..c7928a656 100644 --- a/ts/src/stats/EaseGraph.svelte +++ b/ts/src/stats/EaseGraph.svelte @@ -12,17 +12,17 @@ let histogramData = null as HistogramData | null; $: if (sourceData) { - console.log("gathering data"); histogramData = prepareData(gatherData(sourceData)); } const title = i18n.tr(i18n.TR.STATISTICS_CARD_EASE_TITLE); + const yText = i18n.tr(i18n.TR.STATISTICS_AXIS_LABEL_CARD_COUNT); {#if histogramData}

{title}

- +
{/if} diff --git a/ts/src/stats/FutureDue.svelte b/ts/src/stats/FutureDue.svelte index ecc8db060..5a8b3a792 100644 --- a/ts/src/stats/FutureDue.svelte +++ b/ts/src/stats/FutureDue.svelte @@ -23,12 +23,10 @@ let range = FutureDueRange.Month; $: if (sourceData) { - console.log("gathering data"); graphData = gatherData(sourceData); } $: if (graphData) { - console.log("preparing data"); histogramData = buildHistogram(graphData, range); } @@ -37,6 +35,7 @@ const month3 = timeSpan(i18n, 3 * MONTH); const year = timeSpan(i18n, 1 * YEAR); const all = i18n.tr(i18n.TR.STATISTICS_RANGE_ALL_TIME); + const yText = i18n.tr(i18n.TR.STATISTICS_AXIS_LABEL_CARD_COUNT); {#if histogramData} @@ -44,6 +43,10 @@

{title}

+
+ The number of cards studied each day, relative to today. +
+
- +
{/if} diff --git a/ts/src/stats/HistogramGraph.svelte b/ts/src/stats/HistogramGraph.svelte index 38c25245e..2e754653c 100644 --- a/ts/src/stats/HistogramGraph.svelte +++ b/ts/src/stats/HistogramGraph.svelte @@ -3,8 +3,10 @@ import AxisLabels from "./AxisLabels.svelte"; import AxisTicks from "./AxisTicks.svelte"; import { defaultGraphBounds } from "./graphs"; + import { I18n } from "../i18n"; export let data: HistogramData | null = null; + export let i18n: I18n; export let xText: string; export let yText: string; @@ -21,5 +23,5 @@ - + diff --git a/ts/src/stats/HourGraph.svelte b/ts/src/stats/HourGraph.svelte index 5f15767f1..8b2478fd1 100644 --- a/ts/src/stats/HourGraph.svelte +++ b/ts/src/stats/HourGraph.svelte @@ -11,16 +11,15 @@ const bounds = defaultGraphBounds(); const xText = ""; - const yText = "Times pressed"; let svg = null as HTMLElement | SVGElement | null; $: if (sourceData) { - console.log("gathering data"); renderHours(svg as SVGElement, bounds, gatherData(sourceData)); } const title = i18n.tr(i18n.TR.STATISTICS_HOURS_TITLE); + const yText = i18n.tr(i18n.TR.STATISTICS_AXIS_LABEL_ANSWER_COUNT);
@@ -31,6 +30,6 @@ - +
diff --git a/ts/src/stats/IntervalsGraph.svelte b/ts/src/stats/IntervalsGraph.svelte index eb5862122..626219300 100644 --- a/ts/src/stats/IntervalsGraph.svelte +++ b/ts/src/stats/IntervalsGraph.svelte @@ -21,18 +21,17 @@ let range = IntervalRange.Percentile95; $: if (sourceData) { - console.log("gathering data"); intervalData = gatherIntervalData(sourceData); } $: if (intervalData) { - console.log("preparing data"); histogramData = prepareIntervalData(intervalData, range); } const title = i18n.tr(i18n.TR.STATISTICS_INTERVALS_TITLE); const month = timeSpan(i18n, 1 * MONTH); const all = i18n.tr(i18n.TR.STATISTICS_RANGE_ALL_TIME); + const yText = i18n.tr(i18n.TR.STATISTICS_AXIS_LABEL_CARD_COUNT); {#if histogramData} @@ -71,9 +70,6 @@ - + {/if} diff --git a/ts/src/stats/ReviewsGraph.svelte b/ts/src/stats/ReviewsGraph.svelte index b275bb7ce..60e12363f 100644 --- a/ts/src/stats/ReviewsGraph.svelte +++ b/ts/src/stats/ReviewsGraph.svelte @@ -32,21 +32,27 @@ } const xText = ""; - const yText = "Times pressed"; $: if (sourceData) { - console.log("gathering data"); graphData = gatherData(sourceData); } $: if (graphData) { - renderReviews(svg as SVGElement, bounds, graphData, range, showTime); + renderReviews(svg as SVGElement, bounds, graphData, range, showTime, i18n); } const title = i18n.tr(i18n.TR.STATISTICS_REVIEWS_TITLE); const month = timeSpan(i18n, 1 * MONTH); const month3 = timeSpan(i18n, 3 * MONTH); const year = timeSpan(i18n, 1 * YEAR); + const all = i18n.tr(i18n.TR.STATISTICS_RANGE_ALL_TIME); + + let yText: string; + $: if (showTime) { + yText = i18n.tr(i18n.TR.STATISTICS_AXIS_LABEL_REVIEW_TIME); + } else { + yText = i18n.tr(i18n.TR.STATISTICS_AXIS_LABEL_ANSWER_COUNT); + }
@@ -75,7 +81,7 @@ {#if revlogRange === RevlogRange.All} {/if}
@@ -87,7 +93,7 @@ - + diff --git a/ts/src/stats/graphs.css b/ts/src/stats/graphs.css index 11c9389af..ee568e416 100644 --- a/ts/src/stats/graphs.css +++ b/ts/src/stats/graphs.css @@ -81,8 +81,7 @@ } .y-axis-label { - writing-mode: vertical-rl; - rotate: 180; + writing-mode: vertical-lr; } .hoverzone rect { diff --git a/ts/src/stats/reviews.ts b/ts/src/stats/reviews.ts index 274a2f93a..d494b17ec 100644 --- a/ts/src/stats/reviews.ts +++ b/ts/src/stats/reviews.ts @@ -21,6 +21,8 @@ import { showTooltip, hideTooltip } from "./tooltip"; import { GraphBounds } from "./graphs"; import { area, curveBasis } from "d3-shape"; import { min, histogram, sum, max, Bin, cumsum } from "d3-array"; +import { timeSpan } from "../time"; +import { I18n } from "../i18n"; interface Reviews { mature: number; @@ -111,7 +113,8 @@ export function renderReviews( bounds: GraphBounds, sourceData: GraphData, range: ReviewRange, - showTime: boolean + showTime: boolean, + i18n: I18n ): void { const xMax = 0; let xMin = 0; @@ -161,6 +164,17 @@ export function renderReviews( axisLeft(y) .ticks(bounds.height / 80) .tickSizeOuter(0) + .tickFormat(((n: number): string => { + if (showTime) { + return timeSpan(i18n, n / 1000); + } else { + if (Math.round(n) != n) { + return ""; + } else { + return n.toString(); + } + } + }) as any) ); // x bars