Skip to content

Commit

Permalink
🎨(dashboard) improve details Dashboard code structure
Browse files Browse the repository at this point in the history
Details Dashboard file is restructured according to the common library
proposed. Hence, the common library is also improved.
  • Loading branch information
quitterie-lcs committed Jul 20, 2021
1 parent 1a07b60 commit d47c261
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 296 deletions.
50 changes: 50 additions & 0 deletions src/dashboards/common.libsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// General commons

{
fields: {
actor_account_name: 'actor.account.name.keyword',
course: 'object.definition.extensions.http://adlnet.gov/expapi/activities/course.keyword',
school: 'object.definition.extensions.https://w3id.org/xapi/acrossx/extensions/school.keyword',
session: 'object.definition.extensions.http://adlnet.gov/expapi/activities/module.keyword',
},
metrics: {
count: { id: '1', type: 'count' },
cardinality(field):: {
id: '1',
type: 'cardinality',
field: field,
},
max(field):: {
id: '1',
type: 'max',
field: field,
},
},
objects: {
date_histogram(interval='auto', min_doc_count='1'):: {
id: 'date',
field: 'timestamp',
type: 'date_histogram',
settings: {
interval: interval,
min_doc_count: min_doc_count,
trimEdges: '0',
},
},
},
tags: {
staff: 'staff',
teacher: 'teacher',
video: 'video',
xapi: 'xAPI',
},
utils: {
double_escape_string(x):: std.strReplace(std.strReplace(x, ':', '\\\\:'), '/', '\\\\/'),
single_escape_string(x):: std.strReplace(std.strReplace(x, ':', '\\:'), '/', '\\/'),
},
verb_ids: {
completed: 'http://adlnet.gov/expapi/verbs/completed',
initialized: 'http://adlnet.gov/expapi/verbs/initialized',
played: 'https://w3id.org/xapi/video/verbs/played',
},
}
71 changes: 36 additions & 35 deletions src/dashboards/videos/common.libsonnet
Original file line number Diff line number Diff line change
@@ -1,74 +1,63 @@
// Video commons

local grafana = import 'grafonnet/grafana.libsonnet';
local template = grafana.template;
local common = import '../common.libsonnet';

