Commit 1cabfb25 authored by I.K Seneviratne's avatar I.K Seneviratne

Committing the partial implementations of the graphical representations of...

Committing the partial implementations of the graphical representations of Emotion and Gaze components in the lecturer Home page.
parent edf1f457
...@@ -202,6 +202,40 @@ class LectureEmotionReport(models.Model): ...@@ -202,6 +202,40 @@ class LectureEmotionReport(models.Model):
return self.lecture_emotion_id return self.lecture_emotion_id
# this abstract class will define the lecture emotion frame group percentages
class LectureEmotionFrameGroupPercentages(models.Model):
happy_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
sad_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
angry_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
disgust_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
surprise_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
neutral_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
class Meta:
abstract = True
# this abstract class will define the details for an emotion frame group
class LectureEmotionFrameGroupDetails(models.Model):
frame_group = models.CharField(max_length=10)
frame_group_percentages = models.EmbeddedField(
model_container=LectureEmotionFrameGroupPercentages
)
class Meta:
abstract = True
# this class will contain the emotion frame groupings
class LectureEmotionFrameGroupings(models.Model):
lecture_emotion_frame_groupings_id = models.CharField(max_length=15, default="")
lecture_emotion_id = models.ForeignKey(LectureEmotionReport, on_delete=models.CASCADE)
frame_group_details = models.ArrayField(model_container=LectureEmotionFrameGroupDetails)
def __str__(self):
return self.lecture_emotion_frame_groupings_id
# POSE section # POSE section
# lecture pose estimation # lecture pose estimation
class LectureGazeEstimation(models.Model): class LectureGazeEstimation(models.Model):
...@@ -214,4 +248,37 @@ class LectureGazeEstimation(models.Model): ...@@ -214,4 +248,37 @@ class LectureGazeEstimation(models.Model):
looking_front_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1) looking_front_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
def __str__(self): def __str__(self):
return self.lecture_gaze_id return self.lecture_gaze_id
\ No newline at end of file
# this abstract class will define the lecture gaze frame group percentages
class LectureGazeFrameGroupPercentages(models.Model):
looking_up_and_right_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
looking_up_and_left_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
looking_down_and_right_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
looking_down_and_left_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
looking_front_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
class Meta:
abstract = True
# this abstract class will define the details for a gaze frame group
class LectureGazeFrameGroupDetails(models.Model):
frame_group = models.CharField(max_length=10)
frame_group_percentages = models.EmbeddedField(
model_container=LectureGazeFrameGroupPercentages
)
class Meta:
abstract = True
# this class will contain the gaze frame groupings
class LectureGazeFrameGroupings(models.Model):
lecture_gaze_frame_groupings_id = models.CharField(max_length=15, default="")
lecture_gaze_id = models.ForeignKey(LectureGazeEstimation, on_delete=models.CASCADE)
frame_group_details = models.ArrayField(model_container=LectureGazeFrameGroupDetails)
def __str__(self):
return self.lecture_gaze_frame_groupings_id
...@@ -953,3 +953,246 @@ class GetLectureActivitySummary(APIView): ...@@ -953,3 +953,246 @@ class GetLectureActivitySummary(APIView):
# "activity_labels": activity_labels # "activity_labels": activity_labels
# }) # })
# this API will retrieve lecture emotion summary
class GetLectureEmotionSummary(APIView):
def get(self, request):
video_name = request.query_params.get('video_name')
# checking the existence of lecture activity frame grouping records in the db
isExist = LectureEmotionFrameGroupings.objects.filter(lecture_emotion_id__lecture_video_id__video_name=video_name).exists()
if (isExist):
frame_group_percentages = {}
frame_landmarks = []
# retrieve frame landmarks from db
lec_video_frame_landmarks = LectureVideoFrameLandmarks.objects.filter(lecture_video_id__video_name=video_name)
lec_video_frame_landmarks_ser = LectureVideoFrameLandmarksSerializer(lec_video_frame_landmarks, many=True)
lec_video_frame_landmarks_data = lec_video_frame_landmarks_ser.data[0]
retrieved_frame_landmarks = lec_video_frame_landmarks_data["frame_landmarks"]
for landmark in retrieved_frame_landmarks:
frame_landmarks.append(landmark['landmark'])
lec_emotion_frame_groupings = LectureEmotionFrameGroupings.objects.filter(lecture_emotion_id__lecture_video_id__video_name=video_name)
lec_emotion_frame_groupings_ser = LectureEmotionFrameGroupingsSerializer(lec_emotion_frame_groupings, many=True)
lec_emotion_frame_groupings_data = lec_emotion_frame_groupings_ser.data[0]
frame_group_details = lec_emotion_frame_groupings_data["frame_group_details"]
# create the new dictionary
for group in frame_group_details:
frame_group_percentages[group['frame_group']] = group['frame_group_percentages']
class_labels = ['happy_perct', 'sad_perct', 'angry_perct', 'disgust_perct', 'surprise_perct', 'neutral_perct']
return Response({
"frame_landmarks": frame_landmarks,
"frame_group_percentages": frame_group_percentages,
"emotion_labels": class_labels
})
else:
# retrieve the previous lecture video frame landmarks details
last_lec_video_frame_landmarks = LectureVideoFrameLandmarks.objects.order_by(
'lecture_video_frame_landmarks_id').last()
new_lecture_video_frame_landmarks_id = "LVFL00001" if (last_lec_video_frame_landmarks is None) else \
ig.generate_new_id(last_lec_video_frame_landmarks.lecture_video_frame_landmarks_id)
frame_landmarks, frame_group_dict = ve.getFrameLandmarks(video_name)
frame_group_percentages, activity_labels = ar.activity_frame_groupings(video_name, frame_landmarks, frame_group_dict)
# retrieve lecture video details
lec_video = LectureVideo.objects.filter(video_name=video_name)
lec_video_ser = LectureVideoSerializer(lec_video, many=True)
lec_video_id = lec_video_ser.data[0]['id']
# save the frame landmarks details into db (temp method)
db_frame_landmarks = []
for landmark in frame_landmarks:
landmark_obj = Landmarks()
landmark_obj.landmark = landmark
db_frame_landmarks.append(landmark_obj)
new_lec_video_frame_landmarks = LectureVideoFrameLandmarks()
new_lec_video_frame_landmarks.lecture_video_frame_landmarks_id = new_lecture_video_frame_landmarks_id
new_lec_video_frame_landmarks.lecture_video_id_id = lec_video_id
new_lec_video_frame_landmarks.frame_landmarks = db_frame_landmarks
new_lec_video_frame_landmarks.save()
# save the frame group details into db (temp method)
last_lec_activity_frame_grouping = LectureActivityFrameGroupings.objects.order_by('lecture_activity_frame_groupings_id').last()
new_lecture_activity_frame_grouping_id = "LAFG00001" if (last_lec_activity_frame_grouping is None) else \
ig.generate_new_id(last_lec_activity_frame_grouping.lecture_activity_frame_groupings_id)
# retrieve the lecture activity id
lec_activity = LectureActivity.objects.filter(lecture_video_id__video_name=video_name)
lec_activity_ser = LectureActivitySerializer(lec_activity, many=True)
lec_activity_id = lec_activity_ser.data[0]['id']
# create the frame group details
frame_group_details = []
for key in frame_group_percentages.keys():
# create an object of type 'LectureActivityFrameGroupDetails'
lec_activity_frame_group_details = LectureActivityFrameGroupDetails()
lec_activity_frame_group_details.frame_group = key
lec_activity_frame_group_details.frame_group_percentages = frame_group_percentages[key]
frame_group_details.append(lec_activity_frame_group_details)
new_lec_activity_frame_groupings = LectureActivityFrameGroupings()
new_lec_activity_frame_groupings.lecture_activity_frame_groupings_id = new_lecture_activity_frame_grouping_id
new_lec_activity_frame_groupings.lecture_activity_id_id = lec_activity_id
new_lec_activity_frame_groupings.frame_group_details = frame_group_details
# save
new_lec_activity_frame_groupings.save()
return Response({
"frame_landmarks": frame_landmarks,
"frame_group_percentages": frame_group_percentages,
"activity_labels": activity_labels
})
# this API will retrieve lecture gaze summary
class GetLectureGazeSummary(APIView):
def get(self, request):
video_name = request.query_params.get('video_name')
# checking the existence of lecture activity frame grouping records in the db
isExist = LectureActivityFrameGroupings.objects.filter(lecture_activity_id__lecture_video_id__video_name=video_name).exists()
if (isExist):
# frame_landmarks, frame_group_dict = ve.getFrameLandmarks(video_name)
frame_group_percentages = {}
frame_landmarks = []
# retrieve frame landmarks from db
lec_video_frame_landmarks = LectureVideoFrameLandmarks.objects.filter(lecture_video_id__video_name=video_name)
lec_video_frame_landmarks_ser = LectureVideoFrameLandmarksSerializer(lec_video_frame_landmarks, many=True)
lec_video_frame_landmarks_data = lec_video_frame_landmarks_ser.data[0]
retrieved_frame_landmarks = lec_video_frame_landmarks_data["frame_landmarks"]
for landmark in retrieved_frame_landmarks:
frame_landmarks.append(landmark['landmark'])
lec_activity_frame_groupings = LectureActivityFrameGroupings.objects.filter(lecture_activity_id__lecture_video_id__video_name=video_name)
lec_activity_frame_groupings_ser = LectureActivityFrameGroupingsSerializer(lec_activity_frame_groupings, many=True)
lec_activity_frame_groupings_data = lec_activity_frame_groupings_ser.data[0]
frame_group_details = lec_activity_frame_groupings_data["frame_group_details"]
# create the new dictionary
for group in frame_group_details:
frame_group_percentages[group['frame_group']] = group['frame_group_percentages']
class_labels = ['phone_perct', 'listen_perct', 'note_perct']
return Response({
"frame_landmarks": frame_landmarks,
"frame_group_percentages": frame_group_percentages,
"activity_labels": class_labels
})
# else:
#
# # retrieve the previous lecture video frame landmarks details
# last_lec_video_frame_landmarks = LectureVideoFrameLandmarks.objects.order_by(
# 'lecture_video_frame_landmarks_id').last()
# new_lecture_video_frame_landmarks_id = "LVFL00001" if (last_lec_video_frame_landmarks is None) else \
# ig.generate_new_id(last_lec_video_frame_landmarks.lecture_video_frame_landmarks_id)
#
#
# frame_landmarks, frame_group_dict = ve.getFrameLandmarks(video_name)
# frame_group_percentages, activity_labels = ar.activity_frame_groupings(video_name, frame_landmarks, frame_group_dict)
#
#
# # retrieve lecture video details
# lec_video = LectureVideo.objects.filter(video_name=video_name)
# lec_video_ser = LectureVideoSerializer(lec_video, many=True)
# lec_video_id = lec_video_ser.data[0]['id']
#
#
# # save the frame landmarks details into db (temp method)
# db_frame_landmarks = []
#
# for landmark in frame_landmarks:
# landmark_obj = Landmarks()
# landmark_obj.landmark = landmark
#
# db_frame_landmarks.append(landmark_obj)
#
#
# new_lec_video_frame_landmarks = LectureVideoFrameLandmarks()
# new_lec_video_frame_landmarks.lecture_video_frame_landmarks_id = new_lecture_video_frame_landmarks_id
# new_lec_video_frame_landmarks.lecture_video_id_id = lec_video_id
# new_lec_video_frame_landmarks.frame_landmarks = db_frame_landmarks
#
# new_lec_video_frame_landmarks.save()
#
#
#
# # save the frame group details into db (temp method)
#
# last_lec_activity_frame_grouping = LectureActivityFrameGroupings.objects.order_by('lecture_activity_frame_groupings_id').last()
# new_lecture_activity_frame_grouping_id = "LAFG00001" if (last_lec_activity_frame_grouping is None) else \
# ig.generate_new_id(last_lec_activity_frame_grouping.lecture_activity_frame_groupings_id)
#
# # retrieve the lecture activity id
# lec_activity = LectureActivity.objects.filter(lecture_video_id__video_name=video_name)
# lec_activity_ser = LectureActivitySerializer(lec_activity, many=True)
# lec_activity_id = lec_activity_ser.data[0]['id']
#
# # create the frame group details
# frame_group_details = []
#
# for key in frame_group_percentages.keys():
# # create an object of type 'LectureActivityFrameGroupDetails'
# lec_activity_frame_group_details = LectureActivityFrameGroupDetails()
# lec_activity_frame_group_details.frame_group = key
# lec_activity_frame_group_details.frame_group_percentages = frame_group_percentages[key]
#
# frame_group_details.append(lec_activity_frame_group_details)
#
#
# new_lec_activity_frame_groupings = LectureActivityFrameGroupings()
# new_lec_activity_frame_groupings.lecture_activity_frame_groupings_id = new_lecture_activity_frame_grouping_id
# new_lec_activity_frame_groupings.lecture_activity_id_id = lec_activity_id
# new_lec_activity_frame_groupings.frame_group_details = frame_group_details
#
# # save
# new_lec_activity_frame_groupings.save()
#
#
# return Response({
# "frame_landmarks": frame_landmarks,
# "frame_group_percentages": frame_group_percentages,
# "activity_labels": activity_labels
# })
\ No newline at end of file
# Generated by Django 2.2.11 on 2020-10-09 16:58
import FirstApp.MongoModels
from django.db import migrations, models
import django.db.models.deletion
import djongo.models.fields
class Migration(migrations.Migration):
dependencies = [
('FirstApp', '0010_lecturevideoframelandmarks_lecturevideotimelandmarks'),
]
operations = [
migrations.CreateModel(
name='LectureGazeFrameGroupings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lecture_gaze_frame_groupings_id', models.CharField(default='', max_length=15)),
('frame_group_details', djongo.models.fields.ArrayField(model_container=FirstApp.MongoModels.LectureGazeFrameGroupDetails)),
('lecture_gaze_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='FirstApp.LectureGazeEstimation')),
],
),
migrations.CreateModel(
name='LectureEmotionFrameGroupings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lecture_emotion_frame_groupings_id', models.CharField(default='', max_length=15)),
('frame_group_details', djongo.models.fields.ArrayField(model_container=FirstApp.MongoModels.LectureEmotionFrameGroupDetails)),
('lecture_emotion_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='FirstApp.LectureEmotionReport')),
],
),
]
...@@ -246,7 +246,7 @@ class LectureVideoFrameLandmarksSerializer(serializers.ModelSerializer): ...@@ -246,7 +246,7 @@ class LectureVideoFrameLandmarksSerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
# Lecture activity serializer
class LectureActivitySerializer(serializers.ModelSerializer): class LectureActivitySerializer(serializers.ModelSerializer):
lecture_video_id = LectureVideoSerializer() lecture_video_id = LectureVideoSerializer()
...@@ -256,6 +256,7 @@ class LectureActivitySerializer(serializers.ModelSerializer): ...@@ -256,6 +256,7 @@ class LectureActivitySerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
# Lecture Activity Frame Group Serializer
class LectureActivityFrameGroupingsSerializer(serializers.ModelSerializer): class LectureActivityFrameGroupingsSerializer(serializers.ModelSerializer):
lecture_activity_id = LectureActivitySerializer() lecture_activity_id = LectureActivitySerializer()
...@@ -292,6 +293,38 @@ class LectureEmotionSerializer(serializers.ModelSerializer): ...@@ -292,6 +293,38 @@ class LectureEmotionSerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
# Lecture emotion Frame Group Serializer
class LectureEmotionFrameGroupingsSerializer(serializers.ModelSerializer):
lecture_emotion_id = LectureEmotionSerializer()
frame_group_details = serializers.SerializerMethodField()
def get_frame_group_details(self, obj):
return_data = []
for frame_group in obj.frame_group_details:
group_details = {}
group_details["frame_group_percentages"] = {}
group_details["frame_group"] = frame_group.frame_group
group_details["frame_group_percentages"]["happy_perct"] = frame_group.frame_group_percentages.happy_perct
group_details["frame_group_percentages"]["sad_perct"] = frame_group.frame_group_percentages.sad_perct
group_details["frame_group_percentages"]["angry_perct"] = frame_group.frame_group_percentages.angry_perct
group_details["frame_group_percentages"]["disgust_perct"] = frame_group.frame_group_percentages.disgust_perct
group_details["frame_group_percentages"]["surprise_perct"] = frame_group.frame_group_percentages.surprise_perct
group_details["frame_group_percentages"]["neutral_perct"] = frame_group.frame_group_percentages.neutral_perct
return_data.append(group_details)
return return_data
class Meta:
model = LectureEmotionFrameGroupings
fields = '__all__'
# lecture video meta serializer # lecture video meta serializer
class VideoMetaSerializer(serializers.ModelSerializer): class VideoMetaSerializer(serializers.ModelSerializer):
...@@ -306,4 +339,34 @@ class LectureGazeEstimationSerializer(serializers.ModelSerializer): ...@@ -306,4 +339,34 @@ class LectureGazeEstimationSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = LectureGazeEstimation model = LectureGazeEstimation
fields = '__all__' fields = '__all__'
\ No newline at end of file
# Lecture emotion Frame Group Serializer
class LectureGazeFrameGroupingsSerializer(serializers.ModelSerializer):
lecture_gaze_id = LectureGazeEstimationSerializer()
frame_group_details = serializers.SerializerMethodField()
def get_frame_group_details(self, obj):
return_data = []
for frame_group in obj.frame_group_details:
group_details = {}
group_details["frame_group_percentages"] = {}
group_details["frame_group"] = frame_group.frame_group
group_details["frame_group_percentages"]["looking_up_and_right_perct"] = frame_group.frame_group_percentages.looking_up_and_right_perct
group_details["frame_group_percentages"]["looking_up_and_left_perct"] = frame_group.frame_group_percentages.looking_up_and_left_perct
group_details["frame_group_percentages"]["looking_down_and_right_perct"] = frame_group.frame_group_percentages.looking_down_and_right_perct
group_details["frame_group_percentages"]["looking_down_and_left_perct"] = frame_group.frame_group_percentages.looking_down_and_left_perct
group_details["frame_group_percentages"]["looking_front_perct"] = frame_group.frame_group_percentages.looking_front_perct
return_data.append(group_details)
return return_data
class Meta:
model = LectureGazeFrameGroupings
fields = '__all__'
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
var student_behavior_summary = {}; var student_behavior_summary = {};
var lecture_video_time_landmarks = []; var lecture_video_time_landmarks = [];
var lecture_activity_frame_group_percentages = {}; var lecture_activity_frame_group_percentages = {};
var lecture_emotion_frame_group_percentages = {};
var lecture_gaze_frame_group_percentages = {};
$(document).ready(function () { $(document).ready(function () {
...@@ -266,26 +268,33 @@ ...@@ -266,26 +268,33 @@
}); });
//this function will handle the emotion 'summary' button //this function will handle the emotion 'summary' button
$('#emotion_summary_btn').click(function () { $('#emotion_summary_btn').click(function (e) {
//open the modal
$('#summaryModal').modal();
//change the innerHTML of the clicked button
e.target.innerHTML = "<span class='font-italic'>Processing</span>";
//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));
//render the chart onto the modal body
renderChart();
}); });
//this function will handle the gaze 'summary' button //this function will handle the gaze 'summary' button
$('#gaze_summary_btn').click(function () { $('#gaze_summary_btn').click(function () {
//open the modal //change the innerHTML of the clicked button
$('#summaryModal').modal(); e.target.innerHTML = "<span class='font-italic'>Processing</span>";
//render the chart onto the modal body //fetch the activity summary details
renderChart(); 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 handle the retrieved activity frame group percentages //this function will handle the retrieved activity frame group percentages
function activityFrameGroupPercentages(response, e) { function activityFrameGroupPercentages(response, e) {
...@@ -299,16 +308,58 @@ ...@@ -299,16 +308,58 @@
e.target.innerHTML = "Summary"; e.target.innerHTML = "Summary";
//open the modal //open the modal
$('#summaryModal').modal(); $('#ActivitySummaryModal').modal();
//render the chart onto the modal body //render the chart onto the modal body
renderChart(activity_labels); renderActivityChart(activity_labels);
} }
//this function will call the chart function //this function will handle the retrieved emotion frame group percentages
function renderChart(activity_labels) { 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;
//change the button back to original
e.target.innerHTML = "Summary";
//open the modal
$('#EmotionSummaryModal').modal();
//render the chart onto the modal body
renderEmotionChart(emotion_labels);
}
//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;
//change the button back to original
e.target.innerHTML = "Summary";
//open the modal
$('#GazeSummaryModal').modal();
//render the chart onto the modal body
renderGazeChart(gaze_labels);
}
//this function will call the activity chart function
function renderActivityChart(activity_labels) {
//get the activity label length //get the activity label length
let activity_label_length = activity_labels.length; let activity_label_length = activity_labels.length;
...@@ -351,17 +402,176 @@ ...@@ -351,17 +402,176 @@
} }
//iterate through the time landmarks
var chart = new CanvasJS.Chart("ActivityChartContainer", {
animationEnabled: true,
theme: "light2",
title: {
text: "Student 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 call the emotion chart function
function renderEmotionChart(emotion_labels) {
//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("EmotionChartContainer", {
animationEnabled: true,
theme: "light2",
title: {
text: "Student 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 call the chart function
function renderGazeChart(gaze_labels) {
//get the activity label length
{#let activity_label_length = activity_labels.length;#}
let data = [];
/* /*
for (let i = 0; i < lecture_video_time_landmarks.length; i++) { //loop through the activity labels
let point = {label: lecture_video_time_landmarks[i], y: Number(Math.round(Math.random() * 1000), 0)}; 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);
datapoints.push(point);
} }
*/
*/
var chart = new CanvasJS.Chart("chartContainer", { var chart = new CanvasJS.Chart("GazeChartContainer", {
animationEnabled: true, animationEnabled: true,
theme: "light2", theme: "light2",
title: { title: {
...@@ -399,6 +609,7 @@ ...@@ -399,6 +609,7 @@
} }
//this function will render the chart for Activity statistics //this function will render the chart for Activity statistics
function renderActivityStatistics() { function renderActivityStatistics() {
...@@ -1571,8 +1782,52 @@ ...@@ -1571,8 +1782,52 @@
</div> </div>
<!-- end of logout modal --> <!-- end of logout modal -->
<!-- summary Modal--> <!-- activity summary Modal-->
<div class="modal fade" id="summaryModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" <div class="modal fade" id="ActivitySummaryModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document" style="max-width: 1300px">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Summary</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="ActivityChartContainer" style="height: 370px; max-width: 920px; margin: 0px auto;"></div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<!-- end of activity summary modal -->
<!-- emotion summary Modal-->
<div class="modal fade" id="EmotionSummaryModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document" style="max-width: 1300px">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Summary</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="EmotionChartContainer" style="height: 370px; max-width: 920px; margin: 0px auto;"></div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<!-- end of emotion summary modal -->
<!-- gaze summary Modal-->
<div class="modal fade" id="GazeSummaryModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true"> aria-hidden="true">
<div class="modal-dialog" role="document" style="max-width: 1300px"> <div class="modal-dialog" role="document" style="max-width: 1300px">
<div class="modal-content"> <div class="modal-content">
...@@ -1583,7 +1838,7 @@ ...@@ -1583,7 +1838,7 @@
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div id="chartContainer" style="height: 370px; max-width: 920px; margin: 0px auto;"></div> <div id="GazeChartContainer" style="height: 370px; max-width: 920px; margin: 0px auto;"></div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button> <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
...@@ -1591,7 +1846,7 @@ ...@@ -1591,7 +1846,7 @@
</div> </div>
</div> </div>
</div> </div>
<!-- end of summary modal --> <!-- end of gaze summary modal -->
<!-- student behavior view summary modal --> <!-- student behavior view summary modal -->
......
...@@ -181,6 +181,12 @@ urlpatterns = [ ...@@ -181,6 +181,12 @@ urlpatterns = [
# retrieves lecture activity summary # retrieves lecture activity summary
url(r'^get-lecture-activity-summary/$', api.GetLectureActivitySummary.as_view()), url(r'^get-lecture-activity-summary/$', api.GetLectureActivitySummary.as_view()),
# retrieves lecture activity summary
url(r'^get-lecture-emotion-summary/$', api.GetLectureEmotionSummary.as_view()),
# retrieves lecture activity summary
url(r'^get-lecture-gaze-summary/$', api.GetLectureGazeSummary.as_view()),
# routers # routers
# path('', include(router.urls)), # path('', include(router.urls)),
......
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