From f62ecb99df238e71c1d99615cae0ea6ae2b67d90 Mon Sep 17 00:00:00 2001 From: Rory Sawyer Date: Tue, 19 Mar 2024 14:16:06 -0400 Subject: [PATCH] feat: add dataset for pageview engagement charts feat: add pageview engagement chart to instructor dashboard fix: include filters in pageview engagement dataset --- ...view_engagement_by_section_subsection.yaml | 69 ++++++++++ .../dashboards/Instructor_Dashboard.yaml | 93 ++++++++++--- .../datasets/fact_pageview_engagement.yaml | 126 ++++++++++++++++++ .../queries/fact_pageview_engagement.sql | 73 ++++++++++ 4 files changed, 345 insertions(+), 16 deletions(-) create mode 100644 tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/charts/Pageview_engagement_by_section_subsection.yaml create mode 100644 tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/datasets/fact_pageview_engagement.yaml create mode 100644 tutoraspects/templates/openedx-assets/queries/fact_pageview_engagement.sql diff --git a/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/charts/Pageview_engagement_by_section_subsection.yaml b/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/charts/Pageview_engagement_by_section_subsection.yaml new file mode 100644 index 000000000..c3e1b8334 --- /dev/null +++ b/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/charts/Pageview_engagement_by_section_subsection.yaml @@ -0,0 +1,69 @@ +_file_name: Pageview_engagement_by_section_subsection.yaml +cache_timeout: null +certification_details: null +certified_by: null +dataset_uuid: 9febd6be-5102-4dbf-86b9-45ebd3cbbc45 +description: null +params: + adhoc_filters: [] + annotation_layers: [] + color_scheme: supersetColors + comparison_type: values + extra_form_data: {} + forecastInterval: 0.8 + forecastPeriods: 10 + groupby: [] + legendOrientation: top + legendType: scroll + metrics: + - aggregate: null + column: null + datasourceWarning: false + expressionType: SQL + hasCustomLabel: true + label: At least one page viewed + optionName: metric_3ripnf7qlwz_sny20kpdx8l + sqlExpression: |- + countIf("section/subsection page engagement" = 'At least one page viewed' or "section/subsection page engagement" = 'All pages viewed') + - aggregate: null + column: null + datasourceWarning: false + expressionType: SQL + hasCustomLabel: true + label: All pages viewed + optionName: metric_x2ljl75aomp_0r5ocutlbvb + sqlExpression: |- + countIf("section/subsection page engagement" = 'All pages viewed') + only_total: true + order_desc: true + orientation: vertical + rich_tooltip: true + row_limit: 10000 + show_empty_columns: true + show_legend: true + sort_series_type: sum + time_grain_sqla: P1D + tooltipTimeFormat: smart_date + truncate_metric: true + viz_type: echarts_timeseries_bar + xAxisLabelRotation: 45 + x_axis: section/subsection name + x_axis_sort_asc: true + x_axis_sort_series: name + x_axis_sort_series_ascending: true + x_axis_time_format: smart_date + x_axis_title: '' + x_axis_title_margin: 150 + y_axis_bounds: + - null + - null + y_axis_format: SMART_NUMBER + y_axis_title: Number of Learners + y_axis_title_margin: 30 + y_axis_title_position: Left +query_context: |- + {"datasource":{"id":68,"type":"table"},"force":false,"queries":[{"filters":[],"extras":{"having":"","where":""},"applied_time_extras":{},"columns":[{"timeGrain":"P1D","columnType":"BASE_AXIS","sqlExpression":"section/subsection name","label":"section/subsection name","expressionType":"SQL"}],"metrics":[{"expressionType":"SQL","sqlExpression":"countIf(\"section/subsection page engagement\" = 'At least one page viewed' or \"section/subsection page engagement\" = 'All pages viewed')","column":null,"aggregate":null,"datasourceWarning":false,"hasCustomLabel":true,"label":"At least one page viewed","optionName":"metric_3ripnf7qlwz_sny20kpdx8l"},{"expressionType":"SQL","sqlExpression":"countIf(\"section/subsection page engagement\" = 'All pages viewed')","column":null,"aggregate":null,"datasourceWarning":false,"hasCustomLabel":true,"label":"All pages viewed","optionName":"metric_x2ljl75aomp_0r5ocutlbvb"}],"orderby":[[{"expressionType":"SQL","sqlExpression":"countIf(\"section/subsection page engagement\" = 'At least one page viewed' or \"section/subsection page engagement\" = 'All pages viewed')","column":null,"aggregate":null,"datasourceWarning":false,"hasCustomLabel":true,"label":"At least one page viewed","optionName":"metric_3ripnf7qlwz_sny20kpdx8l"},false]],"annotation_layers":[],"row_limit":10000,"series_columns":[],"series_limit":0,"order_desc":true,"url_params":{},"custom_params":{},"custom_form_data":{},"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["section/subsection name"],"columns":[],"aggregates":{"At least one page viewed":{"operator":"mean"},"All pages viewed":{"operator":"mean"}},"drop_missing_columns":false}},{"operation":"flatten"}]}],"form_data":{"datasource":"68__table","viz_type":"echarts_timeseries_bar","x_axis":"section/subsection name","time_grain_sqla":"P1D","x_axis_sort_asc":true,"x_axis_sort_series":"name","x_axis_sort_series_ascending":true,"metrics":[{"expressionType":"SQL","sqlExpression":"countIf(\"section/subsection page engagement\" = 'At least one page viewed' or \"section/subsection page engagement\" = 'All pages viewed')","column":null,"aggregate":null,"datasourceWarning":false,"hasCustomLabel":true,"label":"At least one page viewed","optionName":"metric_3ripnf7qlwz_sny20kpdx8l"},{"expressionType":"SQL","sqlExpression":"countIf(\"section/subsection page engagement\" = 'All pages viewed')","column":null,"aggregate":null,"datasourceWarning":false,"hasCustomLabel":true,"label":"All pages viewed","optionName":"metric_x2ljl75aomp_0r5ocutlbvb"}],"groupby":[],"adhoc_filters":[],"order_desc":true,"row_limit":10000,"truncate_metric":true,"show_empty_columns":true,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"orientation":"vertical","x_axis_title":"","x_axis_title_margin":150,"y_axis_title":"Number of Learners","y_axis_title_margin":30,"y_axis_title_position":"Left","sort_series_type":"sum","color_scheme":"supersetColors","only_total":true,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","xAxisLabelRotation":45,"y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"rich_tooltip":true,"tooltipTimeFormat":"smart_date","extra_form_data":{},"dashboards":[520],"force":false,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"} +slice_name: Pageview engagement by section/subsection +uuid: 366a8193-30c3-4aaf-a1ac-360609dfa0ed +version: 1.0.0 +viz_type: echarts_timeseries_bar diff --git a/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/dashboards/Instructor_Dashboard.yaml b/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/dashboards/Instructor_Dashboard.yaml index 06885d666..371681c7f 100644 --- a/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/dashboards/Instructor_Dashboard.yaml +++ b/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/dashboards/Instructor_Dashboard.yaml @@ -6,6 +6,25 @@ dashboard_title: Instructor Dashboard description: null metadata: chart_configuration: + '1804': + crossFilters: + chartsInScope: + - 24 + - 25 + - 32 + - 34 + - 37 + - 45 + - 46 + - 47 + - 52 + - 865 + - 879 + - 894 + - 908 + - 922 + scope: global + id: 1804 '32': crossFilters: chartsInScope: @@ -22,6 +41,7 @@ metadata: - 894 - 908 - 922 + - 1804 scope: global id: 32 '34': @@ -40,6 +60,7 @@ metadata: - 894 - 908 - 922 + - 1804 scope: global id: 34 color_scheme: '' @@ -63,6 +84,7 @@ metadata: - 894 - 908 - 922 + - 1804 scope: excluded: [] rootPath: @@ -307,14 +329,16 @@ metadata: datasetUuid: 417b2035-8fa1-4c60-a405-4b1947c3c966 type: NATIVE_FILTER refresh_frequency: 0 - shared_label_colors: {} + shared_label_colors: + All pages viewed: '#5AC189' + At least one page viewed: '#1FA8C9' timed_refresh_immune_slices: [] position: CHART-AZZnl_lpMv: children: [] id: CHART-AZZnl_lpMv meta: - chartId: 13 + chartId: 25 height: 50 sliceName: Watches Per Video uuid: 829c1d5b-2844-4115-876a-34ad3b3cad64 @@ -329,7 +353,7 @@ position: children: [] id: CHART-GFCO8s2cxv meta: - chartId: 25 + chartId: 45 height: 50 sliceName: Distribution Of Responses uuid: f1651c44-a8f4-4b44-ad49-962823009319 @@ -344,7 +368,7 @@ position: children: [] id: CHART-GJJ8VYQ03v meta: - chartId: 55 + chartId: 922 height: 50 sliceName: Posts per user uuid: bc191ce7-f39d-48db-86a9-d19949f4211d @@ -374,7 +398,7 @@ position: children: [] id: CHART-OMy4wjRBWt meta: - chartId: 45 + chartId: 52 height: 50 sliceName: Watched Video Segments uuid: 2985a9db-c338-4008-af52-2930b81ee2e5 @@ -389,7 +413,7 @@ position: children: [] id: CHART-RTO33WE9FH meta: - chartId: 59 + chartId: 894 height: 50 sliceName: Responses Per Problem uuid: a3e79162-4ace-4349-ab34-89aa60ae75ed @@ -404,7 +428,7 @@ position: children: [] id: CHART-Tej2oLPBAl meta: - chartId: 58 + chartId: 24 height: 50 sliceName: Transcripts / Captions Per Video uuid: 6b830def-f3ca-4b4c-9455-7a7b7354bce8 @@ -419,7 +443,7 @@ position: children: [] id: CHART-evjVO-ZSSd meta: - chartId: 27 + chartId: 32 height: 50 sliceName: Enrollments By Enrollment Mode uuid: 05ed7102-5464-4e2f-86ae-31700b787cc3 @@ -430,11 +454,26 @@ position: - TAB-8BxDuJd9Jb - ROW-je_Wqya3Ga type: CHART + CHART-j3trfNh8_p: + children: [] + id: CHART-j3trfNh8_p + meta: + chartId: 1804 + height: 50 + sliceName: Pageview engagement by section/subsection + uuid: 366a8193-30c3-4aaf-a1ac-360609dfa0ed + width: 12 + parents: + - ROOT_ID + - TABS-SNeKAJcjhd + - TAB-4Z1kfBQZO + - ROW-Lt0M87yMb3 + type: CHART CHART-lTr8DL3XuI: children: [] id: CHART-lTr8DL3XuI meta: - chartId: 57 + chartId: 46 height: 50 sliceName: Distribution Of Hints Per Correct Answer uuid: ee94be4c-6fdd-4295-b43c-40890d6c549d @@ -449,7 +488,7 @@ position: children: [] id: CHART-o56v9yEe2I meta: - chartId: 11 + chartId: 865 height: 50 sliceName: Distribution Of Problem Grades uuid: 4f7e3606-f5de-4643-97c0-bbb6340a3df2 @@ -464,7 +503,7 @@ position: children: [] id: CHART-qG1WaGKl_b meta: - chartId: 26 + chartId: 908 height: 50 sliceName: Distinct forum users uuid: feb323ad-c819-49ca-a336-584bd9ff1a2e @@ -479,7 +518,7 @@ position: children: [] id: CHART-rnb6PSwCOS meta: - chartId: 65 + chartId: 37 height: 50 sliceName: Currently Enrolled Learners Per Day uuid: ed2fe731-6544-422f-bc55-42f399f48b2c @@ -494,7 +533,7 @@ position: children: [] id: CHART-tWnaoVNNTH meta: - chartId: 70 + chartId: 47 height: 50 sliceName: Distribution Of Attempts uuid: db90930f-f16e-4c32-8050-0e4abae28f4c @@ -509,7 +548,7 @@ position: children: [] id: CHART-w-k4N2T_L8 meta: - chartId: 16 + chartId: 879 height: 50 sliceName: Course Grade Distribution uuid: f9adbc85-1f50-4c04-ace3-31ba7390de5e @@ -715,6 +754,17 @@ position: - TABS-SNeKAJcjhd - TAB-8BxDuJd9Jb type: ROW + ROW-Lt0M87yMb3: + children: + - CHART-j3trfNh8_p + id: ROW-Lt0M87yMb3 + meta: + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - TABS-SNeKAJcjhd + - TAB-4Z1kfBQZO + type: ROW ROW-chsNWRRd4: children: - MARKDOWN-EVIRENCcGc @@ -795,6 +845,18 @@ position: - TABS-SNeKAJcjhd - TAB-NR4UTAs9K type: ROW + TAB-4Z1kfBQZO: + children: + - ROW-Lt0M87yMb3 + id: TAB-4Z1kfBQZO + meta: + defaultText: Tab title + placeholder: Tab title + text: Pageview Engagement + parents: + - ROOT_ID + - TABS-SNeKAJcjhd + type: TAB TAB-7PGDduCA7: children: - ROW-nNEywSG0jX @@ -898,9 +960,8 @@ position: - TAB-7PGDduCA7 - TAB-CLiLC4zxo - TAB-eE0OQxuju - # {% if ASPECTS_INSTRUCTOR_HELP_MARKDOWN %} - TAB-nXpinnLEX - # {% endif %} + - TAB-4Z1kfBQZO id: TABS-SNeKAJcjhd meta: {} parents: diff --git a/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/datasets/fact_pageview_engagement.yaml b/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/datasets/fact_pageview_engagement.yaml new file mode 100644 index 000000000..556d16904 --- /dev/null +++ b/tutoraspects/templates/aspects/build/aspects-superset/openedx-assets/assets/datasets/fact_pageview_engagement.yaml @@ -0,0 +1,126 @@ +_file_name: fact_pageview_engagement.yaml +cache_timeout: null +columns: + - advanced_data_type: null + column_name: org + description: null + expression: null + extra: null + filterable: true + groupby: true + is_active: true + is_dttm: false + python_date_format: null + type: String + verbose_name: null + - advanced_data_type: null + column_name: course_key + description: null + expression: null + extra: null + filterable: true + groupby: true + is_active: true + is_dttm: false + python_date_format: null + type: String + verbose_name: null + - advanced_data_type: null + column_name: section/subsection page engagement + description: null + expression: null + extra: null + filterable: true + groupby: true + is_active: true + is_dttm: false + python_date_format: null + type: String + verbose_name: null + - advanced_data_type: null + column_name: section/subsection name + description: null + expression: null + extra: null + filterable: true + groupby: true + is_active: true + is_dttm: false + python_date_format: null + type: String + verbose_name: null + - advanced_data_type: null + column_name: content level + description: null + expression: null + extra: null + filterable: true + groupby: true + is_active: true + is_dttm: false + python_date_format: null + type: String + verbose_name: null + - advanced_data_type: null + column_name: actor_id + description: null + expression: null + extra: null + filterable: true + groupby: true + is_active: true + is_dttm: false + python_date_format: null + type: String + verbose_name: null + - advanced_data_type: null + column_name: course_run + description: null + expression: null + extra: null + filterable: true + groupby: true + is_active: true + is_dttm: false + python_date_format: null + type: String + verbose_name: null + - advanced_data_type: null + column_name: org + description: null + expression: null + extra: null + filterable: true + groupby: true + is_active: true + is_dttm: false + python_date_format: null + type: String + verbose_name: null +database_uuid: 21174b6c-4d40-4958-8161-d6c3cf5e77b6 +default_endpoint: null +description: null +extra: null +fetch_values_predicate: null +filter_select_enabled: false +main_dttm_col: null +metrics: + - currency: null + d3format: null + description: null + expression: count(*) + extra: null + metric_name: count + metric_type: null + verbose_name: null + warning_text: null +normalize_columns: true +offset: 0 +params: null +schema: main +sql: |- + {% filter indent(width=2) %}{% include 'openedx-assets/queries/fact_pageview_engagement.sql' %}{% endfilter %} +table_name: fact_pageview_engagement +template_params: {} +uuid: 9febd6be-5102-4dbf-86b9-45ebd3cbbc45 +version: 1.0.0 diff --git a/tutoraspects/templates/openedx-assets/queries/fact_pageview_engagement.sql b/tutoraspects/templates/openedx-assets/queries/fact_pageview_engagement.sql new file mode 100644 index 000000000..f768694bc --- /dev/null +++ b/tutoraspects/templates/openedx-assets/queries/fact_pageview_engagement.sql @@ -0,0 +1,73 @@ +with + subsection_counts as ( + select + org, + course_key, + section_with_name, + subsection_with_name, + actor_id, + page_count, + countdistinct(block_id) as pages_visited, + case + when pages_visited = 0 + then 'No pages viewed yet' + when pages_visited = page_count + then 'All pages viewed' + else 'At least one page viewed' + end as engagement_level + from {{ DBT_PROFILE_TARGET_DATABASE }}.fact_navigation_completion + where + 1 = 1 + {% raw %} + {% if from_dttm is not none %} + and visited_on > date('{{ from_dttm }}') + {% endif %} + {% if to_dttm is not none %} + and visited_on < date('{{ to_dttm }}') + {% endif %} + {% endraw %} + {% include 'openedx-assets/queries/common_filters.sql' %} + group by + org, + course_key, + section_with_name, + subsection_with_name, + actor_id, + page_count + ), + section_counts as ( + select + org, + course_key, + section_with_name, + actor_id, + sum(page_count) as page_count, + sum(pages_visited) as pages_visited, + case + when pages_visited = 0 + then 'No pages viewed yet' + when pages_visited = page_count + then 'All pages viewed' + else 'At least one page viewed' + end as engagement_level + from subsection_counts + group by org, course_key, section_with_name, actor_id + ) + +select + org, + course_key, + subsection_with_name as `section/subsection name`, + 'subsection' as `content level`, + actor_id as actor_id, + engagement_level as `section/subsection page engagement` +from subsection_counts +union all +select + org, + course_key, + section_with_name as `section/subsection name`, + 'section' as `content level`, + actor_id as actor_id, + engagement_level as `section/subsection page engagement` +from section_counts