Index: lams_tool_assessment/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r7f00c08c54ad8e6bfc47ea24d69008e5bd2af46f -r36716004da333fcc5eb3f776801e3e5278719fd7 --- lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 7f00c08c54ad8e6bfc47ea24d69008e5bd2af46f) +++ lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 36716004da333fcc5eb3f776801e3e5278719fd7) @@ -151,6 +151,9 @@ label.monitoring.summary.completion.possible = Not started label.monitoring.summary.completion.started = In progress label.monitoring.summary.completion.completed = Completed +label.monitoring.summary.answered.questions = Answered questions +label.monitoring.summary.answered.questions.x.axis = Number of answered questions +label.monitoring.summary.answered.questions.y.axis = Number of students label.monitoring.user.summary.history.responses = History of responses label.monitoring.user.summary.user.name = Username label.monitoring.user.summary.number.attempts = Number of attempts Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/AssessmentResultDAO.java =================================================================== diff -u -r5b3b4fd2df1de75d853c5fb9dcf9f02eb2a5ca5a -r36716004da333fcc5eb3f776801e3e5278719fd7 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/AssessmentResultDAO.java (.../AssessmentResultDAO.java) (revision 5b3b4fd2df1de75d853c5fb9dcf9f02eb2a5ca5a) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/AssessmentResultDAO.java (.../AssessmentResultDAO.java) (revision 36716004da333fcc5eb3f776801e3e5278719fd7) @@ -23,6 +23,7 @@ package org.lamsfoundation.lams.tool.assessment.dao; import java.util.List; +import java.util.Map; import org.lamsfoundation.lams.tool.assessment.dto.AssessmentUserDTO; import org.lamsfoundation.lams.tool.assessment.model.AssessmentResult; @@ -103,4 +104,6 @@ * Count how many last finished attempts selected specified option. */ int countAttemptsPerOption(Long toolContentId, Long optionUid); + + Map countAnsweredQuestionsByUsers(long toolContentId); } \ No newline at end of file Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java =================================================================== diff -u -r5b3b4fd2df1de75d853c5fb9dcf9f02eb2a5ca5a -r36716004da333fcc5eb3f776801e3e5278719fd7 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision 5b3b4fd2df1de75d853c5fb9dcf9f02eb2a5ca5a) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision 36716004da333fcc5eb3f776801e3e5278719fd7) @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import org.hibernate.query.NativeQuery; import org.hibernate.query.Query; @@ -105,6 +107,24 @@ private static final String FIND_BY_UID = "FROM " + AssessmentResult.class.getName() + " AS r WHERE r.uid = ?"; + private static final String ANSWERED_QUESTIONS_BY_USER_COUNT = "" + + "SELECT answered_question_count, COUNT(user_uid) AS user_count FROM " + + " (SELECT user_uid, " + + " SUM(IF(answer_boolean = 1 OR (answer IS NOT NULL AND TRIM(answer) <> ''), 1, 0)) AS answered_question_count FROM" + + " (SELECT ar.user_uid, oa.question_result_uid, oa.answer_boolean, qba.answer" + + " FROM tl_laasse10_assessment AS a" + + " JOIN tl_laasse10_assessment_result AS ar ON a.uid = ar.assessment_uid" + + " LEFT JOIN tl_laasse10_question_result AS qr ON ar.uid = qr.result_uid" + + " LEFT JOIN lams_qb_tool_answer AS qba ON qba.answer_uid = qr.uid" + + " LEFT JOIN tl_laasse10_option_answer AS oa ON oa.question_result_uid = qr.uid" + + " WHERE ar.latest = 1 " + + " AND (oa.answer_boolean IS NULL OR oa.answer_boolean = 1)" + + " AND a.content_id = :toolContentId " + + " GROUP BY oa.question_result_uid, ar.user_uid " + + " ) AS answered_questions " + + " GROUP BY user_uid) AS answered_questions_by_user_count " + + "GROUP BY answered_question_count "; + @Override @SuppressWarnings("unchecked") public List getAssessmentResults(Long assessmentUid, Long userId) { @@ -321,6 +341,18 @@ return query.uniqueResult().intValue(); } + @Override + @SuppressWarnings("unchecked") + public Map countAnsweredQuestionsByUsers(long toolContentId) { + Map answeredQuestions = new TreeMap<>(); + List results = getSession().createNativeQuery(ANSWERED_QUESTIONS_BY_USER_COUNT) + .setParameter("toolContentId", toolContentId).getResultList(); + for (Object[] result : results) { + answeredQuestions.put(((Number) result[0]).intValue(), ((Number) result[1]).intValue()); + } + return answeredQuestions; + } + private List convertResultsToAssessmentUserDTOList(List list) { List lastTotalScores = new ArrayList<>(); @@ -344,4 +376,4 @@ return lastTotalScores; } -} +} \ No newline at end of file Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r7f00c08c54ad8e6bfc47ea24d69008e5bd2af46f -r36716004da333fcc5eb3f776801e3e5278719fd7 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 7f00c08c54ad8e6bfc47ea24d69008e5bd2af46f) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 36716004da333fcc5eb3f776801e3e5278719fd7) @@ -3734,4 +3734,23 @@ Lesson lesson = lessonService.getLessonByToolContentId(toolContentId); return lessonService.getLessonLearners(lesson.getLessonId(), searchString, null, null, true); } + + @Override + public Map getCountAnsweredQuestionsByUsers(long toolContentId) { + Map answeredQuestions = assessmentResultDao.countAnsweredQuestionsByUsers(toolContentId); + if (answeredQuestions.isEmpty()) { + return answeredQuestions; + } + + Assessment assessment = getAssessmentByContentId(toolContentId); + int questionCount = assessment.getQuestions().size(); + + // list all question counts, from 0 to maximum possible questions + Map result = new HashMap<>(); + for (int i = 0; i <= questionCount; i++) { + result.put(i, 0); + } + result.putAll(answeredQuestions); + return result; + } } \ No newline at end of file Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -r5b3b4fd2df1de75d853c5fb9dcf9f02eb2a5ca5a -r36716004da333fcc5eb3f776801e3e5278719fd7 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 5b3b4fd2df1de75d853c5fb9dcf9f02eb2a5ca5a) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 36716004da333fcc5eb3f776801e3e5278719fd7) @@ -548,4 +548,6 @@ Grouping getGrouping(long toolContentId); List getPossibleIndividualTimeLimitUsers(long toolContentId, String searchString); + + Map getCountAnsweredQuestionsByUsers(long toolContentId); } \ No newline at end of file Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java =================================================================== diff -u -r3c6af4b3a8f2ceb9710a326997d5683d229d26cc -r36716004da333fcc5eb3f776801e3e5278719fd7 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 3c6af4b3a8f2ceb9710a326997d5683d229d26cc) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 36716004da333fcc5eb3f776801e3e5278719fd7) @@ -108,6 +108,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.util.HtmlUtils; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -236,13 +237,28 @@ request.setAttribute("questions", questionDtos); } - request.setAttribute("possibleLearners", service.getCountLessonLearnersByContentId(contentId)); - request.setAttribute("startedLearners", service.getCountUsersByContentId(contentId)); - request.setAttribute("completedLearners", service.getCountLearnersWithFinishedCurrentAttempt(contentId)); - return "pages/monitoring/monitoring"; } + @RequestMapping(path = "/getCompletionChartsData") + @ResponseBody + public String getCompletionChartsData(@RequestParam long toolContentId, HttpServletResponse response) + throws JsonProcessingException, IOException { + ObjectNode chartJson = JsonNodeFactory.instance.objectNode(); + + chartJson.put("possibleLearners", service.getCountLessonLearnersByContentId(toolContentId)); + chartJson.put("startedLearners", service.getCountUsersByContentId(toolContentId)); + chartJson.put("completedLearners", service.getCountLearnersWithFinishedCurrentAttempt(toolContentId)); + + Map answeredQuestionsByUsers = service.getCountAnsweredQuestionsByUsers(toolContentId); + if (!answeredQuestionsByUsers.isEmpty()) { + chartJson.set("answeredQuestionsByUsers", JsonUtil.readObject(answeredQuestionsByUsers)); + } + + response.setContentType("application/json;charset=utf-8"); + return chartJson.toString(); + } + @RequestMapping("/userMasterDetail") public String userMasterDetail(HttpServletRequest request, HttpServletResponse response) { Long userId = WebUtil.readLongParam(request, AttributeNames.PARAM_USER_ID); Index: lams_tool_assessment/web/pages/monitoring/monitoring.jsp =================================================================== diff -u -r7f00c08c54ad8e6bfc47ea24d69008e5bd2af46f -r36716004da333fcc5eb3f776801e3e5278719fd7 --- lams_tool_assessment/web/pages/monitoring/monitoring.jsp (.../monitoring.jsp) (revision 7f00c08c54ad8e6bfc47ea24d69008e5bd2af46f) +++ lams_tool_assessment/web/pages/monitoring/monitoring.jsp (.../monitoring.jsp) (revision 36716004da333fcc5eb3f776801e3e5278719fd7) @@ -32,8 +32,12 @@ text-align: center; } - #completion-chart-container { - width: 400px; + #completion-charts-container { + display: flex; + } + + #completion-charts-container > div { + width: 40%; margin: auto; } Index: lams_tool_assessment/web/pages/monitoring/summary.jsp =================================================================== diff -u -r0308bc895456fece130e1b2fddfd16bdd40fc190 -r36716004da333fcc5eb3f776801e3e5278719fd7 --- lams_tool_assessment/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision 0308bc895456fece130e1b2fddfd16bdd40fc190) +++ lams_tool_assessment/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision 36716004da333fcc5eb3f776801e3e5278719fd7) @@ -5,6 +5,11 @@