mirror of
https://github.com/ankitects/anki.git
synced 2025-11-10 14:47:12 -05:00
show total correct in answer buttons graph
This commit is contained in:
parent
0d287330c3
commit
aa45d4add6
1 changed files with 50 additions and 15 deletions
|
|
@ -15,6 +15,7 @@ import { axisBottom, axisLeft } from "d3-axis";
|
||||||
import { showTooltip, hideTooltip } from "./tooltip";
|
import { showTooltip, hideTooltip } from "./tooltip";
|
||||||
import { GraphBounds, setDataAvailable } from "./graphs";
|
import { GraphBounds, setDataAvailable } from "./graphs";
|
||||||
import { I18n } from "../i18n";
|
import { I18n } from "../i18n";
|
||||||
|
import { sum } from "d3-array";
|
||||||
|
|
||||||
type ButtonCounts = [number, number, number, number];
|
type ButtonCounts = [number, number, number, number];
|
||||||
|
|
||||||
|
|
@ -62,12 +63,20 @@ export function gatherData(data: pb.BackendProto.GraphsOut): GraphData {
|
||||||
return { learning, young, mature };
|
return { learning, young, mature };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GroupKind = "learning" | "young" | "mature";
|
||||||
|
|
||||||
interface Datum {
|
interface Datum {
|
||||||
buttonNum: string;
|
buttonNum: number;
|
||||||
group: "learning" | "young" | "mature";
|
group: GroupKind;
|
||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TotalCorrect {
|
||||||
|
total: number;
|
||||||
|
correct: number;
|
||||||
|
percent: string;
|
||||||
|
}
|
||||||
|
|
||||||
export function renderButtons(
|
export function renderButtons(
|
||||||
svgElem: SVGElement,
|
svgElem: SVGElement,
|
||||||
bounds: GraphBounds,
|
bounds: GraphBounds,
|
||||||
|
|
@ -77,27 +86,38 @@ export function renderButtons(
|
||||||
const data = [
|
const data = [
|
||||||
...sourceData.learning.map((count: number, idx: number) => {
|
...sourceData.learning.map((count: number, idx: number) => {
|
||||||
return {
|
return {
|
||||||
buttonNum: (idx + 1).toString(),
|
buttonNum: idx + 1,
|
||||||
group: "learning",
|
group: "learning",
|
||||||
count,
|
count,
|
||||||
} as Datum;
|
} as Datum;
|
||||||
}),
|
}),
|
||||||
...sourceData.young.map((count: number, idx: number) => {
|
...sourceData.young.map((count: number, idx: number) => {
|
||||||
return {
|
return {
|
||||||
buttonNum: (idx + 1).toString(),
|
buttonNum: idx + 1,
|
||||||
group: "young",
|
group: "young",
|
||||||
count,
|
count,
|
||||||
} as Datum;
|
} as Datum;
|
||||||
}),
|
}),
|
||||||
...sourceData.mature.map((count: number, idx: number) => {
|
...sourceData.mature.map((count: number, idx: number) => {
|
||||||
return {
|
return {
|
||||||
buttonNum: (idx + 1).toString(),
|
buttonNum: idx + 1,
|
||||||
group: "mature",
|
group: "mature",
|
||||||
count,
|
count,
|
||||||
} as Datum;
|
} 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 yMax = Math.max(...data.map((d) => d.count));
|
||||||
|
|
||||||
const svg = select(svgElem);
|
const svg = select(svgElem);
|
||||||
|
|
@ -117,17 +137,21 @@ export function renderButtons(
|
||||||
.transition(trans)
|
.transition(trans)
|
||||||
.call(
|
.call(
|
||||||
axisBottom(xGroup)
|
axisBottom(xGroup)
|
||||||
.tickFormat(((d: string) => {
|
.tickFormat(((d: GroupKind) => {
|
||||||
|
let kind: string;
|
||||||
switch (d) {
|
switch (d) {
|
||||||
case "learning":
|
case "learning":
|
||||||
return i18n.tr(i18n.TR.STATISTICS_COUNTS_LEARNING_CARDS);
|
kind = i18n.tr(i18n.TR.STATISTICS_COUNTS_LEARNING_CARDS);
|
||||||
|
break;
|
||||||
case "young":
|
case "young":
|
||||||
return i18n.tr(i18n.TR.STATISTICS_COUNTS_YOUNG_CARDS);
|
kind = i18n.tr(i18n.TR.STATISTICS_COUNTS_YOUNG_CARDS);
|
||||||
|
break;
|
||||||
case "mature":
|
case "mature":
|
||||||
return i18n.tr(i18n.TR.STATISTICS_COUNTS_MATURE_CARDS);
|
|
||||||
default:
|
default:
|
||||||
console.log(d);
|
kind = i18n.tr(i18n.TR.STATISTICS_COUNTS_MATURE_CARDS);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
return `${kind} (${totalCorrect(d).percent}%)`;
|
||||||
}) as any)
|
}) as any)
|
||||||
.tickSizeOuter(0)
|
.tickSizeOuter(0)
|
||||||
);
|
);
|
||||||
|
|
@ -169,10 +193,13 @@ export function renderButtons(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.transition(trans)
|
.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("y", (d: Datum) => y(d.count)!)
|
||||||
.attr("height", (d: Datum) => y(0) - 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")
|
svg.select("g.bars")
|
||||||
|
|
@ -183,7 +210,11 @@ export function renderButtons(
|
||||||
enter
|
enter
|
||||||
.append("rect")
|
.append("rect")
|
||||||
.attr("rx", 1)
|
.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("y", y(0))
|
||||||
.attr("height", 0)
|
.attr("height", 0)
|
||||||
.call(updateBar),
|
.call(updateBar),
|
||||||
|
|
@ -199,14 +230,18 @@ export function renderButtons(
|
||||||
function tooltipText(d: Datum): string {
|
function tooltipText(d: Datum): string {
|
||||||
const button = i18n.tr(i18n.TR.STATISTICS_ANSWER_BUTTONS_BUTTON_NUMBER);
|
const button = i18n.tr(i18n.TR.STATISTICS_ANSWER_BUTTONS_BUTTON_NUMBER);
|
||||||
const timesPressed = i18n.tr(i18n.TR.STATISTICS_ANSWER_BUTTONS_BUTTON_PRESSED);
|
const timesPressed = i18n.tr(i18n.TR.STATISTICS_ANSWER_BUTTONS_BUTTON_PRESSED);
|
||||||
return `${button}: ${d.buttonNum}<br>${timesPressed}: ${d.count}`;
|
const correctStr = i18n.tr(
|
||||||
|
i18n.TR.STATISTICS_HOURS_CORRECT,
|
||||||
|
totalCorrect(d.group)
|
||||||
|
);
|
||||||
|
return `${button}: ${d.buttonNum}<br>${timesPressed}: ${d.count}<br>${correctStr}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg.select("g.hoverzone")
|
svg.select("g.hoverzone")
|
||||||
.selectAll("rect")
|
.selectAll("rect")
|
||||||
.data(data)
|
.data(data)
|
||||||
.join("rect")
|
.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("y", () => y(yMax!))
|
||||||
.attr("width", xButton.bandwidth())
|
.attr("width", xButton.bandwidth())
|
||||||
.attr("height", () => y(0) - y(yMax!))
|
.attr("height", () => y(0) - y(yMax!))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue