add timeSpan()

This commit is contained in:
Damien Elmes 2020-06-27 22:10:56 +10:00
parent 93ab3b4164
commit 8e118bbc76
6 changed files with 104 additions and 27 deletions

View file

@ -1,10 +1,13 @@
<script lang="typescript">
import { timeSpan, MONTH, YEAR } from "../time";
import { I18n } from "../i18n";
import { HistogramData } from "./histogram-graph";
import { gatherData, buildHistogram, GraphData, AddedRange } from "./added";
import pb from "../backend/proto";
import HistogramGraph from "./HistogramGraph.svelte";
export let sourceData: pb.BackendProto.GraphsOut | null = null;
export let i18n: I18n;
let svg = null as HTMLElement | SVGElement | null;
let histogramData = null as HistogramData | null;
@ -20,6 +23,10 @@
console.log("preparing data");
histogramData = buildHistogram(addedData, range);
}
const month = timeSpan(i18n, 1 * MONTH);
const month3 = timeSpan(i18n, 3 * MONTH);
const year = timeSpan(i18n, 1 * YEAR);
</script>
{#if histogramData}
@ -29,15 +36,15 @@
<div class="range-box-inner">
<label>
<input type="radio" bind:group={range} value={AddedRange.Month} />
Month
{month}
</label>
<label>
<input type="radio" bind:group={range} value={AddedRange.Quarter} />
3 months
{month3}
</label>
<label>
<input type="radio" bind:group={range} value={AddedRange.Year} />
Year
{year}
</label>
<label>
<input type="radio" bind:group={range} value={AddedRange.AllTime} />

View file

@ -1,4 +1,6 @@
<script lang="typescript">
import { timeSpan, MONTH, YEAR } from "../time";
import { I18n } from "../i18n";
import { HistogramData } from "./histogram-graph";
import { defaultGraphBounds } from "./graphs";
import {
@ -12,6 +14,8 @@
import HistogramGraph from "./HistogramGraph.svelte";
export let sourceData: pb.BackendProto.GraphsOut | null = null;
export let i18n: I18n;
let graphData = null as GraphData | null;
let histogramData = null as HistogramData | null;
@ -27,6 +31,10 @@
console.log("preparing data");
histogramData = buildHistogram(graphData, range);
}
const month = timeSpan(i18n, 1 * MONTH);
const month3 = timeSpan(i18n, 3 * MONTH);
const year = timeSpan(i18n, 1 * YEAR);
</script>
{#if histogramData}
@ -37,15 +45,15 @@
<div class="range-box-inner">
<label>
<input type="radio" bind:group={range} value={FutureDueRange.Month} />
Month
{month}
</label>
<label>
<input type="radio" bind:group={range} value={FutureDueRange.Quarter} />
3 months
{month3}
</label>
<label>
<input type="radio" bind:group={range} value={FutureDueRange.Year} />
Year
{year}
</label>
<label>
<input type="radio" bind:group={range} value={FutureDueRange.AllTime} />

View file

@ -3,8 +3,9 @@
</script>
<script lang="typescript">
import { assertUnreachable } from "../typing";
import { timeSpan, MONTH, YEAR } from "../time";
import { I18n } from "../i18n";
import { assertUnreachable } from "../typing";
import pb from "../backend/proto";
import { getGraphData, RevlogRange } from "./graphs";
import IntervalsGraph from "./IntervalsGraph.svelte";
@ -81,6 +82,9 @@
search = displayedSearch;
}
};
const month = timeSpan(i18n, 1 * MONTH);
const year = timeSpan(i18n, 1 * YEAR);
</script>
<div class="range-box">
@ -113,11 +117,11 @@
Review history:
<label>
<input type="radio" bind:group={revlogRange} value={RevlogRange.Month} />
Month
{month}
</label>
<label>
<input type="radio" bind:group={revlogRange} value={RevlogRange.Year} />
Year
{year}
</label>
<label>
<input type="radio" bind:group={revlogRange} value={RevlogRange.All} />
@ -129,10 +133,10 @@
<TodayStats {sourceData} {i18n} />
<CardCounts {sourceData} {i18n} />
<FutureDue {sourceData} />
<ReviewsGraph {sourceData} {revlogRange} />
<IntervalsGraph {sourceData} />
<FutureDue {sourceData} {i18n} />
<ReviewsGraph {sourceData} {revlogRange} {i18n} />
<IntervalsGraph {sourceData} {i18n} />
<EaseGraph {sourceData} />
<ButtonsGraph {sourceData} />
<HourGraph {sourceData} />
<AddedGraph {sourceData} />
<AddedGraph {sourceData} {i18n} />

View file

