From e91b80d27012f4048ddc65f77a4f411c2fb37e50 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Wed, 20 Jan 2021 21:17:36 +0100 Subject: [PATCH 1/5] Add labels to calendar days --- ts/graphs/CalendarGraph.svelte | 1 + ts/graphs/calendar.ts | 41 +++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/ts/graphs/CalendarGraph.svelte b/ts/graphs/CalendarGraph.svelte index 059668333..c11606c09 100644 --- a/ts/graphs/CalendarGraph.svelte +++ b/ts/graphs/CalendarGraph.svelte @@ -74,6 +74,7 @@ + diff --git a/ts/graphs/calendar.ts b/ts/graphs/calendar.ts index a5b1deb23..f9ddc55bf 100644 --- a/ts/graphs/calendar.ts +++ b/ts/graphs/calendar.ts @@ -28,6 +28,7 @@ export interface GraphData { // indexed by day, where day is relative to today reviewCount: Map; timeFunction: CountableTimeInterval; + weekdayLabels: string[]; } interface DayDatum { @@ -63,7 +64,14 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { ? timeSaturday : timeSunday; - return { reviewCount, timeFunction }; + const weekdayLabels = ["S", "M", "T", "W", "T", "F", "S"]; + + for (let i = 0; i < data.firstWeekday; i++) { + const shifted = weekdayLabels.shift() as string; + weekdayLabels.push(shifted); + } + + return { reviewCount, timeFunction, weekdayLabels }; } export function renderCalendar( @@ -82,7 +90,8 @@ export function renderCalendar( const x = scaleLinear() .range([bounds.marginLeft, bounds.width - bounds.marginRight]) - .domain([0, 53]); + .domain([-1, 53]); + // map of 0-365 -> day const dayMap: Map = new Map(); let maxCount = 0; @@ -153,20 +162,30 @@ export function renderCalendar( } const height = bounds.height / 10; - let emptyColour = "#ddd"; - if (nightMode) { - emptyColour = "#333"; - } - svg.select(`g.days`) + const emptyColour = nightMode ? "#333" : "#ddd"; + + svg.select("g.weekdays") + .selectAll("text") + .data(sourceData.weekdayLabels) + .join("text") + .text((d) => d) + .attr("width", x(-1)! - 2) + .attr("height", height - 2) + .attr("x", x(0)!) + .attr("y", (_d, index) => bounds.marginTop + index * height) + .attr("dominant-baseline", "hanging") + .attr("font-size", "small") + .attr("font-family", "monospace") + .style("user-select", "none"); + + svg.select("g.days") .selectAll("rect") .data(data) .join("rect") .attr("fill", emptyColour) - .attr("width", (d) => { - return x(d.weekNumber + 1)! - x(d.weekNumber)! - 2; - }) + .attr("width", (d) => x(d.weekNumber + 1)! - x(d.weekNumber)! - 2) .attr("height", height - 2) - .attr("x", (d) => x(d.weekNumber)!) + .attr("x", (d) => x(d.weekNumber + 1)!) .attr("y", (d) => bounds.marginTop + d.weekDay * height) .on("mousemove", function (this: any, d: any) { const [x, y] = mouse(document.body); From 8e39ebb2f5d3a334dfea9e0e7c7cabf46d5e5414 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Wed, 20 Jan 2021 21:49:01 +0100 Subject: [PATCH 2/5] Make weekday labels localizable --- ftl/core/statistics.ftl | 7 +++++++ ts/graphs/CalendarGraph.svelte | 2 +- ts/graphs/calendar.ts | 12 ++++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ftl/core/statistics.ftl b/ftl/core/statistics.ftl index 0b5fc5eb5..5c4353717 100644 --- a/ftl/core/statistics.ftl +++ b/ftl/core/statistics.ftl @@ -156,6 +156,13 @@ statistics-hours-subtitle = Review success rate for each hour of the day. # shown when graph is empty statistics-no-data = NO DATA statistics-calendar-title = Calendar +statistics-calendar-label-sunday = S +statistics-calendar-label-monday = M +statistics-calendar-label-tuesday = T +statistics-calendar-label-wednesday = W +statistics-calendar-label-thursday = T +statistics-calendar-label-friday = F +statistics-calendar-label-saturday = S ## An amount of elapsed time, used in the graphs to show the amount of ## time spent studying. For example, English would show "5s" for 5 seconds, diff --git a/ts/graphs/CalendarGraph.svelte b/ts/graphs/CalendarGraph.svelte index c11606c09..910ed6565 100644 --- a/ts/graphs/CalendarGraph.svelte +++ b/ts/graphs/CalendarGraph.svelte @@ -25,7 +25,7 @@ let targetYear = maxYear; $: if (sourceData) { - graphData = gatherData(sourceData); + graphData = gatherData(sourceData, i18n); } $: { diff --git a/ts/graphs/calendar.ts b/ts/graphs/calendar.ts index f9ddc55bf..3afbc02f2 100644 --- a/ts/graphs/calendar.ts +++ b/ts/graphs/calendar.ts @@ -41,7 +41,7 @@ interface DayDatum { date: Date; } -export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { +export function gatherData(data: pb.BackendProto.GraphsOut, i18n: I18n): GraphData { const reviewCount = new Map(); for (const review of data.revlog as pb.BackendProto.RevlogEntry[]) { @@ -64,7 +64,15 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { ? timeSaturday : timeSunday; - const weekdayLabels = ["S", "M", "T", "W", "T", "F", "S"]; + const weekdayLabels = [ + i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_SUNDAY), + i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_MONDAY), + i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_TUESDAY), + i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_WEDNESDAY), + i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_THURSDAY), + i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_FRIDAY), + i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_SATURDAY), + ]; for (let i = 0; i < data.firstWeekday; i++) { const shifted = weekdayLabels.shift() as string; From 8ab2b36034e6a3c54dc10a0ed584fff9a723d598 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Wed, 20 Jan 2021 22:07:02 +0100 Subject: [PATCH 3/5] Support languages with day labels larger than one character --- ts/graphs/calendar.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ts/graphs/calendar.ts b/ts/graphs/calendar.ts index 3afbc02f2..4c70ab012 100644 --- a/ts/graphs/calendar.ts +++ b/ts/graphs/calendar.ts @@ -179,9 +179,10 @@ export function renderCalendar( .text((d) => d) .attr("width", x(-1)! - 2) .attr("height", height - 2) - .attr("x", x(0)!) + .attr("x", x(1)! - 3) .attr("y", (_d, index) => bounds.marginTop + index * height) .attr("dominant-baseline", "hanging") + .attr("text-anchor", "end") .attr("font-size", "small") .attr("font-family", "monospace") .style("user-select", "none"); From d961e61f2b7371ff70f6adb0bc89b798989f44d4 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 21 Jan 2021 18:56:56 +0100 Subject: [PATCH 4/5] Revert "Make weekday labels localizable" This reverts commit 8e39ebb2f5d3a334dfea9e0e7c7cabf46d5e5414. --- ftl/core/statistics.ftl | 7 ------- ts/graphs/CalendarGraph.svelte | 2 +- ts/graphs/calendar.ts | 12 ++---------- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/ftl/core/statistics.ftl b/ftl/core/statistics.ftl index 5c4353717..0b5fc5eb5 100644 --- a/ftl/core/statistics.ftl +++ b/ftl/core/statistics.ftl @@ -156,13 +156,6 @@ statistics-hours-subtitle = Review success rate for each hour of the day. # shown when graph is empty statistics-no-data = NO DATA statistics-calendar-title = Calendar -statistics-calendar-label-sunday = S -statistics-calendar-label-monday = M -statistics-calendar-label-tuesday = T -statistics-calendar-label-wednesday = W -statistics-calendar-label-thursday = T -statistics-calendar-label-friday = F -statistics-calendar-label-saturday = S ## An amount of elapsed time, used in the graphs to show the amount of ## time spent studying. For example, English would show "5s" for 5 seconds, diff --git a/ts/graphs/CalendarGraph.svelte b/ts/graphs/CalendarGraph.svelte index 910ed6565..c11606c09 100644 --- a/ts/graphs/CalendarGraph.svelte +++ b/ts/graphs/CalendarGraph.svelte @@ -25,7 +25,7 @@ let targetYear = maxYear; $: if (sourceData) { - graphData = gatherData(sourceData, i18n); + graphData = gatherData(sourceData); } $: { diff --git a/ts/graphs/calendar.ts b/ts/graphs/calendar.ts index 4c70ab012..c8823fe0b 100644 --- a/ts/graphs/calendar.ts +++ b/ts/graphs/calendar.ts @@ -41,7 +41,7 @@ interface DayDatum { date: Date; } -export function gatherData(data: pb.BackendProto.GraphsOut, i18n: I18n): GraphData { +export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { const reviewCount = new Map(); for (const review of data.revlog as pb.BackendProto.RevlogEntry[]) { @@ -64,15 +64,7 @@ export function gatherData(data: pb.BackendProto.GraphsOut, i18n: I18n): GraphDa ? timeSaturday : timeSunday; - const weekdayLabels = [ - i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_SUNDAY), - i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_MONDAY), - i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_TUESDAY), - i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_WEDNESDAY), - i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_THURSDAY), - i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_FRIDAY), - i18n.tr(i18n.TR.STATISTICS_CALENDAR_LABEL_SATURDAY), - ]; + const weekdayLabels = ["S", "M", "T", "W", "T", "F", "S"]; for (let i = 0; i < data.firstWeekday; i++) { const shifted = weekdayLabels.shift() as string; From d1980aae68d75d072b653ec3d756efe5931bd71a Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Thu, 21 Jan 2021 19:31:47 +0100 Subject: [PATCH 5/5] Get weekday labels via Date.prototype.toLocaleString --- ts/graphs/calendar.ts | 12 +++++------- ts/lib/i18n.ts | 7 +++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ts/graphs/calendar.ts b/ts/graphs/calendar.ts index c8823fe0b..49069b320 100644 --- a/ts/graphs/calendar.ts +++ b/ts/graphs/calendar.ts @@ -28,7 +28,7 @@ export interface GraphData { // indexed by day, where day is relative to today reviewCount: Map; timeFunction: CountableTimeInterval; - weekdayLabels: string[]; + weekdayLabels: number[]; } interface DayDatum { @@ -64,11 +64,9 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData { ? timeSaturday : timeSunday; - const weekdayLabels = ["S", "M", "T", "W", "T", "F", "S"]; - - for (let i = 0; i < data.firstWeekday; i++) { - const shifted = weekdayLabels.shift() as string; - weekdayLabels.push(shifted); + const weekdayLabels: number[] = []; + for (let i = 0; i < 7; i++) { + weekdayLabels.push((data.firstWeekday + i) % 7); } return { reviewCount, timeFunction, weekdayLabels }; @@ -168,7 +166,7 @@ export function renderCalendar( .selectAll("text") .data(sourceData.weekdayLabels) .join("text") - .text((d) => d) + .text((d: number) => i18n.weekdayLabel(d)) .attr("width", x(-1)! - 2) .attr("height", height - 2) .attr("x", x(1)! - 3) diff --git a/ts/lib/i18n.ts b/ts/lib/i18n.ts index 443c9c687..7210196ed 100644 --- a/ts/lib/i18n.ts +++ b/ts/lib/i18n.ts @@ -59,6 +59,13 @@ export class I18n { } } + weekdayLabel(n: number): string { + const firstLang = this.bundles[0].locales[0]; + return new Date(86_400_000 * (3 + n)).toLocaleDateString(firstLang, { + weekday: "narrow", + }); + } + private keyName(msg: pb.FluentProto.FluentString): string { return this.TR[msg].toLowerCase().replace(/_/g, "-"); }