Skip to content

Commit 67d9c92

Browse files
committed
feat: display reading speed on analytics dashboard
1 parent c7f7c45 commit 67d9c92

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

pom-dependency-tree.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ai.elimu:webapp:war:2.6.32-SNAPSHOT
1+
ai.elimu:webapp:war:2.6.34-SNAPSHOT
22
+- ai.elimu:model:jar:model-2.0.97:compile
33
| \- com.google.code.gson:gson:jar:2.13.0:compile
44
| \- com.google.errorprone:error_prone_annotations:jar:2.37.0:compile

src/main/java/ai/elimu/web/analytics/students/StudentController.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,38 @@ public String handleRequest(@PathVariable Long studentId, Model model) {
143143
}
144144
model.addAttribute("wordAssessmentEventCorrectCountList", wordAssessmentEventCorrectCountList);
145145
model.addAttribute("wordAssessmentEventIncorrectCountList", wordAssessmentEventIncorrectCountList);
146+
147+
// Prepare chart data - Reading speed (words per minute)
148+
List<Double> readingSpeedAvgList = new ArrayList<>();
149+
if (!wordAssessmentEvents.isEmpty()) {
150+
Map<String, Integer> eventCountByWeekMap = new HashMap<>();
151+
Map<String, Long> timeSpentMsSumByWeekMap = new HashMap<>();
152+
for (WordAssessmentEvent event : wordAssessmentEvents) {
153+
String eventWeek = simpleDateFormat.format(event.getTimestamp().getTime());
154+
if (event.getMasteryScore() >= 0.5) {
155+
eventCountByWeekMap.put(eventWeek, eventCountByWeekMap.getOrDefault(eventWeek, 0) + 1);
156+
timeSpentMsSumByWeekMap.put(eventWeek, eventCountByWeekMap.getOrDefault(eventWeek, 0) + event.getTimeSpentMs());
157+
}
158+
}
159+
week = (Calendar) calendar6MonthsAgo.clone();
160+
while (!week.after(calendarNow)) {
161+
String weekAsString = simpleDateFormat.format(week.getTime());
162+
Integer wordsReadCount = eventCountByWeekMap.getOrDefault(weekAsString, 0);
163+
log.info("wordsReadCount: " + wordsReadCount);
164+
Long timeSpentMsSum = timeSpentMsSumByWeekMap.getOrDefault(weekAsString, 0L);
165+
log.info("timeSpentMsSum: " + timeSpentMsSum);
166+
Double timeSpentInMinutes = (double) (timeSpentMsSum / 1_000);
167+
log.info("timeSpentInMinutes: " + timeSpentInMinutes);
168+
Double wordsPerMinute = 0.00;
169+
if (timeSpentInMinutes > 0) {
170+
wordsPerMinute = wordsReadCount / timeSpentInMinutes;
171+
log.info("wordsPerMinute: " + wordsPerMinute);
172+
}
173+
readingSpeedAvgList.add(wordsPerMinute);
174+
week.add(Calendar.WEEK_OF_YEAR, 1);
175+
}
176+
}
177+
model.addAttribute("readingSpeedAvgList", readingSpeedAvgList);
146178

147179
// Prepare chart data - WordLearningEvents
148180
List<WordLearningEvent> wordLearningEvents = wordLearningEventDao.readAll(student.getAndroidId());

src/main/webapp/WEB-INF/jsp/analytics/students/id.jsp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,34 @@
202202

203203
<h5 style="margin-top: 1em;">🔤 Words</h5>
204204
<div class="card-panel">
205+
<h5>Reading speed (correct words per minute)</h5>
206+
<canvas id="readingSpeedChart"></canvas>
207+
<script>
208+
const readingSpeedLabels = [
209+
<c:forEach var="week" items="${weekList}">'${week}',</c:forEach>
210+
];
211+
const readingSpeedData = {
212+
labels: readingSpeedLabels,
213+
datasets: [{
214+
data: <c:out value="${readingSpeedAvgList}" />,
215+
label: 'cwpm',
216+
backgroundColor: 'rgba(100,181,246, 0.5)', // #64b5f6 blue lighten-2
217+
borderColor: 'rgba(100,181,246, 0.5)', // #64b5f6 blue lighten-2
218+
tension: 0.5,
219+
fill: true
220+
}]
221+
};
222+
const readingSpeedConfig = {
223+
type: 'line',
224+
data: readingSpeedData,
225+
options: {}
226+
};
227+
var readingSpeedCtx = document.getElementById('readingSpeedChart');
228+
new Chart(readingSpeedCtx, readingSpeedConfig);
229+
</script>
230+
231+
<div class="divider" style="margin: 2em 0;"></div>
232+
205233
<a id="exportWordAssessmentEventsToCsvButton" class="right btn waves-effect waves-light grey-text white"
206234
href="<spring:url value='/analytics/students/${student.id}/word-assessment-events.csv' />">
207235
Export to CSV<i class="material-icons right">vertical_align_bottom</i>

0 commit comments

Comments
 (0)