Index: lams_central/web/qb/stats.jsp =================================================================== diff -u -r75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed -red9a00f4f59d352ae53b11ba461f12affd12dab0 --- lams_central/web/qb/stats.jsp (.../stats.jsp) (revision 75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed) +++ lams_central/web/qb/stats.jsp (.../stats.jsp) (revision ed9a00f4f59d352ae53b11ba461f12affd12dab0) @@ -22,14 +22,6 @@ font-weight: bold; } - { - font-weight: bold; - } - - { - font-weight: bold; - } - #chartDiv { height: 220px; } @@ -165,9 +157,12 @@ Tool type + + Average correct selection
(as first choice) + - - + + @@ -176,11 +171,14 @@ - + - + + + % + Index: lams_common/src/java/org/lamsfoundation/lams/qb/dao/IQbDAO.java =================================================================== diff -u -r75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed -red9a00f4f59d352ae53b11ba461f12affd12dab0 --- lams_common/src/java/org/lamsfoundation/lams/qb/dao/IQbDAO.java (.../IQbDAO.java) (revision 75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed) +++ lams_common/src/java/org/lamsfoundation/lams/qb/dao/IQbDAO.java (.../IQbDAO.java) (revision ed9a00f4f59d352ae53b11ba461f12affd12dab0) @@ -18,5 +18,9 @@ List getQuestionVersions(long qbQuestionUid); - Map getAnswerStats(long qbQuestionUid); + Map getAnswerStatsForQbQuestion(long qbQuestionUid); + + Map geAnswerStatsForQbToolQuestion(long qbToolQuestionUid); + + Map geAnswerStatsForActivity(long activityId); } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/qb/dao/hibernate/QbDAO.java =================================================================== diff -u -r75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed -red9a00f4f59d352ae53b11ba461f12affd12dab0 --- lams_common/src/java/org/lamsfoundation/lams/qb/dao/hibernate/QbDAO.java (.../QbDAO.java) (revision 75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed) +++ lams_common/src/java/org/lamsfoundation/lams/qb/dao/hibernate/QbDAO.java (.../QbDAO.java) (revision ed9a00f4f59d352ae53b11ba461f12affd12dab0) @@ -17,8 +17,12 @@ + "WHERE a.toolContentId = q.toolContentId AND a.learningDesign.lessons IS NOT EMPTY AND q.qbQuestion.uid = :qbQuestionUid"; private static final String FIND_QUESTION_VERSIONS = "SELECT q FROM QbQuestion AS q, QbQuestion AS r " + "WHERE q.questionId = r.questionId AND q.uid <> r.uid AND r.uid = :qbQuestionUid"; - private static final String FIND_ANSWER_STATS = "SELECT a.qbOption.uid, COUNT(a.uid) FROM QbToolAnswer AS a " + private static final String FIND_ANSWER_STATS_BY_QB_QUESTION = "SELECT a.qbOption.uid, COUNT(a.uid) FROM QbToolAnswer AS a " + "WHERE a.qbOption.qbQuestion.uid = :qbQuestionUid GROUP BY a.qbOption.uid"; + private static final String FIND_ANSWER_STATS_BY_TOOL_QUESTION = "SELECT a.qbOption.uid, COUNT(a.uid) FROM QbToolAnswer AS a " + + "WHERE a.qbToolQuestion.uid = :qbToolQuestionUid GROUP BY a.qbOption.uid"; + private static final String FIND_ANSWER_STATS_BY_ACTIVITY = "SELECT a.qbOption.uid, COUNT(a.uid) FROM QbToolAnswer AS a, " + + " ToolActivity AS act WHERE a.qbToolQuestion.toolContentId = act.toolContentId AND act.activityId = :activityId GROUP BY a.qbOption.uid"; @Override public int getMaxQuestionId() { @@ -51,13 +55,37 @@ @Override @SuppressWarnings("unchecked") - public Map getAnswerStats(long qbQuestionUid) { - List result = this.getSession().createQuery(FIND_ANSWER_STATS) + public Map getAnswerStatsForQbQuestion(long qbQuestionUid) { + List result = this.getSession().createQuery(FIND_ANSWER_STATS_BY_QB_QUESTION) .setParameter("qbQuestionUid", qbQuestionUid).list(); Map map = new HashMap<>(result.size()); for (Object[] answerStat : result) { map.put((Long) answerStat[0], (Long) answerStat[1]); } return map; } + + @Override + @SuppressWarnings("unchecked") + public Map geAnswerStatsForQbToolQuestion(long qbToolQuestionUid) { + List result = this.getSession().createQuery(FIND_ANSWER_STATS_BY_TOOL_QUESTION) + .setParameter("qbToolQuestionUid", qbToolQuestionUid).list(); + Map map = new HashMap<>(result.size()); + for (Object[] answerStat : result) { + map.put((Long) answerStat[0], (Long) answerStat[1]); + } + return map; + } + + @Override + @SuppressWarnings("unchecked") + public Map geAnswerStatsForActivity(long activityId) { + List result = this.getSession().createQuery(FIND_ANSWER_STATS_BY_ACTIVITY) + .setParameter("activityId", activityId).list(); + Map map = new HashMap<>(result.size()); + for (Object[] answerStat : result) { + map.put((Long) answerStat[0], (Long) answerStat[1]); + } + return map; + } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/qb/dto/QbStatsDTO.java =================================================================== diff -u -r75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed -red9a00f4f59d352ae53b11ba461f12affd12dab0 --- lams_common/src/java/org/lamsfoundation/lams/qb/dto/QbStatsDTO.java (.../QbStatsDTO.java) (revision 75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed) +++ lams_common/src/java/org/lamsfoundation/lams/qb/dto/QbStatsDTO.java (.../QbStatsDTO.java) (revision ed9a00f4f59d352ae53b11ba461f12affd12dab0) @@ -7,11 +7,32 @@ import org.lamsfoundation.lams.qb.model.QbQuestion; public class QbStatsDTO { + public static class QbStatsActivityDTO { + public ToolActivity activity; + public Integer average; + + public ToolActivity getActivity() { + return activity; + } + + public void setActivity(ToolActivity activity) { + this.activity = activity; + } + + public Integer getAverage() { + return average; + } + + public void setAverage(Integer average) { + this.average = average; + } + } + private QbQuestion question; private Map answersRaw; private Map answersPercent; private String answersJSON; - private List activities; + private List activities; private List versions; public QbQuestion getQuestion() { @@ -46,11 +67,11 @@ this.answersJSON = answersJSON; } - public List getActivities() { + public List getActivities() { return activities; } - public void setActivities(List activities) { + public void setActivities(List activities) { this.activities = activities; } Index: lams_common/src/java/org/lamsfoundation/lams/qb/service/QbService.java =================================================================== diff -u -r75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed -red9a00f4f59d352ae53b11ba461f12affd12dab0 --- lams_common/src/java/org/lamsfoundation/lams/qb/service/QbService.java (.../QbService.java) (revision 75e43eb7dffa6bf6eb2a11bb1e616c53bdbd76ed) +++ lams_common/src/java/org/lamsfoundation/lams/qb/service/QbService.java (.../QbService.java) (revision ed9a00f4f59d352ae53b11ba461f12affd12dab0) @@ -1,11 +1,14 @@ package org.lamsfoundation.lams.qb.service; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.qb.dao.IQbDAO; import org.lamsfoundation.lams.qb.dto.QbStatsDTO; +import org.lamsfoundation.lams.qb.dto.QbStatsDTO.QbStatsActivityDTO; import org.lamsfoundation.lams.qb.model.QbOption; import org.lamsfoundation.lams.qb.model.QbQuestion; @@ -30,10 +33,36 @@ @Override public QbStatsDTO getStats(long qbQuestionUid) { QbStatsDTO stats = new QbStatsDTO(); - stats.setQuestion((QbQuestion) qbDAO.find(QbQuestion.class, qbQuestionUid)); - stats.setActivities(qbDAO.getQuestionActivities(qbQuestionUid)); + QbQuestion qbQuestion = (QbQuestion) qbDAO.find(QbQuestion.class, qbQuestionUid); + List qbOptions = qbQuestion.getQbOptions(); + stats.setQuestion(qbQuestion); + + List activities = qbDAO.getQuestionActivities(qbQuestionUid); + List activityDTOs = new LinkedList<>(); + // calculate correct answer average for each activity + for (ToolActivity activity : activities) { + QbStatsActivityDTO activityDTO = new QbStatsActivityDTO(); + activityDTO.setActivity(activity); + Map activityAnswersRaw = qbDAO.geAnswerStatsForActivity(activity.getActivityId()); + double total = 0; + long correctCount = 0; + for (QbOption option : qbOptions) { + Long answerCount = activityAnswersRaw.get(option.getUid()); + if (answerCount == null) { + answerCount = 0L; + } + total += answerCount; + if (option.isCorrect()) { + correctCount = answerCount; + } + } + activityDTO.setAverage(Long.valueOf(Math.round(correctCount / total * 100)).intValue()); + activityDTOs.add(activityDTO); + } + stats.setActivities(activityDTOs); + stats.setVersions(qbDAO.getQuestionVersions(qbQuestionUid)); - Map answersRaw = qbDAO.getAnswerStats(qbQuestionUid); + Map answersRaw = qbDAO.getAnswerStatsForQbQuestion(qbQuestionUid); stats.setAnswersRaw(answersRaw); ArrayNode answersJSON = JsonNodeFactory.instance.arrayNode(); @@ -42,7 +71,6 @@ total += answerCount; } Map answerPercent = new HashMap<>(); - List qbOptions = stats.getQuestion().getQbOptions(); for (int answerIndex = 0; answerIndex < qbOptions.size(); answerIndex++) { QbOption option = qbOptions.get(answerIndex); Long answerCount = answersRaw.get(option.getUid());