{
constants: {
datasources: {
lrs: 'lrs',
verb_id_completed: 'http://adlnet.gov/expapi/verbs/completed',
verb_id_played: 'https://w3id.org/xapi/video/verbs/played',
},
fields: {
actor_account_name: 'actor.account.name.keyword',
context_extensions_completion_threshold: 'context.extensions.https://w3id.org/xapi/video/extensions/completion-threshold',
course: 'object.definition.extensions.http://adlnet.gov/expapi/activities/course.keyword',
result_extensions_length: 'result.extensions.https://w3id.org/xapi/video/extensions/length',
result_extensions_time: 'result.extensions.https://w3id.org/xapi/video/extensions/time',
school: 'object.definition.extensions.https://w3id.org/xapi/acrossx/extensions/school.keyword',
session: 'object.definition.extensions.http://adlnet.gov/expapi/activities/module.keyword',
verb_display_en_us: 'verb.display.en-US.keyword',
video_id: 'object.id.keyword',
},
utils: {
double_escape_string(x):: std.strReplace(std.strReplace(x, ':', '\\\\:'), '/', '\\\\/'),
single_escape_string(x):: std.strReplace(std.strReplace(x, ':', '\\:'), '/', '\\/'),
},
objects: {
count_metric: { id: '1', type: 'count' },
date_histogram(interval='auto', min_doc_count='1'):: {
id: 'date',
field: 'timestamp',
type: 'date_histogram',
settings: {
interval: interval,
min_doc_count: min_doc_count,
trimEdges: '0',
},
},
},
queries: {
school_course_session: '%(school)s:$SCHOOL AND %(course)s:$COURSE AND %(session)s:$SESSION' % {
school: $.utils.single_escape_string($.fields.school),
course: $.utils.single_escape_string($.fields.course),
session: $.utils.single_escape_string($.fields.session),
course: common.utils.single_escape_string(common.fields.course),
school: common.utils.single_escape_string(common.fields.school),
session: common.utils.single_escape_string(common.fields.session),
},
video_id: 'object.id.keyword:$VIDEO',
},
templates: {
course: template.new(
name='COURSE',
current='all',
label='Course',
datasource=$.constants.lrs,
datasource=$.datasources.lrs,
query='{"find": "terms", "field": "%(course)s", "query": "%(school)s:$SCHOOL"}' % {
course: $.fields.course,
school: $.utils.double_escape_string($.fields.school),
course: common.fields.course,
school: common.utils.double_escape_string(common.fields.school),
},
refresh='time'
),
event_group_interval: template.custom(
name='EVENT_GROUP_INTERVAL',
current='30',
label='Event group interval',
query='1,10,20,30,60,120,180,300,600',
refresh='time'
),
school: template.new(
name='SCHOOL',
current='all',
label='School',
datasource=$.constants.lrs,
query='{"find": "terms", "field": "%(school)s"}' % { school: $.fields.school },
datasource=$.datasources.lrs,
query='{"find": "terms", "field": "%(school)s"}' % { school: common.fields.school },
refresh='time'
),
session: template.new(
name='SESSION',
current='all',
label='Session',
datasource=$.constants.lrs,
datasource=$.datasources.lrs,
query='{"find": "terms", "field": "%(session)s", "query": "%(course)s:$COURSE"}' % {
session: $.fields.session,
course: $.utils.double_escape_string($.fields.course),
session: common.fields.session,
course: common.utils.double_escape_string(common.fields.course),
},
refresh='time'
),
Expand All @@ -79,6 +68,18 @@ local template = grafana.template;
query='1d,7d,14d,21d,28d',
refresh='time'
),
video: template.new(
name='VIDEO',
current='all',
label='Video',
datasource=$.datasources.lrs,
query='{"find": "terms", "field": "%(video_id)s", "query": "%(course)s:$COURSE AND %(session)s:$SESSION"}' % {
video_id: $.fields.video_id,
course: common.utils.double_escape_string(common.fields.course),
session: common.utils.double_escape_string(common.fields.session),
},
refresh='time'
),
view_count_threshold: template.custom(
name='VIEW_COUNT_THRESHOLD',
current='30',
Expand Down
83 changes: 42 additions & 41 deletions src/dashboards/videos/course.jsonnet
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
// Video course dashboard

local grafana = import 'grafonnet/grafana.libsonnet';
local dashboard = grafana.dashboard;
local elasticsearch = grafana.elasticsearch;
local barGaugePanel = grafana.barGaugePanel;
local graphPanel = grafana.graphPanel;
local statPanel = grafana.statPanel;

local common = import 'common.libsonnet';

local common = import '../common.libsonnet';
local video_common = import 'common.libsonnet';

dashboard.new(
'Course',
tags=['xAPI', 'video', 'teacher'],
tags=[common.tags.xapi, common.tags.video, common.tags.teacher],
editable=false
)
.addTemplate(common.templates.school)
.addTemplate(common.templates.course)
.addTemplate(common.templates.session)
.addTemplate(common.templates.view_count_threshold)
.addTemplate(common.templates.statements_interval)
.addTemplate(video_common.templates.school)
.addTemplate(video_common.templates.course)
.addTemplate(video_common.templates.session)
.addTemplate(video_common.templates.view_count_threshold)
.addTemplate(video_common.templates.statements_interval)
.addPanel(
statPanel.new(
title='Views',
Expand All @@ -29,18 +30,18 @@ dashboard.new(
the video during the first seconds of the video. This time range is
controlled by the `View count threshold` variable.
|||,
datasource=common.constants.lrs,
datasource=video_common.datasources.lrs,
graphMode='none',
reducerFunction='sum'
).addTarget(
elasticsearch.target(
datasource=common.constants.lrs,
datasource=video_common.datasources.lrs,
query='%(course_query)s AND verb.id:"%(verb_played)s" AND %(time)s:[0 TO $VIEW_COUNT_THRESHOLD]' % {
course_query: common.queries.school_course_session,
verb_played: common.constants.verb_id_played,
time: common.utils.single_escape_string(common.fields.result_extensions_time),
course_query: video_common.queries.school_course_session,
verb_played: common.verb_ids.played,
time: common.utils.single_escape_string(video_common.fields.result_extensions_time),
},
metrics=[common.objects.count_metric],
metrics=[common.metrics.count],
bucketAggs=[common.objects.date_histogram('$STATEMENTS_INTERVAL')],
timeField='timestamp'
)
Expand All @@ -54,17 +55,17 @@ dashboard.new(
Total number of complete views of videos present in the selected course / session.
A view is considered as complete when the completion threshold of the video has been reached.
|||,
datasource=common.constants.lrs,
datasource=video_common.datasources.lrs,
graphMode='none',
reducerFunction='sum',
).addTarget(
elasticsearch.target(
datasource=common.constants.lrs,
datasource=video_common.datasources.lrs,
query='%(course_query)s AND verb.id:"%(verb_completed)s"' % {
course_query: common.queries.school_course_session,
verb_completed: common.constants.verb_id_completed,
course_query: video_common.queries.school_course_session,
verb_completed: common.verb_ids.completed,
},
metrics=[common.objects.count_metric],
metrics=[common.metrics.count],
bucketAggs=[common.objects.date_histogram()],
timeField='timestamp'
)
Expand All @@ -78,16 +79,16 @@ dashboard.new(
A view is counted when the user has clicked the play button in the interface
in the first ${VIEW_COUNT_THRESHOLD} seconds of the video.
|||,
datasource=common.constants.lrs,
datasource=video_common.datasources.lrs,
).addTarget(
elasticsearch.target(
datasource=common.constants.lrs,
datasource=video_common.datasources.lrs,
query='%(course_query)s AND verb.id:"%(verb_played)s" AND %(time)s:[0 TO $VIEW_COUNT_THRESHOLD]' % {
course_query: common.queries.school_course_session,
verb_played: common.constants.verb_id_played,
time: common.utils.single_escape_string(common.fields.result_extensions_time),
course_query: video_common.queries.school_course_session,
verb_played: common.verb_ids.played,
time: common.utils.single_escape_string(video_common.fields.result_extensions_time),
},
metrics=[common.objects.count_metric],
metrics=[common.metrics.count],
bucketAggs=[common.objects.date_histogram('$STATEMENTS_INTERVAL')],
timeField='timestamp'
)
Expand All @@ -102,7 +103,7 @@ dashboard.new(
On the X-axis is the number of statements.
On the Y-axis is the number of users.
|||,
datasource: common.constants.lrs,
datasource: video_common.datasources.lrs,
fieldConfig: {
defaults: {
color: {
Expand All @@ -126,7 +127,7 @@ dashboard.new(
field: 'timestamp',
id: '2',
settings: {
interval: '3600000',
interval: '1h',
min_doc_count: '1',
},
type: 'histogram',
Expand All @@ -143,8 +144,8 @@ dashboard.new(
type: 'terms',
},
],
metrics: [common.objects.count_metric],
query: common.queries.school_course_session,
metrics: [common.metrics.count],
query: video_common.queries.school_course_session,
refId: 'A',
timeField: 'timestamp',
},
Expand Down Expand Up @@ -179,7 +180,7 @@ dashboard.new(
On the X-axis is the number of completed videos.
On the Y-axis is the number of users.
|||,
datasource: common.constants.lrs,
datasource: video_common.datasources.lrs,
fieldConfig: {
defaults: {
color: {
Expand Down Expand Up @@ -220,10 +221,10 @@ dashboard.new(
type: 'terms',
},
],
metrics: [common.objects.count_metric],
metrics: [common.metrics.count],
query: '%(course_query)s AND verb.id:"%(completed)s"' % {
course_query: common.queries.school_course_session,
completed: common.constants.verb_id_completed,
course_query: video_common.queries.school_course_session,
completed: common.verb_ids.completed,
},
refId: 'A',
timeField: 'timestamp',
Expand Down Expand Up @@ -257,19 +258,19 @@ dashboard.new(
description=|||
The total count of views by video.
|||,
datasource=common.constants.lrs,
datasource=video_common.datasources.lrs,
).addTarget(
elasticsearch.target(
datasource=common.constants.lrs,
datasource=video_common.datasources.lrs,
query='%(course_query)s AND verb.id:"%(verb_played)s" AND %(time)s:[0 TO $VIEW_COUNT_THRESHOLD]' % {
course_query: common.queries.school_course_session,
verb_played: common.constants.verb_id_played,
time: common.utils.single_escape_string(common.fields.result_extensions_time),
course_query: video_common.queries.school_course_session,
verb_played: common.verb_ids.played,
time: common.utils.single_escape_string(video_common.fields.result_extensions_time),
},
metrics=[common.objects.count_metric],
metrics=[common.metrics.count],
bucketAggs=[
{
field: common.fields.video_id,
field: video_common.fields.video_id,
id: '2',
settings: {
min_doc_count: '1',
Expand Down
Loading

0 comments on commit d47c261

Please sign in to comment.