diff --git a/ts/src/stats/buttons.ts b/ts/src/stats/buttons.ts
index e0bc18444..e761c521b 100644
--- a/ts/src/stats/buttons.ts
+++ b/ts/src/stats/buttons.ts
@@ -15,6 +15,7 @@ import { axisBottom, axisLeft } from "d3-axis";
import { showTooltip, hideTooltip } from "./tooltip";
import { GraphBounds, setDataAvailable } from "./graphs";
import { I18n } from "../i18n";
+import { sum } from "d3-array";
type ButtonCounts = [number, number, number, number];
@@ -62,12 +63,20 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData {
return { learning, young, mature };
}
+type GroupKind = "learning" | "young" | "mature";
+
interface Datum {
- buttonNum: string;
- group: "learning" | "young" | "mature";
+ buttonNum: number;
+ group: GroupKind;
count: number;
}
+interface TotalCorrect {
+ total: number;
+ correct: number;
+ percent: string;
+}
+
export function renderButtons(
svgElem: SVGElement,
bounds: GraphBounds,
@@ -77,27 +86,38 @@ export function renderButtons(
const data = [
...sourceData.learning.map((count: number, idx: number) => {
return {
- buttonNum: (idx + 1).toString(),
+ buttonNum: idx + 1,
group: "learning",
count,
} as Datum;
}),
...sourceData.young.map((count: number, idx: number) => {
return {
- buttonNum: (idx + 1).toString(),
+ buttonNum: idx + 1,
group: "young",
count,
} as Datum;
}),
...sourceData.mature.map((count: number, idx: number) => {
return {
- buttonNum: (idx + 1).toString(),
+ buttonNum: idx + 1,
group: "mature",
count,
} as Datum;
}),
];
+ const totalCorrect = (kind: GroupKind): TotalCorrect => {
+ const groupData = data.filter((d) => d.group == kind);
+ const total = sum(groupData, (d) => d.count);
+ const correct = sum(
+ groupData.filter((d) => d.buttonNum > 1),
+ (d) => d.count
+ );
+ const percent = total ? ((correct / total) * 100).toFixed(2) : "0";
+ return { total, correct, percent };
+ };
+
const yMax = Math.max(...data.map((d) => d.count));
const svg = select(svgElem);
@@ -117,17 +137,21 @@ export function renderButtons(
.transition(trans)
.call(
axisBottom(xGroup)
- .tickFormat(((d: string) => {
+ .tickFormat(((d: GroupKind) => {
+ let kind: string;
switch (d) {
case "learning":
- return i18n.tr(i18n.TR.STATISTICS_COUNTS_LEARNING_CARDS);
+ kind = i18n.tr(i18n.TR.STATISTICS_COUNTS_LEARNING_CARDS);
+ break;
case "young":
- return i18n.tr(i18n.TR.STATISTICS_COUNTS_YOUNG_CARDS);
+ kind = i18n.tr(i18n.TR.STATISTICS_COUNTS_YOUNG_CARDS);
+ break;
case "mature":
- return i18n.tr(i18n.TR.STATISTICS_COUNTS_MATURE_CARDS);
default:
- console.log(d);
+ kind = i18n.tr(i18n.TR.STATISTICS_COUNTS_MATURE_CARDS);
+ break;
}
+ return `${kind} (${totalCorrect(d).percent}%)`;
}) as any)
.tickSizeOuter(0)
);
@@ -169,10 +193,13 @@ export function renderButtons(
}
})
.transition(trans)
- .attr("x", (d: Datum) => xGroup(d.group)! + xButton(d.buttonNum)!)
+ .attr(
+ "x",
+ (d: Datum) => xGroup(d.group)! + xButton(d.buttonNum.toString())!
+ )
.attr("y", (d: Datum) => y(d.count)!)
.attr("height", (d: Datum) => y(0) - y(d.count))
- .attr("fill", (d: Datum) => colour(parseInt(d.buttonNum)));
+ .attr("fill", (d: Datum) => colour(d.buttonNum));
};
svg.select("g.bars")
@@ -183,7 +210,11 @@ export function renderButtons(
enter
.append("rect")
.attr("rx", 1)
- .attr("x", (d: Datum) => xGroup(d.group)! + xButton(d.buttonNum)!)
+ .attr(
+ "x",
+ (d: Datum) =>
+ xGroup(d.group)! + xButton(d.buttonNum.toString())!
+ )
.attr("y", y(0))
.attr("height", 0)
.call(updateBar),
@@ -199,14 +230,18 @@ export function renderButtons(
function tooltipText(d: Datum): string {
const button = i18n.tr(i18n.TR.STATISTICS_ANSWER_BUTTONS_BUTTON_NUMBER);
const timesPressed = i18n.tr(i18n.TR.STATISTICS_ANSWER_BUTTONS_BUTTON_PRESSED);
- return `${button}: ${d.buttonNum}
${timesPressed}: ${d.count}`;
+ const correctStr = i18n.tr(
+ i18n.TR.STATISTICS_HOURS_CORRECT,
+ totalCorrect(d.group)
+ );
+ return `${button}: ${d.buttonNum}
${timesPressed}: ${d.count}
${correctStr}`;
}
svg.select("g.hoverzone")
.selectAll("rect")
.data(data)
.join("rect")
- .attr("x", (d: Datum) => xGroup(d.group)! + xButton(d.buttonNum)!)
+ .attr("x", (d: Datum) => xGroup(d.group)! + xButton(d.buttonNum.toString())!)
.attr("y", () => y(yMax!))
.attr("width", xButton.bandwidth())
.attr("height", () => y(0) - y(yMax!))