Index: lams_monitoring/web/css/components-monitoring.css =================================================================== diff -u -r89da5ec382514ba94e3b2f2b8661ec28b42f7afe -r56003dc7b87af7983c137daf04e402404932aeaa --- lams_monitoring/web/css/components-monitoring.css (.../components-monitoring.css) (revision 89da5ec382514ba94e3b2f2b8661ec28b42f7afe) +++ lams_monitoring/web/css/components-monitoring.css (.../components-monitoring.css) (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -63,7 +63,6 @@ vertical-align: top; } - .component-sidebar { height: initial; align-items: center; @@ -1250,6 +1249,7 @@ .table-hover > tbody > tr:hover > * { --bs-table-accent-bg: var(--bs-gray-200); + color: var(--bs-black) !important; } .gate-card .card-body { Index: lams_monitoring/web/includes/javascript/monitorLesson5.js =================================================================== diff -u -r08f538ec5750238a01bc6b9a029c05531a201c2e -r56003dc7b87af7983c137daf04e402404932aeaa --- lams_monitoring/web/includes/javascript/monitorLesson5.js (.../monitorLesson5.js) (revision 08f538ec5750238a01bc6b9a029c05531a201c2e) +++ lams_monitoring/web/includes/javascript/monitorLesson5.js (.../monitorLesson5.js) (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -153,6 +153,11 @@ tabContent.load(LAMS_URL + 'tool/laasse10/tblmonitoring/iraAssessment.do?toolContentID=' + iraToolContentId); } break; + + case 'iraAssessmentStudentChoices': { + tabContent.load(LAMS_URL + 'tool/laasse10/tblmonitoring/iraAssessmentStudentChoices.do?toolContentID=' + iraToolContentId); + } + break; } } Index: lams_monitoring/web/monitor5.jsp =================================================================== diff -u -r08f538ec5750238a01bc6b9a029c05531a201c2e -r56003dc7b87af7983c137daf04e402404932aeaa --- lams_monitoring/web/monitor5.jsp (.../monitor5.jsp) (revision 08f538ec5750238a01bc6b9a029c05531a201c2e) +++ lams_monitoring/web/monitor5.jsp (.../monitor5.jsp) (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -27,6 +27,8 @@ + + Index: lams_monitoring/web/timeLimit5.jsp =================================================================== diff -u --- lams_monitoring/web/timeLimit5.jsp (revision 0) +++ lams_monitoring/web/timeLimit5.jsp (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -0,0 +1,709 @@ +<%@ include file="/taglibs.jsp"%> + + + + + + + + +
+
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+

+
+ ${param.relativeTimeLimit}  + + +
+ +
+
+ +
+
+ + + + + + + + + + +

+

+
+
+ +
+
+ +
+
+ + + + + + + + + + +
+

+

+
+
+ + + + +
+ + + + + + + + + + + + + +
+
+
+ +
+ + +
+
+ +
+ +
+ +
+ +
+ +
+
+
\ No newline at end of file Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java =================================================================== diff -u -r08f538ec5750238a01bc6b9a029c05531a201c2e -r56003dc7b87af7983c137daf04e402404932aeaa --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java (.../TblMonitoringController.java) (revision 08f538ec5750238a01bc6b9a029c05531a201c2e) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java (.../TblMonitoringController.java) (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -123,7 +123,7 @@ request.setAttribute("assessment", assessment); request.setAttribute("isTbl", true); - return "pages/tblmonitoring/iraAssessmentStudentChoices"; + return "pages/tblmonitoring/iraAssessmentStudentChoices5"; } private List getAssessmentDtos(String[] toolContentIds, String[] activityTitles) { Index: lams_tool_assessment/web/includes/javascript/chart5.js =================================================================== diff -u --- lams_tool_assessment/web/includes/javascript/chart5.js (revision 0) +++ lams_tool_assessment/web/includes/javascript/chart5.js (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -0,0 +1,462 @@ +function drawCompletionCharts(toolContentId, useGroups, animate) { + + const source = new EventSource( WEB_APP_URL + 'monitoring/getCompletionChartsData.do?toolContentId=' + toolContentId); + + source.onmessage = function (event) { + if (!event.data) { + return; + } + var data = JSON.parse(event.data); + drawActivityCompletionChart(data, animate); + drawAnsweredQuestionsChart(data, useGroups, animate); + } +} + +function drawActivityCompletionChart(data, animate){ + var newData = [ data.possibleLearners - data.startedLearners, + data.startedLearners - data.completedLearners, + data.completedLearners + ]; + if (activityCompletionChart != null) { + // chart already exists, just update data + activityCompletionChart.data.datasets[0].data = newData; + activityCompletionChart.update(); + return; + } + + let ctx = document.getElementById('activity-completion-chart').getContext('2d'); + + activityCompletionChart = new Chart(ctx, { + type : 'doughnut', + borderWidth : 0, + data : { + elements : { + arc : { + borderWidth : 0, + fontSize : 0, + } + }, + datasets : [ { + data : newData, + backgroundColor : [ 'rgba(5, 204, 214, 1)', + 'rgba(255, 195, 55, 1)', + 'rgba(253, 60, 165, 1)', + ], + borderWidth : 0, + } ], + labels : [ LABELS.ACTIVITY_COMPLETION_CHART_POSSIBLE_LEARNERS, + LABELS.ACTIVITY_COMPLETION_CHART_STARTED_LEARNERS, + LABELS.ACTIVITY_COMPLETION_CHART_COMPLETED_LEARNERS ] + }, + options : { + layout : { + padding : { + top: 10 + } + }, + legend : { + position: 'left', + labels : { + generateLabels : function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0), + style = meta.controller.getStyle(i), + value = data.datasets[0].data[i]; + + return { + text: label + ": " + value, + fillStyle: style.backgroundColor, + strokeStyle: style.borderColor, + lineWidth: style.borderWidth, + hidden: isNaN(value) || meta.data[i].hidden, + + // Extra data used for toggling the + // correct item + index: i + }; + }); + } + return []; + } + } + }, + title : { + display: true, + fontSize : '15', + text : LABELS.ACTIVITY_COMPLETION_CHART_TITLE + }, + animation : { + animateScale : true, + animateRotate : true, + duration : animate ? 1000 : 0 + } + } + }); +} + +function drawAnsweredQuestionsChart(data, useGroups, animate){ + if (!data.answeredQuestionsByUsers) { + $('#answered-questions-chart-none').show(); + return; + } + + $('#answered-questions-chart-none').hide(); + + // store current data for custom tooltip + $('#answered-questions-chart').data('tooltip-input', data.answeredQuestionsByUsers); + + if (answeredQuestionsChart != null) { + // chart already exists, just update data + answeredQuestionsChart.data.datasets[0].data = Object.values(data.answeredQuestionsByUsersCount); + answeredQuestionsChart.update(); + return; + } + + let ctx = document.getElementById('answered-questions-chart').getContext('2d'); + answeredQuestionsChart = new Chart(ctx, { + type : 'bar', + data : { + datasets : [ { + data : Object.values(data.answeredQuestionsByUsersCount), + backgroundColor : 'rgba(255, 195, 55, 1)' + + } ], + labels : Object.keys(data.answeredQuestionsByUsersCount), + }, + options : { + layout : { + paddint : { + top : 30 + } + }, + legend : { + display : false + }, + title : { + display: true, + fontSize : '15', + lineHeight: 3, + text : useGroups ? LABELS.ANSWERED_QUESTIONS_CHART_TITLE_GROUPS : LABELS.ANSWERED_QUESTIONS_CHART_TITLE + }, + animation : { + duration : animate ? 1000 : 0 + }, + scales : { + xAxes : [{ + scaleLabel : { + display : true, + labelString : LABELS.ANSWERED_QUESTIONS_CHART_X_AXIS + } + } + ], + yAxes : [ + { + ticks : { + beginAtZero : true, + stepSize : 1, + maxTicksLimit : 5, + // prevent scale to change on each update + // set suggested max number of students to 3/4 + // of all possible learners + suggestedMax : Math.max(2, Math.floor(3 * (useGroups ? data.sessionCount : data.possibleLearners) / 4)) + }, + scaleLabel : { + display : true, + labelString : useGroups ? LABELS.ANSWERED_QUESTIONS_CHART_Y_AXIS_GROUPS : LABELS.ANSWERED_QUESTIONS_CHART_Y_AXIS_STUDENTS, + fontSize : 14 + } + } + ] + }, + tooltips : { + enabled : false, + custom : function(tooltipModel) { + // always remove the tooltip at the beginning + $('.answered-questions-chart-tooltip').remove(); + if (tooltipModel.opacity === 0) { + // if it should be hidden, there is nothing to do + return; + } + + // create tooltip + var tooltipEl = $('
').addClass('answered-questions-chart-tooltip') + .appendTo(document.body) + .css({ + 'opacity' : 1, + 'position' :'absolute', + 'pointerEvents' : 'none', + 'background-color' : 'white', + 'padding' : '15px', + 'border' : 'thin solid #ddd', + 'border-radius' : '25px' + }); + + // iterate over learners, get their names and portraits + var counter = 0, + users = $('#answered-questions-chart').data('tooltip-input')[tooltipModel.dataPoints[0].label]; + $(users).each(function(){ + var portraitDiv = $(definePortrait(this[1], this[0], STYLE_SMALL, true, LAMS_URL)).css({ + 'vertical-align' : 'middle' + }), + userDiv = $('
').append(portraitDiv).appendTo(tooltipEl).css({ + 'padding-bottom' : '5px' + }); + + $('').text(this[3] ? this[3] + ' (' + this[2] + ')' : this[2]).appendTo(userDiv).css({ + 'padding-left' : '10px' + }); + + if (counter === 15) { + // do not display more than 15 learners + if (users.length > 16) { + $('
').text('...').appendTo(tooltipEl).css({ + 'font-weight' : 'bold', + 'font-size' : '20px', + 'text-align' : 'center' + }); + } + return false; + } + counter++; + }); + + // do not add padding for the last element as the tooltip does not look symmetric + tooltipEl.children(':last-child').css({ + 'padding-bottom' : '0' + }); + + var position = this._chart.canvas.getBoundingClientRect(); + tooltipEl.css({ + 'left' : position.left + window.pageXOffset + tooltipModel.caretX - tooltipEl.width() - 60 + 'px', + 'top' : Math.max(10, position.top + window.pageYOffset + tooltipModel.caretY - tooltipEl.height()/2) + 'px', + }); + } + } + } + }); +} + +function drawActivityCompletionChart(data, animate){ + var newData = [ data.possibleLearners - data.startedLearners, + data.startedLearners - data.completedLearners, + data.completedLearners + ]; + if (activityCompletionChart != null) { + // chart already exists, just update data + activityCompletionChart.data.datasets[0].data = newData; + activityCompletionChart.update(); + return; + } + + let ctx = document.getElementById('activity-completion-chart').getContext('2d'); + + activityCompletionChart = new Chart(ctx, { + type : 'doughnut', + borderWidth : 0, + data : { + elements : { + arc : { + borderWidth : 0, + fontSize : 0, + } + }, + datasets : [ { + data : newData, + backgroundColor : [ 'rgba(5, 204, 214, 1)', + 'rgba(255, 195, 55, 1)', + 'rgba(253, 60, 165, 1)', + ], + borderWidth : 0, + } ], + labels : [ LABELS.ACTIVITY_COMPLETION_CHART_POSSIBLE_LEARNERS, + LABELS.ACTIVITY_COMPLETION_CHART_STARTED_LEARNERS, + LABELS.ACTIVITY_COMPLETION_CHART_COMPLETED_LEARNERS ] + }, + options : { + layout : { + padding : { + top: 10 + } + }, + legend : { + position: 'left', + labels : { + generateLabels : function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0), + style = meta.controller.getStyle(i), + value = data.datasets[0].data[i]; + + return { + text: label + ": " + value, + fillStyle: style.backgroundColor, + strokeStyle: style.borderColor, + lineWidth: style.borderWidth, + hidden: isNaN(value) || meta.data[i].hidden, + + // Extra data used for toggling the + // correct item + index: i + }; + }); + } + return []; + } + } + }, + title : { + display: true, + fontSize : '15', + text : LABELS.ACTIVITY_COMPLETION_CHART_TITLE + }, + animation : { + animateScale : true, + animateRotate : true, + duration : animate ? 1000 : 0 + } + } + }); +} + +function drawAnsweredQuestionsChart(data, useGroups, animate){ + if (!data.answeredQuestionsByUsers) { + return; + } + + // store current data for custom tooltip + $('#answered-questions-chart').data('tooltip-input', data.answeredQuestionsByUsers); + + if (answeredQuestionsChart != null) { + // chart already exists, just update data + answeredQuestionsChart.data.datasets[0].data = Object.values(data.answeredQuestionsByUsersCount); + answeredQuestionsChart.update(); + return; + } + + let ctx = document.getElementById('answered-questions-chart').getContext('2d'); + answeredQuestionsChart = new Chart(ctx, { + type : 'bar', + data : { + datasets : [ { + data : Object.values(data.answeredQuestionsByUsersCount), + backgroundColor : 'rgba(255, 195, 55, 1)' + + } ], + labels : Object.keys(data.answeredQuestionsByUsersCount), + }, + options : { + layout : { + paddint : { + top : 30 + } + }, + legend : { + display : false + }, + title : { + display: true, + fontSize : '15', + lineHeight: 3, + text : useGroups ? LABELS.ANSWERED_QUESTIONS_CHART_TITLE_GROUPS : LABELS.ANSWERED_QUESTIONS_CHART_TITLE + }, + animation : { + duration : animate ? 1000 : 0 + }, + scales : { + xAxes : [{ + scaleLabel : { + display : true, + labelString : LABELS.ANSWERED_QUESTIONS_CHART_X_AXIS + } + } + ], + yAxes : [ + { + ticks : { + beginAtZero : true, + stepSize : 1, + maxTicksLimit : 5, + // prevent scale to change on each update + // set suggested max number of students to 3/4 + // of all possible learners + suggestedMax : Math.max(2, Math.floor(3 * (useGroups ? data.sessionCount : data.possibleLearners) / 4)) + }, + scaleLabel : { + display : true, + labelString : useGroups ? LABELS.ANSWERED_QUESTIONS_CHART_Y_AXIS_GROUPS : LABELS.ANSWERED_QUESTIONS_CHART_Y_AXIS_STUDENTS, + fontSize : 14 + } + } + ] + }, + tooltips : { + enabled : false, + custom : function(tooltipModel) { + // always remove the tooltip at the beginning + $('.answered-questions-chart-tooltip').remove(); + if (tooltipModel.opacity === 0) { + // if it should be hidden, there is nothing to do + return; + } + + // create tooltip + var tooltipEl = $('
').addClass('answered-questions-chart-tooltip') + .appendTo(document.body) + .css({ + 'opacity' : 1, + 'position' :'absolute', + 'pointerEvents' : 'none', + 'background-color' : 'white', + 'padding' : '15px', + 'border' : 'thin solid #ddd', + 'border-radius' : '25px' + }); + + // iterate over learners, get their names and portraits + var counter = 0, + users = $('#answered-questions-chart').data('tooltip-input')[tooltipModel.dataPoints[0].label]; + $(users).each(function(){ + var portraitDiv = $(definePortrait(this[1], this[0], STYLE_SMALL, true, LAMS_URL)).css({ + 'vertical-align' : 'middle' + }), + userDiv = $('
').append(portraitDiv).appendTo(tooltipEl).css({ + 'padding-bottom' : '5px' + }); + + $('').text(this[3] ? this[3] + ' (' + this[2] + ')' : this[2]).appendTo(userDiv).css({ + 'padding-left' : '10px' + }); + + if (counter === 15) { + // do not display more than 15 learners + if (users.length > 16) { + $('
').text('...').appendTo(tooltipEl).css({ + 'font-weight' : 'bold', + 'font-size' : '20px', + 'text-align' : 'center' + }); + } + return false; + } + counter++; + }); + + // do not add padding for the last element as the tooltip does not look symmetric + tooltipEl.children(':last-child').css({ + 'padding-bottom' : '0' + }); + + var position = this._chart.canvas.getBoundingClientRect(); + tooltipEl.css({ + 'left' : position.left + window.pageXOffset + tooltipModel.caretX - tooltipEl.width() - 60 + 'px', + 'top' : Math.max(10, position.top + window.pageYOffset + tooltipModel.caretY - tooltipEl.height()/2) + 'px', + }); + } + } + } + }); +} \ No newline at end of file Index: lams_tool_assessment/web/pages/monitoring/parts/mcqStudentChoices5.jsp =================================================================== diff -u --- lams_tool_assessment/web/pages/monitoring/parts/mcqStudentChoices5.jsp (revision 0) +++ lams_tool_assessment/web/pages/monitoring/parts/mcqStudentChoices5.jsp (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -0,0 +1,103 @@ +<%@ include file="/common/taglibs.jsp"%> + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + ${ALPHABET_CAPITAL_LETTERS[i]} +
+ + ${i.index+1} + + + % +
+
+
+ + + + + + + + +
\ No newline at end of file Index: lams_tool_assessment/web/pages/tblmonitoring/assessment5.jsp =================================================================== diff -u -r08f538ec5750238a01bc6b9a029c05531a201c2e -r56003dc7b87af7983c137daf04e402404932aeaa --- lams_tool_assessment/web/pages/tblmonitoring/assessment5.jsp (.../assessment5.jsp) (revision 08f538ec5750238a01bc6b9a029c05531a201c2e) +++ lams_tool_assessment/web/pages/tblmonitoring/assessment5.jsp (.../assessment5.jsp) (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -19,7 +19,7 @@ function showStudentChoices() { // these methods come from tblmonitor.jsp and aes.jsp in lams_monitoring if (${not empty isIraAssessment and isIraAssessment}) { - loadTab('iraAssessmentStudentChoices', ${toolContentID}); + loadTab('iraAssessmentStudentChoices'); return; } loadAePane(${toolContentID}, 'studentChoices'); Index: lams_tool_assessment/web/pages/tblmonitoring/iraAssessmentStudentChoices5.jsp =================================================================== diff -u --- lams_tool_assessment/web/pages/tblmonitoring/iraAssessmentStudentChoices5.jsp (revision 0) +++ lams_tool_assessment/web/pages/tblmonitoring/iraAssessmentStudentChoices5.jsp (revision 56003dc7b87af7983c137daf04e402404932aeaa) @@ -0,0 +1,122 @@ +<%@ include file="/common/taglibs.jsp"%> +<% pageContext.setAttribute("newLineChar", "\r\n"); %> + +monitoring/timeLimit5.jsp + + + + + + + + + + + +
+
+
+

+ +

+
+
+ + + + + +
+
+
+ +
+
+ +
+
+

No students have answered questions yet

+ +
+
+
+ + <%-- Include student's choices part --%> +
+
+ <%@ include file="/pages/monitoring/parts/mcqStudentChoices5.jsp" %> +
+
+ +
+
+
+
+
\ No newline at end of file