@ -1,4 +1,6 @@
<script lang="typescript">
import { timeSpan, MONTH, YEAR } from "../time";
import { I18n } from "../i18n";
import { HistogramData } from "./histogram-graph";
import {
gatherIntervalData,
@ -10,13 +12,14 @@
import HistogramGraph from "./HistogramGraph.svelte";
export let sourceData: pb.BackendProto.GraphsOut | null = null;
export let i18n: I18n;
let intervalData: IntervalGraphData | null = null;
let histogramData = null as HistogramData | null;
let svg = null as HTMLElement | SVGElement | null;
let range = IntervalRange.Percentile95;
$: if (sourceData) {
console.log("gathering data");
intervalData = gatherIntervalData(sourceData);
@ -26,6 +29,8 @@
console.log("preparing data");
histogramData = prepareIntervalData(intervalData, range);
}
const month = timeSpan(i18n, 1 * MONTH);
</script>
{#if histogramData}
@ -35,28 +40,28 @@
<div class="range-box-inner">
<label>
<input type="radio" bind:group={range} value={IntervalRange.Month} />
Month
{month}
</label>
<label>
<input
type="radio"
bind:group={range}
value={IntervalRange.Percentile50} />
50th percentile
50%
</label>
<label>
<input
type="radio"
bind:group={range}
value={IntervalRange.Percentile95} />
95th percentile
95%
</label>
<label>
<input
type="radio"
bind:group={range}
value={IntervalRange.Percentile999} />
99.9th percentile
99.9%
</label>
<label>
<input type="radio" bind:group={range} value={IntervalRange.All} />

View file

@ -5,9 +5,12 @@
import { defaultGraphBounds, RevlogRange } from "./graphs";
import { GraphData, gatherData, renderReviews, ReviewRange } from "./reviews";
import pb from "../backend/proto";
import { timeSpan, MONTH, YEAR } from "../time";
import { I18n } from "../i18n";
export let sourceData: pb.BackendProto.GraphsOut | null = null;
export let revlogRange: RevlogRange = RevlogRange.Month;
export let i18n: I18n;
let graphData: GraphData | null = null;
@ -39,6 +42,10 @@
$: if (graphData) {
renderReviews(svg as SVGElement, bounds, graphData, range, showTime);
}
const month = timeSpan(i18n, 1 * MONTH);
const month3 = timeSpan(i18n, 3 * MONTH);
const year = timeSpan(i18n, 1 * YEAR);
</script>
<div class="graph">
@ -53,15 +60,15 @@
{#if revlogRange >= RevlogRange.Year}
<label>
<input type="radio" bind:group={range} value={ReviewRange.Month} />
Month
{month}
</label>
<label>
<input type="radio" bind:group={range} value={ReviewRange.Quarter} />
3 months
{month3}
</label>
<label>
<input type="radio" bind:group={range} value={ReviewRange.Year} />
Year
{year}
</label>
{/if}
{#if revlogRange === RevlogRange.All}

View file

@ -3,12 +3,12 @@
import { I18n } from "./i18n";
const SECOND = 1.0;
const MINUTE = 60.0 * SECOND;
const HOUR = 60.0 * MINUTE;
const DAY = 24.0 * HOUR;
const MONTH = 30.0 * DAY;
const YEAR = 12.0 * MONTH;
export const SECOND = 1.0;
export const MINUTE = 60.0 * SECOND;
export const HOUR = 60.0 * MINUTE;
export const DAY = 24.0 * HOUR;
export const MONTH = 30.0 * DAY;
export const YEAR = 12.0 * MONTH;
enum TimespanUnit {
Seconds,
@ -70,6 +70,15 @@ function unitAmount(unit: TimespanUnit, secs: number): number {
}
}
function unitAmountRounded(unit: TimespanUnit, secs: number): number {
const value = unitAmount(unit, secs);
if (unit === TimespanUnit.Seconds || unit === TimespanUnit.Days) {
return Math.round(value);
} else {
return value;
}
}
export function studiedToday(i18n: I18n, cards: number, secs: number): string {
const unit = naturalUnit(secs);
const amount = unitAmount(unit, secs);
@ -86,3 +95,40 @@ export function studiedToday(i18n: I18n, cards: number, secs: number): string {
"secs-per-card": secsPer,
});
}
/// Describe the given seconds using the largest appropriate unit.
/// If precise is true, show to two decimal places, eg
/// eg 70 seconds -> "1.17 minutes"
/// If false, seconds and days are shown without decimals.
export function timeSpan(i18n: I18n, seconds: number, precise = true): string {
const unit = naturalUnit(seconds);
let amount: number;
if (precise) {
amount = unitAmount(unit, seconds);
} else {
amount = unitAmountRounded(unit, seconds);
}
let key: number;
switch (unit) {
case TimespanUnit.Seconds:
key = i18n.TR.SCHEDULING_TIME_SPAN_SECONDS;
break;
case TimespanUnit.Minutes:
key = i18n.TR.SCHEDULING_TIME_SPAN_MINUTES;
break;
case TimespanUnit.Hours:
key = i18n.TR.SCHEDULING_TIME_SPAN_HOURS;
break;
case TimespanUnit.Days:
key = i18n.TR.SCHEDULING_TIME_SPAN_DAYS;
break;
case TimespanUnit.Months:
key = i18n.TR.SCHEDULING_TIME_SPAN_MONTHS;
break;
case TimespanUnit.Years:
key = i18n.TR.SCHEDULING_TIME_SPAN_YEARS;
break;
}
return i18n.tr(key, { amount });
}