Dear fellow reporters,
I would like to share two new visual hacks I added recently to some useful reports we are using for some time now (originally developed and shared by Elizabeth Dalton's on the ad-hoc SQL reports wiki)
(1) Student activity over the course weeks:
Display a resizable Font Awesome Icon to represent the quantitative hits of student's activity.
And the SQL code:
(The magic is mark in bold)
SELECT
u.lastname AS 'Last Name'
, u.firstname AS 'First Name'
, COUNT(l.id) AS 'Edits'
, COUNT(DISTINCT IF((l.timecreated-c.startdate)<0,l.id,NULL)) AS 'Before Term'
# 60*60*24*7 = 604800
#,FLOOR((l.timecreated - c.startdate)/604800) as 'timediff'
#,DATE_FORMAT(FROM_UNIXTIME(l.timecreated),'%Y-%m-%d') AS 'l_timecreated'
#,DATE_FORMAT(FROM_UNIXTIME(c.startdate),'%Y-%m-%d') AS 'c_startdate'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=0,l.id,NULL)) AS 'Week 1'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=0,l.id,NULL))) ,'em;"></i>') AS 'Week 1'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=1,l.id,NULL)) AS 'Week 2'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=1,l.id,NULL))) ,'em;"></i>') AS 'Week 2'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=2,l.id,NULL)) AS 'Week 3'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=2,l.id,NULL))) ,'em;"></i>') AS 'Week 3'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=3,l.id,NULL)) AS 'Week 4'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=3,l.id,NULL))) ,'em;"></i>') AS 'Week 4'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=4,l.id,NULL)) AS 'Week 5'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=4,l.id,NULL))) ,'em;"></i>') AS 'Week 5'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=5,l.id,NULL)) AS 'Week 6'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=5,l.id,NULL))) ,'em;"></i>') AS 'Week 6'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=6,l.id,NULL)) AS 'Week 7'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=6,l.id,NULL))) ,'em;"></i>') AS 'Week 7'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=7,l.id,NULL)) AS 'Week 8'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=7,l.id,NULL))) ,'em;"></i>') AS 'Week 8'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=8,l.id,NULL)) AS 'Week 9'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=8,l.id,NULL))) ,'em;"></i>') AS 'Week 9'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=9,l.id,NULL)) AS 'Week 10'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=9,l.id,NULL))) ,'em;"></i>') AS 'Week 10'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=10,l.id,NULL)) AS 'Week 11'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=10,l.id,NULL))) ,'em;"></i>') AS 'Week 11'
#, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=11,l.id,NULL)) AS 'Week 12'
,CONCAT('<i class="fa fa-user" style="font-size: ', LOG(1 + COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/604800)=11,l.id,NULL))) ,'em;"></i>') AS 'Week 12'
, COUNT(DISTINCT IF(FLOOR((l.timecreated - c.startdate)/(60*60*24*7))>=12,l.id,NULL)) AS 'After Term'
# Our institution stores academic advisor names AND emails IN custom profile FIELDS
#, CONCAT('<a href="mailto:',uce.DATA,'">',uid.DATA, '</a>') AS 'Academic Advisor'
, CONCAT('<a target="_blank" href="%%WWWROOT%%/report/log/index.php',CHAR(63),'chooselog=1&showusers=1&showcourses=0&id=',c.id,'&user=',u.id,'&date=0&modid=&modaction=&logformat=showashtml','">','Logs','</a>') AS 'Logs'
, CONCAT('<a target="_blank" href="%%WWWROOT%%/report/outline/user.php',CHAR(63),'id=',u.id,'&course=',c.id,'&mode=outline">','Outline','</a>') AS 'Activity Outline'
, CONCAT('<a target="_blank" href="%%WWWROOT%%/report/outline/user.php',CHAR(63),'id=',u.id,'&course=',c.id,'&mode=complete">','Activity','</a>') AS 'Consolidated Activity'
#, CONCAT('<a target="_blank" href="%%WWWROOT%%/mod/forum/user.php',CHAR(63),'id=',u.id,'&course=',c.id,'">','Posts','</a>') AS 'Posts'
FROM prefix_user AS u
JOIN prefix_role_assignments AS ra ON u.id = ra.userid
JOIN prefix_context AS ctx ON ra.contextid = ctx.id
JOIN prefix_course AS c ON c.id = ctx.instanceid
JOIN prefix_course_categories AS cc ON c.category = cc.id
# student academic coach - you can include custom profile FIELD DATA WITH these methods
# LEFT JOIN prefix_user_info_data AS uid ON u.id = uid.userid AND uid.fieldid = '2'
# student academic coach email
# LEFT JOIN prefix_user_info_data AS uce ON u.id = uce.userid AND uce.fieldid = '6'
LEFT JOIN prefix_logstore_standard_log AS l ON l.userid = u.id AND l.courseid = c.id AND l.crud IN ('c','u')
WHERE ra.roleid =5
AND ctx.instanceid = c.id
AND c.id = %%COURSEID%%
GROUP BY u.idnumber
ORDER BY u.lastname, u.firstname
(2) Student's assignment's completion status and grades (in current course, and other courses too)
Use Bootstrap progress (simple & colorful) classes to represent course grade (percentage) and also HTML5 progress tag, in case you are not using a bootstrap based theme.
And the SQL magic for displaying various progress bars is marked in bold:
SELECT
#course.fullname as CourseName, ra.userid as CodeStudent
,(SELECT CONCAT('<a target="_new" href="%%WWWROOT%%/report/outline/user.php?id=',
u.id, '&course=', course.id, '&mode=complete">', u.firstname, ' ', u.lastname, '</a>')
FROM mdl_user AS u WHERE u.id = ra.userid) AS "סטודנט"
,(SELECT count(*)
from mdl_assign where course=course.id ) as "מטלות - בקורס זה"
,(SELECT count(*)
from mdl_assign_submission as mas
join mdl_assign as ma on ma.id=mas.assignment
where ra.userid=mas.userid and ma.course=course.id) as "הגשות - בקורס זה"
,(SELECT count(*)
from mdl_assign_submission as mas
join mdl_assign as ma on ma.id=mas.assignment
where ra.userid=mas.userid) as "הגשות - בכל הקורסים"
,(SELECT count(*) from mdl_assign where course=course.id and id not in
(SELECT mas.assignment
from mdl_assign_submission as mas
join mdl_assign as ma on ma.id=mas.assignment
where ra.userid=mas.userid and ma.course=course.id)) as "טרם הוגש - בקורס זה"
#,(SELECT count(*) from mdl_assign where course in (select con.instanceid
#from mdl_role_assignments as mra join
#mdl_context as con on mra.contextid=con.id and con.contextlevel=50
#where roleid=5 and userid= ra.userid)
#and id not in
#(select mas.assignment
#from mdl_assign_submission as mas
#join mdl_assign as ma on ma.id=mas.assignment
#where ra.userid=mas.userid and ma.course=course.id)) as "טרם הוגש - בכל הקורסים"
,(SELECT COUNT( * ) FROM mdl_assign_grades AS ag
JOIN mdl_assign AS a ON a.id = ag.assignment
WHERE ag.userid = ra.userid and a.course= course.id
and ag.grade not like 'NULL') AS "מטלות בהן התקבל ציון - בקורס זה"
#,(SELECT COUNT( * ) FROM mdl_assign_grades AS ag
#JOIN mdl_assign AS a ON a.id = ag.assignment
#WHERE ag.userid = ra.userid and
# ag.grade not like 'NULL') AS "Number of assign got grade In All Courses"
,CONCAT(
'<progress max="100" value="'
,(SELECT ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2)
FROM mdl_grade_grades AS gg
JOIN mdl_grade_items AS gi ON gi.id = gg.itemid
WHERE gg.userid = ra.userid AND gi.itemtype = 'Course'
)
,'">50%</progress>') AS "Course grade in percentage"
,CONCAT('<div class="progress">
<div class="bar" style="width: ',
(SELECT ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2)
FROM mdl_grade_grades AS gg
JOIN mdl_grade_items AS gi ON gi.id = gg.itemid
WHERE gg.userid = ra.userid AND gi.itemtype = 'Course')
,'%;"></div></div>') AS "Course grade in percentage"
,CASE
WHEN
(SELECT ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2)
FROM mdl_grade_grades AS gg
JOIN mdl_grade_items AS gi ON gi.id = gg.itemid
WHERE gg.userid = ra.userid AND gi.itemtype = 'Course') < 60
THEN
CONCAT('<div class="progress">
<div class="bar bar-danger" style="width: ',
(SELECT ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2)
FROM mdl_grade_grades AS gg
JOIN mdl_grade_items AS gi ON gi.id = gg.itemid
WHERE gg.userid = ra.userid AND gi.itemtype = 'Course')
,'%;"></div>
</div>')
WHEN
(SELECT ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2)
FROM mdl_grade_grades AS gg
JOIN mdl_grade_items AS gi ON gi.id = gg.itemid
WHERE gg.userid = ra.userid AND gi.itemtype = 'Course') >= 60
THEN
CONCAT('<div class="progress">
<div class="bar bar-warning" style="width: ',
(SELECT ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2)
FROM mdl_grade_grades AS gg
JOIN mdl_grade_items AS gi ON gi.id = gg.itemid
WHERE gg.userid = ra.userid AND gi.itemtype = 'Course')
,'%;"></div>
</div>')
WHEN (SELECT ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2)
FROM mdl_grade_grades AS gg
JOIN mdl_grade_items AS gi ON gi.id = gg.itemid
WHERE gg.userid = ra.userid AND gi.itemtype = 'Course') >= 85
THEN
CONCAT('<div class="progress">
<div class="bar bar-success" style="width: ',
(SELECT ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2)
FROM mdl_grade_grades AS gg
JOIN mdl_grade_items AS gi ON gi.id = gg.itemid
WHERE gg.userid = ra.userid AND gi.itemtype = 'Course')
,'%;"></div>
</div>')
END AS "colorful percentage"
#<div class="progress">
# <div class="bar bar-success" style="width: 35%;"></div>
# <div class="bar bar-warning" style="width: 20%;"></div>
# <div class="bar bar-danger" style="width: 10%;"></div>
#</div>
FROM mdl_role_assignments AS ra
JOIN mdl_context AS context ON ra.contextid = context.id
AND context.contextlevel =50
JOIN mdl_course AS course ON course.id = context.instanceid
WHERE ra.roleid=5
AND course.id='%%COURSEID%%'
#and ra.userid=339
----
Hope you like it and it get you into creating some more inspiring visual representations for all those number-full hard to read reports.
Nadav