From 8eb961e8428c9efcf0e707d584929f9eaf99b2d2 Mon Sep 17 00:00:00 2001 From: Marcio Fernando Stabile Junior Date: Tue, 29 Aug 2023 07:24:47 -0300 Subject: [PATCH] Adding new visualization option for student progress --- .../dashboard/static/dashboard-progress.js | 76 +++++++++++++++++++ .../dashboard/instructor-progress.html | 5 ++ backend/app/dashboard/views.py | 10 ++- 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/backend/app/dashboard/static/dashboard-progress.js b/backend/app/dashboard/static/dashboard-progress.js index 5ff7aab..9b83f48 100644 --- a/backend/app/dashboard/static/dashboard-progress.js +++ b/backend/app/dashboard/static/dashboard-progress.js @@ -43,6 +43,12 @@ function createHandsontable(data, columns_list) { function updateHandsontable(data, columns_list) { data = filterStudentsInClass(data); + ret = generateMatrix(data, columns_list) + zvals = ret[1] + data_h[0]['x'] = columns_list.slice(1); + data_h[0]['z'] = zvals; + Plotly.redraw('chart'); + let dataSchema = getDataSchema(columns_list); hot.updateSettings({ data: data, @@ -142,6 +148,29 @@ function generateTagView() { }); } +function generateMatrix(tableData, columns){ + nulls = new Array(columns.length-1).fill(null) + zvals = [] + usernames = [] + tableData.forEach(row => { + studentvals = [...nulls] + Object.entries(row).forEach((val) => { + if (val[0] == "Name") { + usernames.push(val[1]) + } + else{ + idx = columns.indexOf(val[0])-1 + if (idx >= 0){ + studentvals[idx] = val[1] + } + } + }); + zvals.push(studentvals) + }); + console.log(usernames) + return [usernames.reverse(), zvals.reverse()] +} + var tags = new Set(); var table; var columns; @@ -180,4 +209,51 @@ document.addEventListener("DOMContentLoaded", function () { tableData = structuredClone(data); createHandsontable(tableData, columns); + + ret = generateMatrix(tableData, columns) + usernames = ret[0] + zvals = ret[1] + data_h = [ + { + x: columns.slice(1), + y: usernames, + z: zvals, + type: 'heatmap', + hovertemplate : 'Exercício: %{x}
Aluno: %{y}
Nota: %{z}', + colorscale:[[0.0, "red"], [0.1, "red"], + [0.1, "orange"], [1, "orange"], + [1, "green"], [1.00, "green"]], + showscale:false, + xgap:0.5, + ygap:0.5, + } + ]; + + var layout = { + margin: { + t: 50, + r: 50, + b: 0, + l: 150 + }, + xaxis: {showticklabels: false, ticks: "", side:"top"}, + showlegend: false, + height: usernames.length * 20, + autosize: true + }; + + Plotly.newPlot('chart', data_h, layout); }); + +function toggleVisibility() { + var table = document.getElementById("table"); + var chart = document.getElementById("chart"); + if (table.style.display === "none") { + table.style.display = ""; + chart.style.display = "none"; + } else { + table.style.display = "none"; + chart.style.display = ""; + document.querySelector('[data-title="Autoscale"]').click() + } +} \ No newline at end of file diff --git a/backend/app/dashboard/templates/dashboard/instructor-progress.html b/backend/app/dashboard/templates/dashboard/instructor-progress.html index d77d040..c7aa9cd 100644 --- a/backend/app/dashboard/templates/dashboard/instructor-progress.html +++ b/backend/app/dashboard/templates/dashboard/instructor-progress.html @@ -7,6 +7,8 @@ + + @@ -40,6 +42,7 @@

Class Progress

{% endfor %} + {% endif %} @@ -47,6 +50,8 @@

Class Progress

+ + diff --git a/backend/app/dashboard/views.py b/backend/app/dashboard/views.py index 2222759..c4f327d 100644 --- a/backend/app/dashboard/views.py +++ b/backend/app/dashboard/views.py @@ -73,10 +73,16 @@ def students_progress(request, course_name): "Name": answer['author__username']}) data[answer['author__username']][answer['exercise__slug'] ] = round(answer['max_points'], 1) - columns_with_list = [*["Name"], *list(columns)] + sorted_columns = sorted(list(columns)) + columns_with_list = [*["Name"], *sorted_columns] + + data_list = sorted(list(data.values()), key=lambda d: d['Name'].lower()) + for d in data_list: + print(d["Name"]) + return render(request, 'dashboard/instructor-progress.html', { - 'data': list(data.values()), + 'data': data_list, 'columns': columns_with_list, 'tags': tag_obj, 'course_classes': course_classes_list,