Commit e3c708cb authored by I.K Seneviratne's avatar I.K Seneviratne

Committing the implementations of displaying graphs on activity, emotion and gaze individual pages.

parent a7659974
...@@ -168,13 +168,17 @@ class LectureVideoViewSet(APIView): ...@@ -168,13 +168,17 @@ class LectureVideoViewSet(APIView):
# serializer = LectureVideoSerializer(data=request.data, many=True) # serializer = LectureVideoSerializer(data=request.data, many=True)
serializer = LectureVideoSerializer(data=request.data) serializer = LectureVideoSerializer(data=request.data)
# serializer.create(validated_data=request.data) # serializer.create(validated_data=request.data)
data = {}
data_ser = {}
if serializer.is_valid(raise_exception=ValueError): if serializer.is_valid(raise_exception=ValueError):
print('valid') data = serializer.create(validated_data=request.data)
serializer.create(validated_data=request.data) print('data: ', data)
# data_ser = LectureVideoSerializer(data, many=True)
return Response(serializer.data, status=status.HTTP_201_CREATED) # return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(data, status=status.HTTP_201_CREATED)
# return Response(serializer.error_messages, # return Response(serializer.error_messages,
...@@ -462,6 +466,7 @@ class GetLectureEmotionReportViewSet(APIView): ...@@ -462,6 +466,7 @@ class GetLectureEmotionReportViewSet(APIView):
lecture_emotions = LectureEmotionReport.objects.filter(lecture_video_id__lecture_video_id=lecture_video_id) lecture_emotions = LectureEmotionReport.objects.filter(lecture_video_id__lecture_video_id=lecture_video_id)
serializer = LectureEmotionSerializer(lecture_emotions, many=True) serializer = LectureEmotionSerializer(lecture_emotions, many=True)
print('data: ', serializer.data)
return Response({ return Response({
"response": serializer.data, "response": serializer.data,
......
...@@ -275,6 +275,11 @@ class LectureVideoSerializer(serializers.ModelSerializer): ...@@ -275,6 +275,11 @@ class LectureVideoSerializer(serializers.ModelSerializer):
video_length=video_length video_length=video_length
) )
# retrieve the created object
created_lecture_video = LectureVideo.objects.filter(lecture_video_id=lecture_video)
create_lecture_video_ser = LectureVideoSerializer(created_lecture_video, many=True)
create_lecture_video_ser_data = create_lecture_video_ser.data
# faculty_data = validated_data.pop('faculty') # faculty_data = validated_data.pop('faculty')
# serialized_faculty = FacultySerializer(data=faculty_data) # serialized_faculty = FacultySerializer(data=faculty_data)
# #
...@@ -294,7 +299,7 @@ class LectureVideoSerializer(serializers.ModelSerializer): ...@@ -294,7 +299,7 @@ class LectureVideoSerializer(serializers.ModelSerializer):
# #
# return lecturer # return lecturer
# #
return lecture_video return create_lecture_video_ser_data
return None return None
......
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
<!-- Core plugin JavaScript--> <!-- Core plugin JavaScript-->
<script src="{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"></script> <script src="{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
<!-- canvasJS implementation -->
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
...@@ -32,12 +37,16 @@ ...@@ -32,12 +37,16 @@
var global_lecture_date = ''; var global_lecture_date = '';
var global_lecturer_video_name = ''; var global_lecturer_video_name = '';
var lecturer_fps = 0; var lecturer_fps = 0;
var lecture_activity_frame_group_percentages = {};
var lecture_video_time_landmarks = [];
;
//jquery //jquery
$(document).ready(function () { $(document).ready(function () {
//disable the 'integrate_activity' button
$('#integrate_activity').hide();
//select a particular subject //select a particular subject
$('input[type=radio]').click(function () { $('input[type=radio]').click(function () {
let subject_id = $(this).attr('id'); let subject_id = $(this).attr('id');
...@@ -76,6 +85,7 @@ ...@@ -76,6 +85,7 @@
let real_class = clicked_class.split(' ')[1]; let real_class = clicked_class.split(' ')[1];
real_class = '.' + real_class; real_class = '.' + real_class;
let date = e.target.parentNode.parentNode.firstChild.innerHTML; let date = e.target.parentNode.parentNode.firstChild.innerHTML;
//assign the date //assign the date
global_lecture_date = date; global_lecture_date = date;
...@@ -161,6 +171,9 @@ ...@@ -161,6 +171,9 @@
$('#generate_report_before').attr('disabled', false); $('#generate_report_before').attr('disabled', false);
$('#video_modal').modal(); $('#video_modal').modal();
//display the 'integrate activity' button
$('#integrate_activity').show();
} }
//binding a click event for 'btn-primary' buttons //binding a click event for 'btn-primary' buttons
...@@ -254,16 +267,15 @@ ...@@ -254,16 +267,15 @@
//fetch the lecture recorded video name //fetch the lecture recorded video name
fetch('http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=' + global_lecturer + '&subject=' + global_subject + '&date=' + global_lecture_date) fetch('http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=' + global_lecturer + '&subject=' + global_subject + '&date=' + global_lecture_date)
.then((res) => res.json()) .then((res) => res.json())
.then((out) => assignLecturerRecordedVideoName(out)) .then((out) => assignLecturerRecordedVideoName(out))
.catch((err) => alert('error: ' + err)); .catch((err) => alert('error: ' + err));
{#global_lecturer_video_name = "Test_1.mp4";#} {#global_lecturer_video_name = "Test_1.mp4";#}
{#global_lecturer_video_name = "Test_2.mp4";#} {#global_lecturer_video_name = "Test_2.mp4";#}
{#global_lecturer_video_name = "Test_3.mp4";#} {#global_lecturer_video_name = "Test_3.mp4";#}
//fetch data from the API //fetch data from the API
fetch('http://127.0.0.1:8000/get-lecture-activity-for-frame?video_name=' + global_video_name) fetch('http://127.0.0.1:8000/get-lecture-activity-for-frame?video_name=' + global_video_name)
.then((res) => res.json()) .then((res) => res.json())
...@@ -524,6 +536,165 @@ ...@@ -524,6 +536,165 @@
}); });
//this function will handle the activity 'summary' button
$('#graph-tab').click(function (e) {
//display the graph loader
$('#graph_loader').attr('hidden', false);
//fetch the video time landmark details
fetch('http://127.0.0.1:8000/get-lecture-video-summary-time-landmarks/?video_name=' + global_video_name)
.then((res) => res.json())
.then((out) => assignTimeLandmarks(out.response))
.catch((err) => alert('error: ' + err));
//change the innerHTML of the clicked button
{#e.target.innerHTML = "<span class='font-italic'>Processing</span>";#}
let phone_perct = $('#phone_perct').text().split("%")[0];
let listen_perct = $('#listening_perct').text().split("%")[0];
let note_perct = $('#writing_perct').text().split("%")[0];
//fetch the activity summary details
fetch('http://127.0.0.1:8000/get-lecture-activity-summary/?video_name=' + global_video_name + '&phone_perct=' + phone_perct + '&note_perct=' + note_perct + '&listen_perct=' + listen_perct)
.then((res) => res.json())
.then((out) => activityFrameGroupPercentages(out, e))
.catch((err) => alert('error: ' + err));
});
//this function will assign lecture video time landmarks
function assignTimeLandmarks(response) {
lecture_video_time_landmarks = response;
}
//this function will handle the retrieved activity frame group percentages
function activityFrameGroupPercentages(response, e) {
lecture_activity_frame_group_percentages = response.frame_group_percentages;
let frame_landmarks = response.frame_landmarks;
{#let frame_group_dict = response.frame_group_dict;#}
let activity_labels = response.activity_labels;
let comment_list = response.comments;
//render the chart onto the modal body
renderActivityChart(activity_labels);
}
//this function will call the activity chart function
function renderActivityChart(activity_labels) {
//hide the graph loader
$('#graph_loader').hide();
//get the activity label length
let activity_label_length = activity_labels.length;
let data = [];
//loop through the activity labels
for (let k = 0; k < activity_label_length; k++) {
let label = activity_labels[k];
let datapoints = [];
let count = 0;
//loop through the activity frame groups
for (let key in lecture_activity_frame_group_percentages) {
let frame_group_details = lecture_activity_frame_group_percentages[key];
let activity_perct = frame_group_details[label];
let point = {label: lecture_video_time_landmarks[count], y: activity_perct};
datapoints.push(point);
count++;
}
let obj = {
type: "line",
showInLegend: true,
name: label,
markerType: "square",
{#xValueFormatString: "DD MMM, YYYY",#}
xValueFormatString: "hh:mm:ss",
color: getRandomColor(),
dataPoints: datapoints
};
data.push(obj);
}
var chart = new CanvasJS.Chart("ActivityChartContainer", {
animationEnabled: true,
theme: "light2",
title: {
text: "Student Activity Behavior"
},
axisX: {
title: "Duration",
{#valueFormatString: "DD MMM",#}
valueFormatString: "hh:mm:ss",
crosshair: {
enabled: true,
snapToDataPoint: true
}
},
axisY: {
title: "Percentage",
includeZero: true,
crosshair: {
enabled: true
}
},
toolTip: {
shared: true
},
legend: {
cursor: "pointer",
verticalAlign: "top",
horizontalAlign: "right",
dockInsidePlotArea: true,
itemclick: toogleDataSeries
},
data: data
});
chart.render();
}
//this function will generate random colors
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
//this function will toggle the content
function toogleDataSeries(e) {
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}); });
</script> </script>
...@@ -702,18 +873,18 @@ ...@@ -702,18 +873,18 @@
<!--this area will display the progress bars --> <!--this area will display the progress bars -->
<div class="progress_area mt-4" hidden> <div class="progress_area mt-4" hidden>
<!--talking with friends --> <!--talking with friends -->
<a href="#" class="btn btn-link labels" data-number="1" {# <a href="#" class="btn btn-link labels" data-number="1"#}
data-label="talking-with-friends"> {# data-label="talking-with-friends">#}
<h4 class="small font-weight-bold">Talking with friends</h4> {# <h4 class="small font-weight-bold">Talking with friends</h4>#}
</a> {# </a>#}
<span class="float-right" id="talking_perct">40%</span> {# <span class="float-right" id="talking_perct">40%</span>#}
<div class="progress mb-4"> {# <div class="progress mb-4">#}
<div class="progress-bar bg-danger" role="progressbar" {# <div class="progress-bar bg-danger" role="progressbar"#}
id="talking_width" {# id="talking_width"#}
style="width: 20%" {# style="width: 20%"#}
aria-valuenow="20" aria-valuemin="0" {# aria-valuenow="20" aria-valuemin="0"#}
aria-valuemax="100"></div> {# aria-valuemax="100"></div>#}
</div> {# </div>#}
<!--phone checking --> <!--phone checking -->
<a href="#" class="btn btn-link labels" data-number="0" <a href="#" class="btn btn-link labels" data-number="0"
...@@ -765,46 +936,45 @@ ...@@ -765,46 +936,45 @@
<!--graph tab --> <!--graph tab -->
<div class="tab-pane fade" id="graph" role="tabpanel" <div class="tab-pane fade" id="graph" role="tabpanel"
aria-labelledby="profile-tab"> aria-labelledby="profile-tab">
<!-- graph loader -->
<div class="text-center mt-3" id="graph_loader" hidden>
<img src="{% static 'FirstApp/images/ajax-loader.gif' %}"
alt="Loader">
</div>
<!-- end of graph loader -->
<!--card content --> <!--card content -->
<div class="card shadow mb-4 p-3"> <div class="card shadow mb-4 p-3">
<!-- Card Header - Dropdown --> {# <!-- Card Header - Dropdown -->#}
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between"> {# <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">#}
<h6 class="m-0 font-weight-bold text-primary">Student {# <h6 class="m-0 font-weight-bold text-primary">Student#}
Activities</h6> {# Activities</h6>#}
<div class="dropdown no-arrow"> {# <div class="dropdown no-arrow">#}
<a class="dropdown-toggle" href="#" role="button" {# <a class="dropdown-toggle" href="#" role="button"#}
id="dropdownMenuLink" data-toggle="dropdown" {# id="dropdownMenuLink" data-toggle="dropdown"#}
aria-haspopup="true" aria-expanded="false"> {# aria-haspopup="true" aria-expanded="false">#}
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i> {# <i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>#}
</a> {# </a>#}
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" {# <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"#}
aria-labelledby="dropdownMenuLink"> {# aria-labelledby="dropdownMenuLink">#}
<div class="dropdown-header">Dropdown Header:</div> {# <div class="dropdown-header">Dropdown Header:</div>#}
<a class="dropdown-item" href="#">Action</a> {# <a class="dropdown-item" href="#">Action</a>#}
<a class="dropdown-item" href="#">Another action</a> {# <a class="dropdown-item" href="#">Another action</a>#}
<div class="dropdown-divider"></div> {# <div class="dropdown-divider"></div>#}
<a class="dropdown-item" href="#">Something else here</a> {# <a class="dropdown-item" href="#">Something else here</a>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
<!-- Card Body --> <!-- Card Body -->
<div class="card-body"> <div class="card-body">
<div class="chart-pie pt-4 pb-2"> <div id="ActivityChartContainer"
<canvas id="myPieChart"></canvas> style="height: 370px; max-width: 920px; margin: 0px auto;"></div>
</div>
<div class="mt-4 text-center small">
<span class="mr-2">
<i class="fas fa-circle text-primary"></i> Direct
</span>
<span class="mr-2">
<i class="fas fa-circle text-success"></i> Social
</span>
<span class="mr-2">
<i class="fas fa-circle text-info"></i> Referral
</span>
</div> </div>
<!-- End of Card Body -->
</div> </div>
</div>
</div> </div>
...@@ -1084,11 +1254,11 @@ ...@@ -1084,11 +1254,11 @@
type="video/mp4"> type="video/mp4">
Your browser does not support the video tag. Your browser does not support the video tag.
</video> </video>
{# <video width="500" height="300" id="student_video" controls>#} {# <video width="500" height="300" id="student_video" controls>#}
{# <source src="{% static 'FirstApp/videos/Video_test_2.mp4' %}"#} {# <source src="{% static 'FirstApp/videos/Video_test_2.mp4' %}"#}
{# type="video/mp4">#} {# type="video/mp4">#}
{# Your browser does not support the video tag.#} {# Your browser does not support the video tag.#}
{# </video>#} {# </video>#}
</div> </div>
<!--end of student video section --> <!--end of student video section -->
...@@ -1155,10 +1325,10 @@ ...@@ -1155,10 +1325,10 @@
<!--display lecture video --> <!--display lecture video -->
<div class="text-center m-3" id="lecturer_video_section"> <div class="text-center m-3" id="lecturer_video_section">
{# <!--temporary text -->#} {# <!--temporary text -->#}
{# <div class="text-center" id="temp_lecturer_text">#} {# <div class="text-center" id="temp_lecturer_text">#}
{# <span class="font-italic">No video was found</span>#} {# <span class="font-italic">No video was found</span>#}
{# </div>#} {# </div>#}
<!--display lecturer video --> <!--display lecturer video -->
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
<!-- Core plugin JavaScript--> <!-- Core plugin JavaScript-->
<script src="{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"></script> <script src="{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
<!-- canvasJS implementation -->
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
...@@ -31,10 +34,16 @@ ...@@ -31,10 +34,16 @@
var global_lecturer_subject_index = 0; var global_lecturer_subject_index = 0;
var global_lecturer_video_name = ''; var global_lecturer_video_name = '';
var lecturer_fps = 0; var lecturer_fps = 0;
var lecture_emotion_frame_group_percentages = {};
var lecture_video_time_landmarks = [];
//jquery //jquery
$(document).ready(function () { $(document).ready(function () {
//hide the 'integrate emotion' button
$('#integrate_emotion').hide();
//select a particular subject //select a particular subject
$('input[type=radio]').click(function () { $('input[type=radio]').click(function () {
let subject_id = $(this).attr('id'); let subject_id = $(this).attr('id');
...@@ -145,8 +154,8 @@ ...@@ -145,8 +154,8 @@
$('#video_name').text(video.video_name); $('#video_name').text(video.video_name);
$('#video_duration').text(video.video_length); $('#video_duration').text(video.video_length);
$('#video_date').text(video.date); $('#video_date').text(video.date);
{#global_lecture_video_id = video.lecture_video_id;#} global_lecture_video_id = video.lecture_video_id;
global_lecture_video_id = video.id; {#global_lecture_video_id = video.id;#}
global_video_name = video.video_name; global_video_name = video.video_name;
...@@ -157,6 +166,9 @@ ...@@ -157,6 +166,9 @@
} }
$('#video_modal').modal(); $('#video_modal').modal();
//display the 'integrate emotion' button
$('#integrate_emotion').show();
} }
//binding a click event for 'btn-primary' buttons //binding a click event for 'btn-primary' buttons
...@@ -255,9 +267,9 @@ ...@@ -255,9 +267,9 @@
//fetch the lecture recorded video name //fetch the lecture recorded video name
fetch('http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=' + global_lecturer + '&subject=' + global_subject + '&date=' + global_lecture_date) fetch('http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=' + global_lecturer + '&subject=' + global_subject + '&date=' + global_lecture_date)
.then((res) => res.json()) .then((res) => res.json())
.then((out) => assignLecturerRecordedVideoName(out)) .then((out) => assignLecturerRecordedVideoName(out))
.catch((err) => alert('error: ' + err)); .catch((err) => alert('error: ' + err));
{#global_lecturer_video_name = "Test_1.mp4";#} {#global_lecturer_video_name = "Test_1.mp4";#}
{#global_lecturer_video_name = "Test_2.mp4";#} {#global_lecturer_video_name = "Test_2.mp4";#}
...@@ -537,6 +549,151 @@ ...@@ -537,6 +549,151 @@
}); });
//this function will handle the activity 'summary' button
$('#graph-tab').click(function (e) {
//display the graph loader
$('#graph_loader').attr('hidden', false);
//fetch the video time landmark details
fetch('http://127.0.0.1:8000/get-lecture-video-summary-time-landmarks/?video_name=' + global_video_name)
.then((res) => res.json())
.then((out) => assignTimeLandmarks(out.response))
.catch((err) => alert('error: ' + err));
//fetch the activity summary details
fetch('http://127.0.0.1:8000/get-lecture-emotion-summary/?video_name=' + global_video_name)
.then((res) => res.json())
.then((out) => emotionFrameGroupPercentages(out, e))
.catch((err) => alert('error: ' + err));
});
//this function will assign lecture video time landmarks
function assignTimeLandmarks(response) {
lecture_video_time_landmarks = response;
}
//this function will handle the retrieved emotion frame group percentages
function emotionFrameGroupPercentages(response, e) {
lecture_emotion_frame_group_percentages = response.frame_group_percentages;
let frame_landmarks = response.frame_landmarks;
let emotion_labels = response.emotion_labels;
//render the chart onto the modal body
renderEmotionChart(emotion_labels);
}
//this function will call the emotion chart function
function renderEmotionChart(emotion_labels) {
//get the activity label length
let emotion_label_length = emotion_labels.length;
let data = [];
//loop through the activity labels
for (let k = 0; k < emotion_label_length; k++) {
let label = emotion_labels[k];
let datapoints = [];
let count = 0;
//loop through the activity frame groups
for (let key in lecture_emotion_frame_group_percentages) {
let frame_group_details = lecture_emotion_frame_group_percentages[key];
let emotion_perct = frame_group_details[label];
let point = {label: lecture_video_time_landmarks[count], y: emotion_perct};
datapoints.push(point);
count++;
}
let obj = {
type: "line",
showInLegend: true,
name: label,
markerType: "square",
{#xValueFormatString: "DD MMM, YYYY",#}
xValueFormatString: "hh:mm:ss",
color: getRandomColor(),
dataPoints: datapoints
};
data.push(obj);
}
var chart = new CanvasJS.Chart("EmotionChartContainer", {
animationEnabled: true,
theme: "light2",
title: {
text: "Student Emotion Behavior"
},
axisX: {
title: "Duration",
{#valueFormatString: "DD MMM",#}
valueFormatString: "hh:mm:ss",
crosshair: {
enabled: true,
snapToDataPoint: true
}
},
axisY: {
title: "Percentage",
includeZero: true,
crosshair: {
enabled: true
}
},
toolTip: {
shared: true
},
legend: {
cursor: "pointer",
verticalAlign: "top",
horizontalAlign: "right",
dockInsidePlotArea: true,
itemclick: toogleDataSeries
},
data: data
});
chart.render();
}
//this function will generate random colors
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
//this function will toggle the content
function toogleDataSeries(e) {
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}); });
</script> </script>
...@@ -787,122 +944,122 @@ ...@@ -787,122 +944,122 @@
</div> </div>
<!-- end of frame tab -->
<!--graph tab --> <!--graph tab -->
<div class="tab-pane fade" id="graph" role="tabpanel" <div class="tab-pane fade" id="graph" role="tabpanel"
aria-labelledby="profile-tab"> aria-labelledby="profile-tab">
<!--card content --> <!--card content -->
<div class="card shadow mb-4 p-3"> <div class="card shadow mb-4 p-3">
<!-- Card Header - Dropdown -->
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Student
Activities</h6>
<div class="dropdown no-arrow">
<a class="dropdown-toggle" href="#" role="button"
id="dropdownMenuLink" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
</a>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
aria-labelledby="dropdownMenuLink">
<div class="dropdown-header">Dropdown Header:</div>
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</div>
</div>
<!-- Card Body --> <!-- Card Body -->
<div class="card-body"> <div class="card-body">
<div class="chart-pie pt-4 pb-2"> <div id="EmotionChartContainer"
<canvas id="myPieChart"></canvas> style="height: 270px; max-width: 920px; margin: 0px auto;"></div>
</div>
<div class="mt-4 text-center small">
<span class="mr-2">
<i class="fas fa-circle text-primary"></i> Direct
</span>
<span class="mr-2">
<i class="fas fa-circle text-success"></i> Social
</span>
<span class="mr-2">
<i class="fas fa-circle text-info"></i> Referral
</span>
</div>
</div> </div>
<!-- End of Card Body -->
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!--2nd column --> <!--2nd column -->
{# <div class="col-lg-6">#} <div class="col-lg-6">
{# <!--card content -->#} <!--card -->
{# <div class="card shadow mb-4">#} <div class="card shadow mb-4">
{# <!--card header -->#} <!--card header -->
{# <div class="card-header py-3">#} <div class="card-header">
{# <h5 class="m-0 font-weight-bold text-primary">Frame Detections</h5>#} <h5 class="m-0 font-weight-bold text-primary">Integrated Evaluation</h5>
{# </div>#} </div>
{##}
{# <!--card body -->#}
{# <div class="text-center p-4" id="detection_frames">#}
{##}
{# <!--no content message-->#}
{# <div class="text-center p-2" id="no_detection_message_content">#}
{# <span class="font-italic">No frame is selected</span>#}
{# </div>#}
{##}
{# <div class="text-left m-3" id="detection_number_area" hidden>#}
{# <p>No of detections: <span id="no_of_detections"></span></p>#}
{# </div>#}
{# <!--the detection loader -->#}
{# <div class="text-center p-2" id="detection_loader" hidden>#}
{# <img src="{% static 'FirstApp/images/ajax-loader.gif' %}"#}
{# alt="Loader">#}
{# </div>#}
{# </div>#}
{# </div>#}
{##}
{# <!--detection person card -->#}
{# <div class="card shadow mb-4">#}
{# <!--card header -->#}
{# <div class="card-header py-3">#}
{# <h5 class="m-0 font-weight-bold text-primary">Detected Students (by emotion#}
{# type)</h5>#}
{# </div>#}
{##}
{# <!--card body -->#}
{# <div class="text-center p-4" id="detection_students">#}
{# <!--activity type line -->#}
{# <div class="text-center p-2" id="activity_type" hidden>#}
{# <p>Activity Type: <span class="font-weight-bold" id="activity_type_text"></span>#}
{# </p>#}
{# </div>#}
{##}
{# <!--no content message-->#}
{# <div class="text-center p-2" id="no_detection_student_content">#}
{# <span class="font-italic">No activity type is selected</span>#}
{# </div>#}
{##}
{# <!--the detection student loader -->#}
{# <div class="text-center p-2" id="detection_student_loader" hidden>#}
{# <img src="{% static 'FirstApp/images/ajax-loader.gif' %}"#}
{# alt="Loader">#}
{# </div>#}
{##}
{# </div>#}
{# </div>#}
{# </div>#}
<!--card body -->
<div class="card-body">
<div class="text-center" id="integrate_message">
<span class="font-italic">The integrated version student and lecturer evaluations will display here.</span>
</div>
<!--button -->
<div class="text-right m-4">
<button type="button" class="btn btn-outline-success" id="integrate_emotion">
Process
</button>
</div>
</div>
</div>
</div>
<!--end of 2nd column -->
</div> </div>
<!--2nd column -->
{# <div class="col-lg-6">#}
{# <!--card content -->#}
{# <div class="card shadow mb-4">#}
{# <!--card header -->#}
{# <div class="card-header py-3">#}
{# <h5 class="m-0 font-weight-bold text-primary">Frame Detections</h5>#}
{# </div>#}
{##}
{# <!--card body -->#}
{# <div class="text-center p-4" id="detection_frames">#}
{##}
{# <!--no content message-->#}
{# <div class="text-center p-2" id="no_detection_message_content">#}
{# <span class="font-italic">No frame is selected</span>#}
{# </div>#}
{##}
{# <div class="text-left m-3" id="detection_number_area" hidden>#}
{# <p>No of detections: <span id="no_of_detections"></span></p>#}
{# </div>#}
{# <!--the detection loader -->#}
{# <div class="text-center p-2" id="detection_loader" hidden>#}
{# <img src="{% static 'FirstApp/images/ajax-loader.gif' %}"#}
{# alt="Loader">#}
{# </div>#}
{# </div>#}
{# </div>#}
{##}
{# <!--detection person card -->#}
{# <div class="card shadow mb-4">#}
{# <!--card header -->#}
{# <div class="card-header py-3">#}
{# <h5 class="m-0 font-weight-bold text-primary">Detected Students (by emotion#}
{# type)</h5>#}
{# </div>#}
{##}
{# <!--card body -->#}
{# <div class="text-center p-4" id="detection_students">#}
{# <!--activity type line -->#}
{# <div class="text-center p-2" id="activity_type" hidden>#}
{# <p>Activity Type: <span class="font-weight-bold" id="activity_type_text"></span>#}
{# </p>#}
{# </div>#}
{##}
{# <!--no content message-->#}
{# <div class="text-center p-2" id="no_detection_student_content">#}
{# <span class="font-italic">No activity type is selected</span>#}
{# </div>#}
{##}
{# <!--the detection student loader -->#}
{# <div class="text-center p-2" id="detection_student_loader" hidden>#}
{# <img src="{% static 'FirstApp/images/ajax-loader.gif' %}"#}
{# alt="Loader">#}
{# </div>#}
{##}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
<!-- end of 2nd row --> <!-- end of 2nd row -->
<!--3rd row --> <!--3rd row -->
...@@ -941,32 +1098,32 @@ ...@@ -941,32 +1098,32 @@
{# </div>#} {# </div>#}
<!--end of 1st column --> <!--end of 1st column -->
{##}
<!--2nd column --> {# <!--2nd column -->#}
<div class="col-lg-6"> {# <div class="col-lg-6">#}
<!--card --> {# <!--card -->#}
<div class="card shadow mb-4"> {# <div class="card shadow mb-4">#}
<!--card header --> {# <!--card header -->#}
<div class="card-header"> {# <div class="card-header">#}
<h5 class="m-0 font-weight-bold text-primary">Integrated Evaluation</h5> {# <h5 class="m-0 font-weight-bold text-primary">Integrated Evaluation</h5>#}
</div> {# </div>#}
{##}
<!--card body --> {# <!--card body -->#}
<div class="card-body"> {# <div class="card-body">#}
<div class="text-center" id="integrate_message"> {# <div class="text-center" id="integrate_message">#}
<span class="font-italic">The integrated version student and lecturer evaluations will display here.</span> {# <span class="font-italic">The integrated version student and lecturer evaluations will display here.</span>#}
</div> {# </div>#}
{##}
<!--button --> {# <!--button -->#}
<div class="text-right m-4"> {# <div class="text-right m-4">#}
<button type="button" class="btn btn-outline-success" id="integrate_emotion"> {# <button type="button" class="btn btn-outline-success" id="integrate_emotion">#}
Process {# Process#}
</button> {# </button>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
<!--end of 2nd column --> {# <!--end of 2nd column -->#}
</div> </div>
<!--end of 3rd row --> <!--end of 3rd row -->
......
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
<!-- Core plugin JavaScript--> <!-- Core plugin JavaScript-->
<script src="{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"></script> <script src="{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
<!-- canvasJS implementation -->
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
...@@ -31,10 +36,15 @@ ...@@ -31,10 +36,15 @@
var global_lecturer_subject_index = 0; var global_lecturer_subject_index = 0;
var global_lecturer_video_name = ''; var global_lecturer_video_name = '';
var lecturer_fps = 0; var lecturer_fps = 0;
var lecture_gaze_frame_group_percentages = {};
//jquery //jquery
$(document).ready(function () { $(document).ready(function () {
//hide the 'integrate gaze' button
$('#integrate_gaze').hide();
//select a particular subject //select a particular subject
$('input[type=radio]').click(function () { $('input[type=radio]').click(function () {
let subject_id = $(this).attr('id'); let subject_id = $(this).attr('id');
...@@ -144,8 +154,8 @@ ...@@ -144,8 +154,8 @@
$('#video_name').text(video.video_name); $('#video_name').text(video.video_name);
$('#video_duration').text(video.video_length); $('#video_duration').text(video.video_length);
$('#video_date').text(video.date); $('#video_date').text(video.date);
{#global_lecture_video_id = video.lecture_video_id;#} global_lecture_video_id = video.lecture_video_id;
global_lecture_video_id = video.id; {#global_lecture_video_id = video.id;#}
global_video_name = video.video_name; global_video_name = video.video_name;
...@@ -157,6 +167,9 @@ ...@@ -157,6 +167,9 @@
} }
$('#video_modal').modal(); $('#video_modal').modal();
//show the 'integrate gaze' button
$('#integrate_gaze').show();
} }
...@@ -247,9 +260,9 @@ ...@@ -247,9 +260,9 @@
//fetch the lecture recorded video name //fetch the lecture recorded video name
fetch('http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=' + global_lecturer + '&subject=' + global_subject + '&date=' + global_lecture_date) fetch('http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=' + global_lecturer + '&subject=' + global_subject + '&date=' + global_lecture_date)
.then((res) => res.json()) .then((res) => res.json())
.then((out) => assignLecturerRecordedVideoName(out)) .then((out) => assignLecturerRecordedVideoName(out))
.catch((err) => alert('error: ' + err)); .catch((err) => alert('error: ' + err));
{#global_lecturer_video_name = "Test_1.mp4";#} {#global_lecturer_video_name = "Test_1.mp4";#}
{#global_lecturer_video_name = "Test_2.mp4";#} {#global_lecturer_video_name = "Test_2.mp4";#}
...@@ -520,6 +533,150 @@ ...@@ -520,6 +533,150 @@
}); });
//this function will handle the activity 'summary' button
$('#graph-tab').click(function (e) {
//display the graph loader
$('#graph_loader').attr('hidden', false);
//fetch the video time landmark details
fetch('http://127.0.0.1:8000/get-lecture-video-summary-time-landmarks/?video_name=' + global_video_name)
.then((res) => res.json())
.then((out) => assignTimeLandmarks(out.response))
.catch((err) => alert('error: ' + err));
//fetch the gaze summary details
fetch('http://127.0.0.1:8000/get-lecture-gaze-summary/?video_name=' + global_video_name)
.then((res) => res.json())
.then((out) => gazeFrameGroupPercentages(out, e))
.catch((err) => alert('error: ' + err));
});
//this function will assign lecture video time landmarks
function assignTimeLandmarks(response) {
lecture_video_time_landmarks = response;
}
//this function will handle the retrieved gaze frame group percentages
function gazeFrameGroupPercentages(response, e) {
lecture_gaze_frame_group_percentages = response.frame_group_percentages;
let frame_landmarks = response.frame_landmarks;
let gaze_labels = response.gaze_labels;
//render the chart onto the modal body
renderGazeChart(gaze_labels);
}
//this function will call the chart function
function renderGazeChart(gaze_labels) {
//get the activity label length
let gaze_label_length = gaze_labels.length;
let data = [];
//loop through the activity labels
for (let k = 0; k < gaze_label_length; k++) {
let label = gaze_labels[k];
let datapoints = [];
let count = 0;
//loop through the activity frame groups
for (let key in lecture_gaze_frame_group_percentages) {
let frame_group_details = lecture_gaze_frame_group_percentages[key];
let gaze_perct = frame_group_details[label];
let point = {label: lecture_video_time_landmarks[count], y: gaze_perct};
datapoints.push(point);
count++;
}
let obj = {
type: "line",
showInLegend: true,
name: label,
markerType: "square",
{#xValueFormatString: "DD MMM, YYYY",#}
xValueFormatString: "hh:mm:ss",
color: getRandomColor(),
dataPoints: datapoints
};
data.push(obj);
}
var chart = new CanvasJS.Chart("GazeChartContainer", {
animationEnabled: true,
theme: "light2",
title: {
text: "Student Gaze estimation Behavior"
},
axisX: {
title: "Duration",
{#valueFormatString: "DD MMM",#}
valueFormatString: "hh:mm:ss",
crosshair: {
enabled: true,
snapToDataPoint: true
}
},
axisY: {
title: "Percentage",
includeZero: true,
crosshair: {
enabled: true
}
},
toolTip: {
shared: true
},
legend: {
cursor: "pointer",
verticalAlign: "top",
horizontalAlign: "right",
dockInsidePlotArea: true,
itemclick: toogleDataSeries
},
data: data
});
chart.render();
}
//this function will generate random colors
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
//this function will toggle the content
function toogleDataSeries(e) {
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}); });
</script> </script>
...@@ -771,53 +928,26 @@ ...@@ -771,53 +928,26 @@
aria-labelledby="profile-tab"> aria-labelledby="profile-tab">
<!--card content --> <!--card content -->
<div class="card shadow mb-4 p-3"> <div class="card shadow mb-4 p-3">
<!-- Card Header - Dropdown -->
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Student
Activities</h6>
<div class="dropdown no-arrow">
<a class="dropdown-toggle" href="#" role="button"
id="dropdownMenuLink" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
</a>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
aria-labelledby="dropdownMenuLink">
<div class="dropdown-header">Dropdown Header:</div>
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</div>
</div>
<!-- Card Body --> <!-- Card Body -->
<div class="card-body"> <div class="card-body">
<div class="chart-pie pt-4 pb-2"> <div id="GazeChartContainer"
<canvas id="myPieChart"></canvas> style="height: 370px; max-width: 920px; margin: 0px auto;"></div>
</div>
<div class="mt-4 text-center small">
<span class="mr-2">
<i class="fas fa-circle text-primary"></i> Direct
</span>
<span class="mr-2">
<i class="fas fa-circle text-success"></i> Social
</span>
<span class="mr-2">
<i class="fas fa-circle text-info"></i> Referral
</span>
</div>
</div> </div>
</div> </div>
<!-- End of Card Body -->
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- end of 1st column -->
<!--2nd column --> <!--2nd column -->
...@@ -846,17 +976,11 @@ ...@@ -846,17 +976,11 @@
</div> </div>
</div> </div>
<!--end of 2nd column --> <!--end of 2nd column -->
</div> </div>
<!-- end of 2nd row -->
<!--3rd row -->
<div class="row p-2">
</div> {# </div>#}
<!--end of 3rd row --> <!-- end of 2nd row -->
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment