average ease + add % to ease ticks

This commit is contained in:
Damien Elmes 2020-08-21 12:58:02 +10:00
parent 2a8a4e9780
commit 98a0753eb8
4 changed files with 48 additions and 18 deletions

View file

@ -183,15 +183,19 @@ statistics-due-tomorrow = Due tomorrow
# eg 5 of 15 (33.3%) # eg 5 of 15 (33.3%)
statistics-amount-of-total-with-percentage = { $amount } of { $total } ({ $percent }%) statistics-amount-of-total-with-percentage = { $amount } of { $total } ({ $percent }%)
statistics-average-over-period = Average over period statistics-average-over-period = Average over period
statistics-reviews-per-day = { $count -> statistics-reviews-per-day =
{ $count ->
[one] { $count } review/day [one] { $count } review/day
*[other] { $count } reviews/day *[other] { $count } reviews/day
} }
statistics-minutes-per-day = { $count -> statistics-minutes-per-day =
{ $count ->
[one] { $count } minute/day [one] { $count } minute/day
*[other] { $count } minutes/day *[other] { $count } minutes/day
} }
statistics-cards-per-day = { $count -> statistics-cards-per-day =
{ $count ->
[one] { $count } card/day [one] { $count } card/day
*[other] { $count } cards/day *[other] { $count } cards/day
} }
statistics-average-ease = Average ease

View file

@ -4,14 +4,17 @@
import pb from "../backend/proto"; import pb from "../backend/proto";
import HistogramGraph from "./HistogramGraph.svelte"; import HistogramGraph from "./HistogramGraph.svelte";
import { I18n } from "../i18n"; import { I18n } from "../i18n";
import { TableDatum } from "./graphs";
import TableData from "./TableData.svelte";
export let sourceData: pb.BackendProto.GraphsOut | null = null; export let sourceData: pb.BackendProto.GraphsOut | null = null;
export let i18n: I18n; export let i18n: I18n;
let histogramData = null as HistogramData | null; let histogramData = null as HistogramData | null;
let tableData: TableDatum[] = [];
$: if (sourceData) { $: if (sourceData) {
histogramData = prepareData(gatherData(sourceData), i18n); [histogramData, tableData] = prepareData(gatherData(sourceData), i18n);
} }
const title = i18n.tr(i18n.TR.STATISTICS_CARD_EASE_TITLE); const title = i18n.tr(i18n.TR.STATISTICS_CARD_EASE_TITLE);
@ -24,4 +27,6 @@
<div class="subtitle">{subtitle}</div> <div class="subtitle">{subtitle}</div>
<HistogramGraph data={histogramData} {i18n} /> <HistogramGraph data={histogramData} {i18n} />
<TableData {i18n} {tableData} />
</div> </div>

View file

@ -7,12 +7,13 @@
*/ */
import pb from "../backend/proto"; import pb from "../backend/proto";
import { extent, histogram } from "d3-array"; import { extent, histogram, sum } from "d3-array";
import { scaleLinear, scaleSequential } from "d3-scale"; import { scaleLinear, scaleSequential } from "d3-scale";
import { CardQueue } from "../cards"; import { CardQueue } from "../cards";
import { HistogramData } from "./histogram-graph"; import { HistogramData } from "./histogram-graph";
import { interpolateRdYlGn } from "d3-scale-chromatic"; import { interpolateRdYlGn } from "d3-scale-chromatic";
import { I18n } from "../i18n"; import { I18n } from "../i18n";
import { TableDatum } from "./graphs";
export interface GraphData { export interface GraphData {
eases: number[]; eases: number[];
@ -25,11 +26,14 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData {
return { eases }; return { eases };
} }
export function prepareData(data: GraphData, i18n: I18n): HistogramData | null { export function prepareData(
data: GraphData,
i18n: I18n
): [HistogramData | null, TableDatum[]] {
// get min/max // get min/max
const allEases = data.eases; const allEases = data.eases;
if (!allEases.length) { if (!allEases.length) {
return null; return [null, []];
} }
const total = allEases.length; const total = allEases.length;
const [_xMin, origXMax] = extent(allEases); const [_xMin, origXMax] = extent(allEases);
@ -57,5 +61,16 @@ export function prepareData(data: GraphData, i18n: I18n): HistogramData | null {
}); });
} }
return { scale, bins, total, hoverText, colourScale, showArea: false }; const xTickFormat = (num: number): string => `${num.toFixed(0)}%`;
const tableData = [
{
label: i18n.tr(i18n.TR.STATISTICS_AVERAGE_EASE),
value: xTickFormat(sum(allEases) / total),
},
];
return [
{ scale, bins, total, hoverText, colourScale, showArea: false, xTickFormat },
tableData,
];
} }

View file

@ -28,6 +28,7 @@ export interface HistogramData {
showArea: boolean; showArea: boolean;
colourScale: ScaleSequential<string>; colourScale: ScaleSequential<string>;
binValue?: (bin: Bin<any, any>) => number; binValue?: (bin: Bin<any, any>) => number;
xTickFormat?: (d: any) => string;
} }
export function histogramGraph( export function histogramGraph(
@ -50,7 +51,12 @@ export function histogramGraph(
const x = data.scale.range([bounds.marginLeft, bounds.width - bounds.marginRight]); const x = data.scale.range([bounds.marginLeft, bounds.width - bounds.marginRight]);
svg.select<SVGGElement>(".x-ticks") svg.select<SVGGElement>(".x-ticks")
.transition(trans) .transition(trans)
.call(axisBottom(x).ticks(7).tickSizeOuter(0)); .call(
axisBottom(x)
.ticks(7)
.tickSizeOuter(0)
.tickFormat((data.xTickFormat ?? null) as any)
);
// y scale // y scale