Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
2
2020-101
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Sachith Fernando
2020-101
Commits
e3c708cb
Commit
e3c708cb
authored
Jan 04, 2021
by
I.K Seneviratne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Committing the implementations of displaying graphs on activity, emotion and gaze individual pages.
parent
a7659974
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
697 additions
and
236 deletions
+697
-236
FirstApp/api.py
FirstApp/api.py
+8
-3
FirstApp/serializers.py
FirstApp/serializers.py
+6
-1
FirstApp/templates/FirstApp/activity.html
FirstApp/templates/FirstApp/activity.html
+230
-60
FirstApp/templates/FirstApp/emotion.html
FirstApp/templates/FirstApp/emotion.html
+281
-124
FirstApp/templates/FirstApp/gaze.html
FirstApp/templates/FirstApp/gaze.html
+172
-48
No files found.
FirstApp/api.py
View file @
e3c708cb
...
...
@@ -168,13 +168,17 @@ class LectureVideoViewSet(APIView):
# serializer = LectureVideoSerializer(data=request.data, many=True)
serializer
=
LectureVideoSerializer
(
data
=
request
.
data
)
# serializer.create(validated_data=request.data)
data
=
{}
data_ser
=
{}
if
serializer
.
is_valid
(
raise_exception
=
ValueError
):
print
(
'valid'
)
serializer
.
create
(
validated_data
=
request
.
data
)
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,
...
...
@@ -462,6 +466,7 @@ class GetLectureEmotionReportViewSet(APIView):
lecture_emotions
=
LectureEmotionReport
.
objects
.
filter
(
lecture_video_id__lecture_video_id
=
lecture_video_id
)
serializer
=
LectureEmotionSerializer
(
lecture_emotions
,
many
=
True
)
print
(
'data: '
,
serializer
.
data
)
return
Response
({
"response"
:
serializer
.
data
,
...
...
FirstApp/serializers.py
View file @
e3c708cb
...
...
@@ -275,6 +275,11 @@ class LectureVideoSerializer(serializers.ModelSerializer):
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')
# serialized_faculty = FacultySerializer(data=faculty_data)
#
...
...
@@ -294,7 +299,7 @@ class LectureVideoSerializer(serializers.ModelSerializer):
#
# return lecturer
#
return
lecture_video
return
create_lecture_video_ser_data
return
None
...
...
FirstApp/templates/FirstApp/activity.html
View file @
e3c708cb
...
...
@@ -21,6 +21,11 @@
<!-- Core plugin JavaScript-->
<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"
>
...
...
@@ -32,12 +37,16 @@
var
global_lecture_date
=
''
;
var
global_lecturer_video_name
=
''
;
var
lecturer_fps
=
0
;
var
lecture_activity_frame_group_percentages
=
{};
var
lecture_video_time_landmarks
=
[];
;
//jquery
$
(
document
).
ready
(
function
()
{
//disable the 'integrate_activity' button
$
(
'
#integrate_activity
'
).
hide
();
//select a particular subject
$
(
'
input[type=radio]
'
).
click
(
function
()
{
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
...
...
@@ -76,6 +85,7 @@
let
real_class
=
clicked_class
.
split
(
'
'
)[
1
];
real_class
=
'
.
'
+
real_class
;
let
date
=
e
.
target
.
parentNode
.
parentNode
.
firstChild
.
innerHTML
;
//assign the date
global_lecture_date
=
date
;
...
...
@@ -161,6 +171,9 @@
$
(
'
#generate_report_before
'
).
attr
(
'
disabled
'
,
false
);
$
(
'
#video_modal
'
).
modal
();
//display the 'integrate activity' button
$
(
'
#integrate_activity
'
).
show
();
}
//binding a click event for 'btn-primary' buttons
...
...
@@ -254,16 +267,15 @@
//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
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_3.mp4
"
;
#
}
//fetch data from the API
fetch
(
'
http://127.0.0.1:8000/get-lecture-activity-for-frame?video_name=
'
+
global_video_name
)
.
then
((
res
)
=>
res
.
json
())
...
...
@@ -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
+
'
¬e_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>
...
...
@@ -702,18 +873,18 @@
<!--this area will display the progress bars -->
<div
class=
"progress_area mt-4"
hidden
>
<!--talking with friends -->
<a
href=
"#"
class=
"btn btn-link labels"
data-number=
"1"
data-label=
"talking-with-friends"
>
<h4
class=
"small font-weight-bold"
>
Talking with friends
</h4>
</a>
<span
class=
"float-right"
id=
"talking_perct"
>
40%
</span>
<div
class=
"progress mb-4"
>
<div
class=
"progress-bar bg-danger"
role=
"progressbar"
id=
"talking_width"
style=
"width: 20%"
aria-valuenow=
"20"
aria-valuemin=
"0"
aria-valuemax=
"100"
></div>
</div>
{#
<a
href=
"#"
class=
"btn btn-link labels"
data-number=
"1"
#
}
{
#
data-label=
"talking-with-friends"
>
#}
{#
<h4
class=
"small font-weight-bold"
>
Talking with friends
</h4>
#}
{#
</a>
#}
{#
<span
class=
"float-right"
id=
"talking_perct"
>
40%
</span>
#}
{#
<div
class=
"progress mb-4"
>
#}
{#
<div
class=
"progress-bar bg-danger"
role=
"progressbar"
#
}
{
#
id=
"talking_width"
#
}
{
#
style=
"width: 20%"
#
}
{
#
aria-valuenow=
"20"
aria-valuemin=
"0"
#
}
{
#
aria-valuemax=
"100"
></div>
#}
{#
</div>
#}
<!--phone checking -->
<a
href=
"#"
class=
"btn btn-link labels"
data-number=
"0"
...
...
@@ -765,46 +936,45 @@
<!--graph tab -->
<div
class=
"tab-pane fade"
id=
"graph"
role=
"tabpanel"
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 -->
<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 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 -->
<div
class=
"card-body"
>
<div
class=
"chart-pie pt-4 pb-2"
>
<canvas
id=
"myPieChart"
></canvas>
</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
id=
"ActivityChartContainer"
style=
"height: 370px; max-width: 920px; margin: 0px auto;"
></div>
</div>
<!-- End of Card Body -->
</div>
</div>
</div>
...
...
@@ -1084,11 +1254,11 @@
type=
"video/mp4"
>
Your browser does not support the video tag.
</video>
{#
<video
width=
"500"
height=
"300"
id=
"student_video"
controls
>
#}
{#
<source
src=
"{% static 'FirstApp/videos/Video_test_2.mp4' %}"
#
}
{
#
type=
"video/mp4"
>
#}
{# Your browser does not support the video tag.#}
{#
</video>
#}
{#
<video
width=
"500"
height=
"300"
id=
"student_video"
controls
>
#}
{#
<source
src=
"{% static 'FirstApp/videos/Video_test_2.mp4' %}"
#
}
{
#
type=
"video/mp4"
>
#}
{# Your browser does not support the video tag.#}
{#
</video>
#}
</div>
<!--end of student video section -->
...
...
@@ -1155,10 +1325,10 @@
<!--display lecture video -->
<div
class=
"text-center m-3"
id=
"lecturer_video_section"
>
{#
<!--temporary text -->
#}
{#
<div
class=
"text-center"
id=
"temp_lecturer_text"
>
#}
{#
<span
class=
"font-italic"
>
No video was found
</span>
#}
{#
</div>
#}
{#
<!--temporary text -->
#}
{#
<div
class=
"text-center"
id=
"temp_lecturer_text"
>
#}
{#
<span
class=
"font-italic"
>
No video was found
</span>
#}
{#
</div>
#}
<!--display lecturer video -->
...
...
FirstApp/templates/FirstApp/emotion.html
View file @
e3c708cb
...
...
@@ -21,6 +21,9 @@
<!-- Core plugin JavaScript-->
<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"
>
...
...
@@ -31,10 +34,16 @@
var
global_lecturer_subject_index
=
0
;
var
global_lecturer_video_name
=
''
;
var
lecturer_fps
=
0
;
var
lecture_emotion_frame_group_percentages
=
{};
var
lecture_video_time_landmarks
=
[];
//jquery
$
(
document
).
ready
(
function
()
{
//hide the 'integrate emotion' button
$
(
'
#integrate_emotion
'
).
hide
();
//select a particular subject
$
(
'
input[type=radio]
'
).
click
(
function
()
{
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
...
...
@@ -145,8 +154,8 @@
$
(
'
#video_name
'
).
text
(
video
.
video_name
);
$
(
'
#video_duration
'
).
text
(
video
.
video_length
);
$
(
'
#video_date
'
).
text
(
video
.
date
);
{
#
global_lecture_video_id
=
video
.
lecture_video_id
;
#
}
global_lecture_video_id
=
video
.
id
;
global_lecture_video_id
=
video
.
lecture_video_id
;
{
#
global_lecture_video_id
=
video
.
id
;
#
}
global_video_name
=
video
.
video_name
;
...
...
@@ -157,6 +166,9 @@
}
$
(
'
#video_modal
'
).
modal
();
//display the 'integrate emotion' button
$
(
'
#integrate_emotion
'
).
show
();
}
//binding a click event for 'btn-primary' buttons
...
...
@@ -255,9 +267,9 @@
//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
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
...
...
@@ -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>
...
...
@@ -787,122 +944,122 @@
</div>
<!-- end of frame tab -->
<!--graph tab -->
<div
class=
"tab-pane fade"
id=
"graph"
role=
"tabpanel"
aria-labelledby=
"profile-tab"
>
<!--card content -->
<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 -->
<div
class=
"card-body"
>
<div
class=
"chart-pie pt-4 pb-2"
>
<canvas
id=
"myPieChart"
></canvas>
</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
id=
"EmotionChartContainer"
style=
"height: 270px; max-width: 920px; margin: 0px auto;"
></div>
</div>
<!-- End of Card Body -->
</div>
</div>
</div>
</div>
</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
class=
"col-lg-6"
>
<!--card -->
<div
class=
"card shadow mb-4"
>
<!--card header -->
<div
class=
"card-header"
>
<h5
class=
"m-0 font-weight-bold text-primary"
>
Integrated Evaluation
</h5>
</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>
<!--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 -->
<!--3rd row -->
...
...
@@ -941,32 +1098,32 @@
{#
</div>
#}
<!--end of 1st column -->
<!--2nd column -->
<div
class=
"col-lg-6"
>
<!--card -->
<div
class=
"card shadow mb-4"
>
<!--card header -->
<div
class=
"card-header"
>
<h5
class=
"m-0 font-weight-bold text-primary"
>
Integrated Evaluation
</h5>
</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 -->
{##}
{#
<!--2nd column -->
#}
{#
<div
class=
"col-lg-6"
>
#}
{#
<!--card -->
#}
{#
<div
class=
"card shadow mb-4"
>
#}
{#
<!--card header -->
#}
{#
<div
class=
"card-header"
>
#}
{#
<h5
class=
"m-0 font-weight-bold text-primary"
>
Integrated Evaluation
</h5>
#}
{#
</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>
<!--end of 3rd row -->
...
...
FirstApp/templates/FirstApp/gaze.html
View file @
e3c708cb
...
...
@@ -21,6 +21,11 @@
<!-- Core plugin JavaScript-->
<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"
>
...
...
@@ -31,10 +36,15 @@
var
global_lecturer_subject_index
=
0
;
var
global_lecturer_video_name
=
''
;
var
lecturer_fps
=
0
;
var
lecture_gaze_frame_group_percentages
=
{};
//jquery
$
(
document
).
ready
(
function
()
{
//hide the 'integrate gaze' button
$
(
'
#integrate_gaze
'
).
hide
();
//select a particular subject
$
(
'
input[type=radio]
'
).
click
(
function
()
{
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
...
...
@@ -144,8 +154,8 @@
$
(
'
#video_name
'
).
text
(
video
.
video_name
);
$
(
'
#video_duration
'
).
text
(
video
.
video_length
);
$
(
'
#video_date
'
).
text
(
video
.
date
);
{
#
global_lecture_video_id
=
video
.
lecture_video_id
;
#
}
global_lecture_video_id
=
video
.
id
;
global_lecture_video_id
=
video
.
lecture_video_id
;
{
#
global_lecture_video_id
=
video
.
id
;
#
}
global_video_name
=
video
.
video_name
;
...
...
@@ -157,6 +167,9 @@
}
$
(
'
#video_modal
'
).
modal
();
//show the 'integrate gaze' button
$
(
'
#integrate_gaze
'
).
show
();
}
...
...
@@ -247,9 +260,9 @@
//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
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
...
...
@@ -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>
...
...
@@ -771,53 +928,26 @@
aria-labelledby=
"profile-tab"
>
<!--card content -->
<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 -->
<div
class=
"card-body"
>
<div
class=
"chart-pie pt-4 pb-2"
>
<canvas
id=
"myPieChart"
></canvas>
</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
id=
"GazeChartContainer"
style=
"height: 370px; max-width: 920px; margin: 0px auto;"
></div>
</div>
</div>
<!-- End of Card Body -->
</div>
</div>
</div>
</div>
</div>
<!-- end of 1st column -->
<!--2nd column -->
...
...
@@ -846,17 +976,11 @@
</div>
</div>
<!--end of 2nd column -->
</div>
<!-- end of 2nd row -->
<!--3rd row -->
<div
class=
"row p-2"
>
</div>
<!--
end of 3r
d row -->
{#
</div>
#}
<!--
end of 2n
d row -->
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment