Solved a bug with calculations of the stats page

This commit is contained in:
Tiago Ribeiro
2024-01-17 11:59:40 +00:00
parent 7a577a7ca2
commit a646955493
2 changed files with 60 additions and 196 deletions

View File

@@ -139,9 +139,9 @@ export default function Stats() {
}
}, [startDate, endDate]);
const calculateTotalScore = (stats: Stat[]) => {
const calculateTotalScore = (stats: Stat[], divisionFactor: number) => {
const moduleScores = calculateModuleScore(stats);
return moduleScores.reduce((acc, curr) => acc + curr.score, 0) / 4;
return moduleScores.reduce((acc, curr) => acc + curr.score, 0) / divisionFactor;
};
const calculateScorePerModule = (stats: Stat[], module: Module) => {
@@ -278,7 +278,10 @@ export default function Stats() {
</span>
<span className="px-2">
Level{" "}
{calculateTotalScore(stats.filter((s) => timestampToMoment(s).isBefore(date))).toFixed(1)}
{calculateTotalScore(
stats.filter((s) => timestampToMoment(s).isBefore(date)),
5,
).toFixed(1)}
</span>
</div>
) : null;
@@ -364,6 +367,7 @@ export default function Stats() {
return date.isValid()
? calculateTotalScore(
stats.filter((s) => timestampToMoment(s).isBefore(date)),
5,
).toFixed(1)
: undefined;
})
@@ -599,188 +603,47 @@ export default function Stats() {
}}
/>
<div className="flex -md:flex-col -md:items-center gap-4 flex-wrap">
{/* Reading Score Band in Interval */}
<div className="w-full md:max-w-2xl border border-mti-gray-platinum p-4 pb-12 rounded-xl h-fit md:h-96">
<span className="text-sm font-bold">Reading Score Band in Interval</span>
<Chart
options={{
scales: {
y: {
min: 0,
max: 9,
{/* Module Score Band in Interval */}
{MODULE_ARRAY.map((module, index) => (
<div
className="w-full md:max-w-2xl border border-mti-gray-platinum p-4 pb-12 rounded-xl h-fit md:h-96"
key={module}>
<span className="text-sm font-bold">{capitalize(module)} Score Band in Interval</span>
<Chart
options={{
scales: {
y: {
min: 0,
max: 9,
},
},
},
}}
type="line"
data={{
labels: intervalDates.map((date) => moment(date).format("DD/MM/YYYY")),
datasets: [
{
type: "line",
label: "Reading",
fill: false,
borderColor: COLORS[0],
backgroundColor: COLORS[0],
borderWidth: 2,
spanGaps: true,
data: intervalDates.map((date) => {
return calculateTotalScore(
stats.filter(
(s) => timestampToMoment(s).isBefore(date) && s.module === "reading",
),
).toFixed(1);
}),
},
],
}}
/>
</div>
{/* Listening Score Band in Interval */}
<div className="w-full md:max-w-2xl border border-mti-gray-platinum p-4 pb-12 rounded-xl h-fit md:h-96">
<span className="text-sm font-bold">Listening Score Band in Interval</span>
<Chart
options={{
scales: {
y: {
min: 0,
max: 9,
},
},
}}
type="line"
data={{
labels: intervalDates.map((date) => moment(date).format("DD/MM/YYYY")),
datasets: [
{
type: "line",
label: "Listening",
fill: false,
borderColor: COLORS[1],
backgroundColor: COLORS[1],
borderWidth: 2,
spanGaps: true,
data: intervalDates.map((date) => {
return calculateTotalScore(
stats.filter(
(s) => timestampToMoment(s).isBefore(date) && s.module === "listening",
),
).toFixed(1);
}),
},
],
}}
/>
</div>
{/* Writing Score Band in Interval */}
<div className="w-full md:max-w-2xl border border-mti-gray-platinum p-4 pb-12 rounded-xl h-fit md:h-96">
<span className="text-sm font-bold">Writing Score Band in Interval</span>
<Chart
options={{
scales: {
y: {
min: 0,
max: 9,
},
},
}}
type="line"
data={{
labels: intervalDates.map((date) => moment(date).format("DD/MM/YYYY")),
datasets: [
{
type: "line",
label: "Writing",
fill: false,
borderColor: COLORS[2],
backgroundColor: COLORS[2],
borderWidth: 2,
spanGaps: true,
data: intervalDates.map((date) => {
return calculateTotalScore(
stats.filter(
(s) => timestampToMoment(s).isBefore(date) && s.module === "writing",
),
).toFixed(1);
}),
},
],
}}
/>
</div>
{/* Speaking Score Band in Interval */}
<div className="w-full md:max-w-2xl border border-mti-gray-platinum p-4 pb-12 rounded-xl h-fit md:h-96">
<span className="text-sm font-bold">Speaking Score Band in Interval</span>
<Chart
options={{
scales: {
y: {
min: 0,
max: 9,
},
},
}}
type="line"
data={{
labels: intervalDates.map((date) => moment(date).format("DD/MM/YYYY")),
datasets: [
{
type: "line",
label: "Speaking",
fill: false,
borderColor: COLORS[3],
backgroundColor: COLORS[3],
borderWidth: 2,
spanGaps: true,
data: intervalDates.map((date) => {
return calculateTotalScore(
stats.filter(
(s) => timestampToMoment(s).isBefore(date) && s.module === "speaking",
),
).toFixed(1);
}),
},
],
}}
/>
</div>
{/* Level Score Band in Interval */}
<div className="w-full md:max-w-2xl border border-mti-gray-platinum p-4 pb-12 rounded-xl h-fit md:h-96">
<span className="text-sm font-bold">Level Score Band in Interval</span>
<Chart
options={{
scales: {
y: {
min: 0,
max: 9,
},
},
}}
type="line"
data={{
labels: intervalDates.map((date) => moment(date).format("DD/MM/YYYY")),
datasets: [
{
type: "line",
label: "Level",
fill: false,
borderColor: COLORS[4],
backgroundColor: COLORS[4],
borderWidth: 2,
spanGaps: true,
data: intervalDates.map((date) => {
return calculateTotalScore(
stats.filter((s) => timestampToMoment(s).isBefore(date) && s.module === "level"),
).toFixed(1);
}),
},
],
}}
/>
</div>
}}
type="line"
data={{
labels: intervalDates.map((date) => moment(date).format("DD/MM/YYYY")),
datasets: [
{
type: "line",
label: capitalize(module),
fill: false,
borderColor: COLORS[index],
backgroundColor: COLORS[index],
borderWidth: 2,
spanGaps: true,
data: intervalDates.map((date) => {
return calculateTotalScore(
stats.filter(
(s) => timestampToMoment(s).isBefore(date) && s.module === module,
),
1,
).toFixed(1);
}),
},
],
}}
/>
</div>
))}
</div>
</div>
</>

View File

@@ -1,5 +1,5 @@
import {Module} from "@/interfaces";
import { LevelScore } from "@/constants/ielts";
import {LevelScore} from "@/constants/ielts";
type Type = "academic" | "general";
@@ -96,7 +96,7 @@ const academicMarking: {[key: number]: number} = {
const levelMarking: {[key: number]: number} = {
88: 9, // Advanced
64: 8 , // Upper-Intermediate
64: 8, // Upper-Intermediate
52: 6, // Intermediate
32: 4, // Pre-Intermediate
16: 2, // Elementary
@@ -142,23 +142,24 @@ export const calculateBandScore = (correct: number, total: number, module: Modul
};
export const calculateAverageLevel = (levels: {[key in Module]: number}) => {
return Object.keys(levels).reduce((accumulator, current) => levels[current as Module] + accumulator, 0) / 4;
return Object.keys(levels).reduce((accumulator, current) => levels[current as Module] + accumulator, 0) / 5;
};
export const getLevelScore = (level: number) => {
switch(level) {
switch (level) {
case 0:
return ['Beginner', 'Low A1'];
return ["Beginner", "Low A1"];
case 2:
return ['Elementary', 'High A1/Low A2'];
return ["Elementary", "High A1/Low A2"];
case 4:
return ['Pre-Intermediate', 'High A2/Low B1'];
return ["Pre-Intermediate", "High A2/Low B1"];
case 6:
return ['Intermediate', 'High B1/Low B2'];
return ["Intermediate", "High B1/Low B2"];
case 8:
return ['Upper-Intermediate', 'High B2/Low C1'];
return ["Upper-Intermediate", "High B2/Low C1"];
case 9:
return ['Advanced', 'C1'];
default: return [];
return ["Advanced", "C1"];
default:
return [];
}
}
};