Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-analytics-dashboard
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-analytics-dashboard
Commits
c9debee7
Commit
c9debee7
authored
Jul 07, 2016
by
Dennis Jen
Committed by
GitHub
Jul 07, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #496 from edx/dsjen/enrollment-tracks
Added audit and credit enrollment tracks.
parents
00c270b5
cfe1dc46
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
119 additions
and
144 deletions
+119
-144
Makefile
+0
-1
acceptance_tests/__init__.py
+0
-1
acceptance_tests/test_course_enrollment.py
+21
-23
analytics_dashboard/courses/presenters/enrollment.py
+16
-33
analytics_dashboard/courses/templates/courses/enrollment_activity.html
+9
-11
analytics_dashboard/courses/tests/test_presenters.py
+26
-6
analytics_dashboard/courses/tests/test_views/test_csv.py
+0
-4
analytics_dashboard/courses/tests/utils.py
+14
-39
analytics_dashboard/courses/views/csv.py
+1
-3
analytics_dashboard/static/js/enrollment-activity-main.js
+31
-22
requirements/base.txt
+1
-1
No files found.
Makefile
View file @
c9debee7
...
@@ -61,7 +61,6 @@ validate_js: requirements.js
...
@@ -61,7 +61,6 @@ validate_js: requirements.js
validate
:
validate_python validate_js
validate
:
validate_python validate_js
demo
:
demo
:
python manage.py switch display_verified_enrollment on
--create
python manage.py switch show_engagement_forum_activity off
--create
python manage.py switch show_engagement_forum_activity off
--create
python manage.py switch enable_course_api off
--create
python manage.py switch enable_course_api off
--create
python manage.py switch display_names_for_course_index off
--create
python manage.py switch display_names_for_course_index off
--create
...
...
acceptance_tests/__init__.py
View file @
c9debee7
...
@@ -62,7 +62,6 @@ TEST_VIDEO_ID = os.environ.get('TEST_VIDEO_ID',
...
@@ -62,7 +62,6 @@ TEST_VIDEO_ID = os.environ.get('TEST_VIDEO_ID',
DOC_BASE_URL
=
os
.
environ
.
get
(
'DOC_BASE_URL'
,
'http://edx-insights.readthedocs.org/en/latest'
)
DOC_BASE_URL
=
os
.
environ
.
get
(
'DOC_BASE_URL'
,
'http://edx-insights.readthedocs.org/en/latest'
)
ENABLE_ENROLLMENT_MODES
=
str2bool
(
os
.
environ
.
get
(
'ENABLE_ENROLLMENT_MODES'
,
False
))
ENABLE_FORUM_POSTS
=
str2bool
(
os
.
environ
.
get
(
'ENABLE_FORUM_POSTS'
,
False
))
ENABLE_FORUM_POSTS
=
str2bool
(
os
.
environ
.
get
(
'ENABLE_FORUM_POSTS'
,
False
))
# Course API settings
# Course API settings
...
...
acceptance_tests/test_course_enrollment.py
View file @
c9debee7
from
collections
import
OrderedDict
import
datetime
import
datetime
from
analyticsclient.constants
import
demographic
,
UNKNOWN_COUNTRY_CODE
,
enrollment_modes
from
analyticsclient.constants
import
demographic
,
UNKNOWN_COUNTRY_CODE
,
enrollment_modes
from
bok_choy.web_app_test
import
WebAppTest
from
bok_choy.web_app_test
import
WebAppTest
from
acceptance_tests
import
ENABLE_ENROLLMENT_MODES
from
acceptance_tests.mixins
import
CoursePageTestsMixin
from
acceptance_tests.mixins
import
CoursePageTestsMixin
from
acceptance_tests.pages
import
CourseEnrollmentActivityPage
,
CourseEnrollmentGeographyPage
from
acceptance_tests.pages
import
CourseEnrollmentActivityPage
,
CourseEnrollmentGeographyPage
...
@@ -25,9 +25,7 @@ class CourseEnrollmentActivityTests(CoursePageTestsMixin, WebAppTest):
...
@@ -25,9 +25,7 @@ class CourseEnrollmentActivityTests(CoursePageTestsMixin, WebAppTest):
"""
"""
end_date
=
datetime
.
datetime
.
utcnow
()
end_date
=
datetime
.
datetime
.
utcnow
()
end_date_string
=
end_date
.
strftime
(
self
.
analytics_api_client
.
DATE_FORMAT
)
end_date_string
=
end_date
.
strftime
(
self
.
analytics_api_client
.
DATE_FORMAT
)
_demographic
=
'mode'
if
ENABLE_ENROLLMENT_MODES
else
None
return
self
.
course
.
enrollment
(
'mode'
,
start_date
=
None
,
end_date
=
end_date_string
)
return
self
.
course
.
enrollment
(
_demographic
,
start_date
=
None
,
end_date
=
end_date_string
)
def
test_page
(
self
):
def
test_page
(
self
):
super
(
CourseEnrollmentActivityTests
,
self
)
.
test_page
()
super
(
CourseEnrollmentActivityTests
,
self
)
.
test_page
()
...
@@ -46,8 +44,8 @@ class CourseEnrollmentActivityTests(CoursePageTestsMixin, WebAppTest):
...
@@ -46,8 +44,8 @@ class CourseEnrollmentActivityTests(CoursePageTestsMixin, WebAppTest):
self
.
assertSummaryTooltipEquals
(
selector
,
tooltip
)
self
.
assertSummaryTooltipEquals
(
selector
,
tooltip
)
def
_get_valid_enrollment_modes
(
self
,
trends
):
def
_get_valid_enrollment_modes
(
self
,
trends
):
valid_modes
=
{
enrollment_modes
.
AUDIT
,
enrollment_modes
.
HONOR
}
valid_modes
=
set
()
invalid_modes
=
set
(
enrollment_modes
.
ALL
)
-
valid_modes
invalid_modes
=
set
(
enrollment_modes
.
ALL
)
for
datum
in
trends
:
for
datum
in
trends
:
for
candidate
in
list
(
invalid_modes
):
for
candidate
in
list
(
invalid_modes
):
...
@@ -76,14 +74,13 @@ class CourseEnrollmentActivityTests(CoursePageTestsMixin, WebAppTest):
...
@@ -76,14 +74,13 @@ class CourseEnrollmentActivityTests(CoursePageTestsMixin, WebAppTest):
tooltip
=
u'Net difference in current enrollment in the last week.'
tooltip
=
u'Net difference in current enrollment in the last week.'
self
.
assertMetricTileValid
(
'enrollment_change_last_
%
s_days'
%
i
,
enrollment
,
tooltip
)
self
.
assertMetricTileValid
(
'enrollment_change_last_
%
s_days'
%
i
,
enrollment
,
tooltip
)
if
ENABLE_ENROLLMENT_MODES
:
valid_modes
=
self
.
_get_valid_enrollment_modes
(
enrollment_data
)
valid_modes
=
self
.
_get_valid_enrollment_modes
(
enrollment_data
)
if
enrollment_modes
.
VERIFIED
in
valid_modes
:
if
enrollment_modes
.
VERIFIED
in
valid_modes
:
# Verify the verified enrollment metric tile.
# Verify the verified enrollment metric tile.
verified_enrollment
=
enrollment_data
[
-
1
][
enrollment_modes
.
VERIFIED
]
verified_enrollment
=
enrollment_data
[
-
1
][
enrollment_modes
.
VERIFIED
]
tooltip
=
u'Number of currently enrolled students pursuing a verified certificate of achievement.'
tooltip
=
u'Number of currently enrolled students pursuing a verified certificate of achievement.'
self
.
assertMetricTileValid
(
'verified_enrollment'
,
verified_enrollment
,
tooltip
)
self
.
assertMetricTileValid
(
'verified_enrollment'
,
verified_enrollment
,
tooltip
)
# Verify *something* rendered where the graph should be. We cannot easily verify what rendered
# Verify *something* rendered where the graph should be. We cannot easily verify what rendered
self
.
assertElementHasContent
(
"[data-section=enrollment-basics] #enrollment-trend-view"
)
self
.
assertElementHasContent
(
"[data-section=enrollment-basics] #enrollment-trend-view"
)
...
@@ -96,16 +93,17 @@ class CourseEnrollmentActivityTests(CoursePageTestsMixin, WebAppTest):
...
@@ -96,16 +93,17 @@ class CourseEnrollmentActivityTests(CoursePageTestsMixin, WebAppTest):
table_selector
=
'div[data-role=enrollment-table] table'
table_selector
=
'div[data-role=enrollment-table] table'
headings
=
[
'Date'
,
'Current Enrollment'
]
headings
=
[
'Date'
,
'Current Enrollment'
]
if
ENABLE_ENROLLMENT_MODES
:
valid_modes
=
self
.
_get_valid_enrollment_modes
(
enrollment_data
)
headings
.
append
(
'Honor Code'
)
display_names
=
OrderedDict
([
(
enrollment_modes
.
HONOR
,
'Honor'
),
valid_modes
=
self
.
_get_valid_enrollment_modes
(
enrollment_data
)
(
enrollment_modes
.
AUDIT
,
'Audit'
),
(
enrollment_modes
.
VERIFIED
,
'Verified'
),
if
enrollment_modes
.
VERIFIED
in
valid_modes
:
(
enrollment_modes
.
PROFESSIONAL
,
'Professional'
),
headings
.
append
(
'Verified'
)
(
enrollment_modes
.
CREDIT
,
'Verified with Credit'
)
])
if
enrollment_modes
.
PROFESSIONAL
in
valid_modes
:
for
mode
,
display_name
in
display_names
.
items
():
headings
.
append
(
'Professional'
)
if
mode
in
valid_modes
:
headings
.
append
(
display_name
)
self
.
assertTableColumnHeadingsEqual
(
table_selector
,
headings
)
self
.
assertTableColumnHeadingsEqual
(
table_selector
,
headings
)
...
...
analytics_dashboard/courses/presenters/enrollment.py
View file @
c9debee7
...
@@ -4,7 +4,6 @@ import logging
...
@@ -4,7 +4,6 @@ import logging
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django_countries
import
countries
from
django_countries
import
countries
from
waffle
import
switch_is_active
from
analyticsclient.constants
import
demographic
,
UNKNOWN_COUNTRY_CODE
,
enrollment_modes
from
analyticsclient.constants
import
demographic
,
UNKNOWN_COUNTRY_CODE
,
enrollment_modes
import
analyticsclient.constants.education_level
as
EDUCATION_LEVEL
import
analyticsclient.constants.education_level
as
EDUCATION_LEVEL
import
analyticsclient.constants.gender
as
GENDER
import
analyticsclient.constants.gender
as
GENDER
...
@@ -82,16 +81,11 @@ class CourseEnrollmentPresenter(BasePresenter):
...
@@ -82,16 +81,11 @@ class CourseEnrollmentPresenter(BasePresenter):
NUMBER_TOP_COUNTRIES
=
3
NUMBER_TOP_COUNTRIES
=
3
@property
def
display_verified_enrollment
(
self
):
return
switch_is_active
(
'display_verified_enrollment'
)
def
get_summary_and_trend_data
(
self
):
def
get_summary_and_trend_data
(
self
):
"""
"""
Retrieve recent summary and all historical trend data.
Retrieve recent summary and all historical trend data.
"""
"""
_demographic
=
'mode'
if
self
.
display_verified_enrollment
else
None
trends
=
self
.
course
.
enrollment
(
'mode'
,
start_date
=
None
,
end_date
=
self
.
get_current_date
())
trends
=
self
.
course
.
enrollment
(
_demographic
,
start_date
=
None
,
end_date
=
self
.
get_current_date
())
trends
=
self
.
_fill_trend
(
trends
)
trends
=
self
.
_fill_trend
(
trends
)
summary
=
self
.
_build_summary
(
trends
)
summary
=
self
.
_build_summary
(
trends
)
...
@@ -101,19 +95,17 @@ class CourseEnrollmentPresenter(BasePresenter):
...
@@ -101,19 +95,17 @@ class CourseEnrollmentPresenter(BasePresenter):
day_before
=
self
.
parse_api_date
(
trends
[
0
][
'date'
])
-
datetime
.
timedelta
(
days
=
1
)
day_before
=
self
.
parse_api_date
(
trends
[
0
][
'date'
])
-
datetime
.
timedelta
(
days
=
1
)
trends
.
insert
(
0
,
self
.
_create_empty_enrollment_datapoint
(
day_before
))
trends
.
insert
(
0
,
self
.
_create_empty_enrollment_datapoint
(
day_before
))
if
self
.
display_verified_enrollment
:
return
self
.
_remove_empty_enrollment_modes
(
summary
,
trends
)
trends
=
self
.
_merge_audit_and_honor
(
trends
)
summary
,
trends
=
self
.
_remove_empty_enrollment_modes
(
summary
,
trends
)
return
summary
,
trends
def
_get_valid_enrollment_modes
(
self
,
trends
):
def
_get_valid_enrollment_modes
(
self
,
trends
):
"""
"""
Return enrollment modes for which there
is currently, or have been in the past,
at least one enrolled student.
Return enrollment modes for which there
was
at least one enrolled student.
"""
"""
valid_modes
=
{
enrollment_modes
.
AUDIT
,
enrollment_modes
.
HONOR
}
# default modes
invalid_modes
=
set
(
enrollment_modes
.
ALL
)
-
valid_modes
valid_modes
=
set
()
invalid_modes
=
set
(
enrollment_modes
.
ALL
)
# go through each day of the trend and record any tracks with enrollment as valid
for
datum
in
trends
:
for
datum
in
trends
:
for
candidate
in
invalid_modes
.
copy
():
for
candidate
in
invalid_modes
.
copy
():
if
datum
.
get
(
candidate
,
0
)
>
0
:
if
datum
.
get
(
candidate
,
0
)
>
0
:
...
@@ -136,22 +128,12 @@ class CourseEnrollmentPresenter(BasePresenter):
...
@@ -136,22 +128,12 @@ class CourseEnrollmentPresenter(BasePresenter):
for
mode
in
invalid_modes
:
for
mode
in
invalid_modes
:
trend
.
pop
(
mode
,
None
)
trend
.
pop
(
mode
,
None
)
# hides verified enrollment counts in the summary card if it doesn't exist
if
enrollment_modes
.
VERIFIED
not
in
valid_modes
:
if
enrollment_modes
.
VERIFIED
not
in
valid_modes
:
summary
.
pop
(
'verified_enrollment'
)
summary
.
pop
(
'verified_enrollment'
)
return
summary
,
trends
return
summary
,
trends
def
_merge_audit_and_honor
(
self
,
data
):
"""
Merge the audit and honor tracks into a single "honor" track
Note: This can be removed once the API has been deployed, as it will be updated to handle this for us.
"""
for
datum
in
data
:
datum
[
enrollment_modes
.
HONOR
]
=
datum
.
get
(
enrollment_modes
.
HONOR
,
0
)
+
datum
.
pop
(
enrollment_modes
.
AUDIT
,
0
)
return
data
def
_fill_trend
(
self
,
api_response
):
def
_fill_trend
(
self
,
api_response
):
""" Fills in enrollment counts for missing days in the trend data for display. """
""" Fills in enrollment counts for missing days in the trend data for display. """
if
api_response
:
if
api_response
:
...
@@ -180,12 +162,14 @@ class CourseEnrollmentPresenter(BasePresenter):
...
@@ -180,12 +162,14 @@ class CourseEnrollmentPresenter(BasePresenter):
"""
"""
Create an enrollment datapoint with all counts set to zero.
Create an enrollment datapoint with all counts set to zero.
"""
"""
trend
=
{
'date'
:
day
.
isoformat
(),
'count'
:
0
}
trend
=
{
'date'
:
day
.
isoformat
(),
'count'
:
0
,
'cumulative_count'
:
0
}
if
self
.
display_verified_enrollment
:
for
mode
in
enrollment_modes
.
ALL
:
trend
[
'cumulative_count'
]
=
0
trend
[
mode
]
=
0
for
mode
in
enrollment_modes
.
ALL
:
trend
[
mode
]
=
0
return
trend
return
trend
...
@@ -273,8 +257,7 @@ class CourseEnrollmentPresenter(BasePresenter):
...
@@ -273,8 +257,7 @@ class CourseEnrollmentPresenter(BasePresenter):
# Add the first values to the returned data dictionary using the most-recent enrollment data
# Add the first values to the returned data dictionary using the most-recent enrollment data
current_enrollment
=
recent_enrollment
[
'count'
]
current_enrollment
=
recent_enrollment
[
'count'
]
verified_enrollment
=
recent_enrollment
.
get
(
enrollment_modes
.
VERIFIED
,
verified_enrollment
=
recent_enrollment
.
get
(
enrollment_modes
.
VERIFIED
,
0
)
0
)
if
self
.
display_verified_enrollment
else
None
data
.
update
({
data
.
update
({
'last_updated'
:
last_enrollment_date
,
'last_updated'
:
last_enrollment_date
,
...
...
analytics_dashboard/courses/templates/courses/enrollment_activity.html
View file @
c9debee7
...
@@ -77,17 +77,15 @@ Individual course-centric enrollment activity view.
...
@@ -77,17 +77,15 @@ Individual course-centric enrollment activity view.
{% summary_point summary.enrollment_change_last_7_days label tooltip=tooltip %}
{% summary_point summary.enrollment_change_last_7_days label tooltip=tooltip %}
</div>
</div>
{% switch display_verified_enrollment %}
{% if not summary.verified_enrollment == None %}
{% if not summary.verified_enrollment == None %}
<div
class=
"col-xs-12 col-sm-3"
data-stat-type=
"verified_enrollment"
>
<div
class=
"col-xs-12 col-sm-3"
data-stat-type=
"verified_enrollment"
>
{# Translators: This is a label to identify enrollment of students on the verified track. #}
{# Translators: This is a label to identify enrollment of students on the verified track. #}
{% trans "Verified Enrollment" as label %}
{% trans "Verified Enrollment" as label %}
{# Translators: This is a label indicating the number of students enrolled in a course on the verified track. #}
{# Translators: This is a label indicating the number of students enrolled in a course on the verified track. #}
{% trans "Number of currently enrolled students pursuing a verified certificate of achievement." as tooltip %}
{% trans "Number of currently enrolled students pursuing a verified certificate of achievement." as tooltip %}
{% summary_point summary.verified_enrollment label tooltip=tooltip %}
{% summary_point summary.verified_enrollment label tooltip=tooltip %}
</div>
</div>
{% endif %}
{% endif %}
{% endswitch %}
</div>
</div>
</div>
</div>
{% else %}
{% else %}
...
...
analytics_dashboard/courses/tests/test_presenters.py
View file @
c9debee7
...
@@ -3,6 +3,7 @@ import copy
...
@@ -3,6 +3,7 @@ import copy
import
datetime
import
datetime
import
analyticsclient.constants.activity_type
as
AT
import
analyticsclient.constants.activity_type
as
AT
from
analyticsclient.constants
import
enrollment_modes
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core.cache
import
cache
from
django.core.cache
import
cache
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
...
@@ -579,9 +580,6 @@ class CourseEngagementVideoPresenterTests(SwitchMixin, TestCase):
...
@@ -579,9 +580,6 @@ class CourseEngagementVideoPresenterTests(SwitchMixin, TestCase):
class
CourseEnrollmentPresenterTests
(
SwitchMixin
,
TestCase
):
class
CourseEnrollmentPresenterTests
(
SwitchMixin
,
TestCase
):
@classmethod
def
setUpClass
(
cls
):
cls
.
toggle_switch
(
'display_verified_enrollment'
,
True
)
def
setUp
(
self
):
def
setUp
(
self
):
self
.
course_id
=
'edX/DemoX/Demo_Course'
self
.
course_id
=
'edX/DemoX/Demo_Course'
...
@@ -659,14 +657,36 @@ class CourseEnrollmentPresenterTests(SwitchMixin, TestCase):
...
@@ -659,14 +657,36 @@ class CourseEnrollmentPresenterTests(SwitchMixin, TestCase):
@mock.patch
(
'analyticsclient.course.Course.enrollment'
)
@mock.patch
(
'analyticsclient.course.Course.enrollment'
)
def
test_hide_empty_enrollment_modes
(
self
,
mock_enrollment
):
def
test_hide_empty_enrollment_modes
(
self
,
mock_enrollment
):
""" Enrollment modes with no enrolled students should not be returned. """
""" Enrollment modes with no enrolled students should not be returned. """
mock_enrollment
.
return_value
=
utils
.
get_mock_api_enrollment_data
(
self
.
course_id
,
include_verified
=
False
)
# set trend for one mode to be all 0
mock_api_data
=
utils
.
get_mock_api_enrollment_data
(
self
.
course_id
)
for
day
in
mock_api_data
:
day
[
enrollment_modes
.
PROFESSIONAL
]
=
0
mock_enrollment
.
return_value
=
mock_api_data
actual_summary
,
actual_trend
=
self
.
presenter
.
get_summary_and_trend_data
()
actual_summary
,
actual_trend
=
self
.
presenter
.
get_summary_and_trend_data
()
self
.
assertDictEqual
(
actual_summary
,
utils
.
get_mock_enrollment_summary
(
include_verified
=
False
))
self
.
assertDictEqual
(
actual_summary
,
utils
.
get_mock_enrollment_summary
())
# trends without enrollment shouldn't be present in the returned trend
expected_trend
=
utils
.
get_mock_presenter_enrollment_trend
(
self
.
course_id
)
for
day
in
expected_trend
:
del
day
[
enrollment_modes
.
PROFESSIONAL
]
expected_trend
=
utils
.
get_mock_presenter_enrollment_trend
(
self
.
course_id
,
include_verified
=
False
)
self
.
assertListEqual
(
actual_trend
,
expected_trend
)
self
.
assertListEqual
(
actual_trend
,
expected_trend
)
@mock.patch
(
'analyticsclient.course.Course.enrollment'
)
def
test_remove_verified_summary
(
self
,
mock_enrollment
):
""" Verified summary should be removed none are enrolled. """
mock_api_data
=
utils
.
get_mock_api_enrollment_data
(
self
.
course_id
)
for
day
in
mock_api_data
:
day
[
enrollment_modes
.
VERIFIED
]
=
0
mock_enrollment
.
return_value
=
mock_api_data
actual_summary
,
_actual_trend
=
self
.
presenter
.
get_summary_and_trend_data
()
expected_summary
=
utils
.
get_mock_enrollment_summary
()
del
expected_summary
[
'verified_enrollment'
]
self
.
assertDictEqual
(
actual_summary
,
expected_summary
)
class
CourseEnrollmentDemographicsPresenterTests
(
TestCase
):
class
CourseEnrollmentDemographicsPresenterTests
(
TestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
...
...
analytics_dashboard/courses/tests/test_views/test_csv.py
View file @
c9debee7
...
@@ -90,10 +90,6 @@ class CourseEnrollmentModeCSVViewTests(SwitchMixin, CourseCSVTestMixin, TestCase
...
@@ -90,10 +90,6 @@ class CourseEnrollmentModeCSVViewTests(SwitchMixin, CourseCSVTestMixin, TestCase
base_file_name
=
'enrollment'
base_file_name
=
'enrollment'
api_method
=
'analyticsclient.course.Course.enrollment'
api_method
=
'analyticsclient.course.Course.enrollment'
@classmethod
def
setUpClass
(
cls
):
cls
.
toggle_switch
(
'display_verified_enrollment'
,
True
)
def
get_mock_data
(
self
,
course_id
):
def
get_mock_data
(
self
,
course_id
):
return
get_mock_api_enrollment_data
(
course_id
)
return
get_mock_api_enrollment_data
(
course_id
)
...
...
analytics_dashboard/courses/tests/utils.py
View file @
c9debee7
...
@@ -20,10 +20,10 @@ GAP_START = 2
...
@@ -20,10 +20,10 @@ GAP_START = 2
GAP_END
=
4
GAP_END
=
4
def
get_mock_api_enrollment_data
(
course_id
,
include_verified
=
True
):
def
get_mock_api_enrollment_data
(
course_id
):
data
=
[]
data
=
[]
start_date
=
datetime
.
date
(
year
=
2014
,
month
=
1
,
day
=
1
)
start_date
=
datetime
.
date
(
year
=
2014
,
month
=
1
,
day
=
1
)
modes
=
enrollment_modes
.
ALL
if
include_verified
else
[
enrollment_modes
.
AUDIT
,
enrollment_modes
.
HONOR
]
modes
=
enrollment_modes
.
ALL
for
index
in
range
(
31
):
for
index
in
range
(
31
):
date
=
start_date
+
datetime
.
timedelta
(
days
=
index
)
date
=
start_date
+
datetime
.
timedelta
(
days
=
index
)
...
@@ -32,12 +32,10 @@ def get_mock_api_enrollment_data(course_id, include_verified=True):
...
@@ -32,12 +32,10 @@ def get_mock_api_enrollment_data(course_id, include_verified=True):
'date'
:
date
.
strftime
(
Client
.
DATE_FORMAT
),
'date'
:
date
.
strftime
(
Client
.
DATE_FORMAT
),
'course_id'
:
unicode
(
course_id
),
'course_id'
:
unicode
(
course_id
),
'count'
:
index
*
len
(
modes
),
'count'
:
index
*
len
(
modes
),
'created'
:
CREATED_DATETIME_STRING
'created'
:
CREATED_DATETIME_STRING
,
'cumulative_count'
:
index
*
len
(
modes
)
*
2
}
}
if
include_verified
:
datum
[
'cumulative_count'
]
=
datum
[
'count'
]
*
2
for
mode
in
modes
:
for
mode
in
modes
:
datum
[
mode
]
=
index
datum
[
mode
]
=
index
...
@@ -52,22 +50,14 @@ def get_mock_api_enrollment_data_with_gaps(course_id):
...
@@ -52,22 +50,14 @@ def get_mock_api_enrollment_data_with_gaps(course_id):
return
data
return
data
def
get_mock_enrollment_summary
(
include_verified
=
True
):
def
get_mock_enrollment_summary
():
summary
=
{
summary
=
{
'last_updated'
:
CREATED_DATETIME
,
'last_updated'
:
CREATED_DATETIME
,
'current_enrollment'
:
60
,
'current_enrollment'
:
150
,
'total_enrollment'
:
None
,
'total_enrollment'
:
300
,
'enrollment_change_last_7_days'
:
14
,
'enrollment_change_last_7_days'
:
35
,
'verified_enrollment'
:
30
,
}
}
if
include_verified
:
summary
.
update
({
'current_enrollment'
:
120
,
'total_enrollment'
:
240
,
'enrollment_change_last_7_days'
:
28
,
'verified_enrollment'
:
30
,
})
return
summary
return
summary
...
@@ -84,17 +74,8 @@ def _get_empty_enrollment(date):
...
@@ -84,17 +74,8 @@ def _get_empty_enrollment(date):
return
enrollment
return
enrollment
def
_clean_modes
(
data
):
def
get_mock_presenter_enrollment_trend
(
course_id
):
for
datum
in
data
:
trend
=
get_mock_api_enrollment_data
(
course_id
)
datum
[
enrollment_modes
.
HONOR
]
=
datum
[
enrollment_modes
.
AUDIT
]
+
datum
[
enrollment_modes
.
HONOR
]
datum
.
pop
(
enrollment_modes
.
AUDIT
)
return
data
def
get_mock_presenter_enrollment_trend
(
course_id
,
include_verified
=
True
):
trend
=
get_mock_api_enrollment_data
(
course_id
,
include_verified
=
include_verified
)
trend
=
_clean_modes
(
trend
)
return
trend
return
trend
...
@@ -119,19 +100,13 @@ def get_mock_presenter_enrollment_trend_with_gaps_filled(course_id):
...
@@ -119,19 +100,13 @@ def get_mock_presenter_enrollment_trend_with_gaps_filled(course_id):
def
get_mock_presenter_enrollment_data_small
(
course_id
):
def
get_mock_presenter_enrollment_data_small
(
course_id
):
data
=
[
_get_empty_enrollment
(
'2014-01-30'
),
get_mock_api_enrollment_data
(
course_id
)[
-
1
]]
data
=
[
_get_empty_enrollment
(
'2014-01-30'
),
get_mock_api_enrollment_data
(
course_id
)[
-
1
]]
data
=
_clean_modes
(
data
)
return
data
return
data
def
get_mock_presenter_enrollment_summary_small
():
def
get_mock_presenter_enrollment_summary_small
():
return
{
summary
=
get_mock_enrollment_summary
()
'last_updated'
:
CREATED_DATETIME
,
summary
[
'enrollment_change_last_7_days'
]
=
None
'current_enrollment'
:
120
,
return
summary
'total_enrollment'
:
240
,
'enrollment_change_last_7_days'
:
None
,
'verified_enrollment'
:
30
,
}
def
get_mock_api_enrollment_geography_data
(
course_id
):
def
get_mock_api_enrollment_geography_data
(
course_id
):
...
...
analytics_dashboard/courses/views/csv.py
View file @
c9debee7
...
@@ -4,7 +4,6 @@ import urllib
...
@@ -4,7 +4,6 @@ import urllib
from
django.http
import
HttpResponse
from
django.http
import
HttpResponse
from
waffle
import
switch_is_active
from
analyticsclient.constants
import
data_format
,
demographic
from
analyticsclient.constants
import
data_format
,
demographic
from
analyticsclient.client
import
Client
from
analyticsclient.client
import
Client
...
@@ -66,9 +65,8 @@ class CourseEnrollmentCSV(CSVResponseMixin, CourseView):
...
@@ -66,9 +65,8 @@ class CourseEnrollmentCSV(CSVResponseMixin, CourseView):
csv_filename_suffix
=
u'enrollment'
csv_filename_suffix
=
u'enrollment'
def
get_data
(
self
):
def
get_data
(
self
):
_demographic
=
'mode'
if
switch_is_active
(
'display_verified_enrollment'
)
else
None
end_date
=
datetime
.
datetime
.
utcnow
()
.
strftime
(
Client
.
DATE_FORMAT
)
end_date
=
datetime
.
datetime
.
utcnow
()
.
strftime
(
Client
.
DATE_FORMAT
)
return
self
.
course
.
enrollment
(
_demographic
,
data_format
=
data_format
.
CSV
,
end_date
=
end_date
)
return
self
.
course
.
enrollment
(
'mode'
,
data_format
=
data_format
.
CSV
,
end_date
=
end_date
)
class
CourseEngagementActivityTrendCSV
(
CSVResponseMixin
,
CourseView
):
class
CourseEngagementActivityTrendCSV
(
CSVResponseMixin
,
CourseView
):
...
...
analytics_dashboard/static/js/enrollment-activity-main.js
View file @
c9debee7
...
@@ -11,40 +11,49 @@ require(['vendor/domReady!', 'load/init-page'], function (doc, page) {
...
@@ -11,40 +11,49 @@ require(['vendor/domReady!', 'load/init-page'], function (doc, page) {
'views/stacked-trends-view'
],
'views/stacked-trends-view'
],
function
(
DataTableView
,
StackedTrendsView
)
{
function
(
DataTableView
,
StackedTrendsView
)
{
var
settings
=
[
var
colors
=
[
'#4BB4FB'
,
'#CA0061'
,
'#CCCCCC'
],
numericColumn
=
{
className
:
'text-right'
,
type
:
'number'
},
settings
=
[
{
{
key
:
'date'
,
key
:
'date'
,
title
:
gettext
(
'Date'
),
title
:
gettext
(
'Date'
),
type
:
'date'
type
:
'date'
},
},
{
_
.
defaults
({},
numericColumn
,
{
key
:
'count'
,
key
:
'count'
,
title
:
gettext
(
'Current Enrollment'
),
title
:
gettext
(
'Current Enrollment'
),
className
:
'text-right'
,
color
:
colors
[
0
]
type
:
'number'
,
}),
color
:
'#4BB4FB'
_
.
defaults
({},
numericColumn
,
{
},
{
key
:
'honor'
,
key
:
'honor'
,
title
:
gettext
(
'Honor Code'
),
// Translators: this describe the learner's enrollment track (e.g. Honor certificate)
className
:
'text-right'
,
title
:
gettext
(
'Honor'
),
type
:
'number'
,
color
:
colors
[
0
]
color
:
'#4BB4FB'
}),
},
_
.
defaults
({},
numericColumn
,
{
{
key
:
'audit'
,
title
:
gettext
(
'Audit'
),
color
:
colors
[
0
]
}),
_
.
defaults
({},
numericColumn
,
{
key
:
'verified'
,
key
:
'verified'
,
title
:
gettext
(
'Verified'
),
title
:
gettext
(
'Verified'
),
className
:
'text-right'
,
color
:
colors
[
1
]
type
:
'number'
,
}),
color
:
'#CA0061'
_
.
defaults
({},
numericColumn
,
{
},
{
key
:
'professional'
,
key
:
'professional'
,
title
:
gettext
(
'Professional'
),
title
:
gettext
(
'Professional'
),
className
:
'text-right'
,
color
:
colors
[
2
]
type
:
'number'
,
}),
color
:
'#CCCCCC'
_
.
defaults
({},
numericColumn
,
{
}
key
:
'credit'
,
// Translators: this label indicates the learner has registered for academic credit
title
:
gettext
(
'Verified with Credit'
),
color
:
colors
[
2
]
})
],
],
trendSettings
,
trendSettings
,
enrollmentTrackTrendSettings
;
enrollmentTrackTrendSettings
;
...
...
requirements/base.txt
View file @
c9debee7
...
@@ -26,7 +26,7 @@ requests==2.10.0 # Apache 2.0
...
@@ -26,7 +26,7 @@ requests==2.10.0 # Apache 2.0
git+https://github.com/pinax/django-announcements.git@f85e690705e038a62407abe54ac195f60760934b#egg=django-announcements # MIT
git+https://github.com/pinax/django-announcements.git@f85e690705e038a62407abe54ac195f60760934b#egg=django-announcements # MIT
git+https://github.com/edx/django-lang-pref-middleware.git@0.1.0#egg=django-lang-pref-middleware
git+https://github.com/edx/django-lang-pref-middleware.git@0.1.0#egg=django-lang-pref-middleware
git+https://github.com/edx/edx-analytics-data-api-client.git@0.
6.1#egg=edx-analytics-data-api-client==0.6.1
# edX
git+https://github.com/edx/edx-analytics-data-api-client.git@0.
8.0#egg=edx-analytics-data-api-client==0.8.0
# edX
git+https://github.com/edx/i18n-tools.git@0d7847f9dfa2281640527b4dc51f5854f950f9b7#egg=i18n_tools
git+https://github.com/edx/i18n-tools.git@0d7847f9dfa2281640527b4dc51f5854f950f9b7#egg=i18n_tools
git+https://github.com/edx/opaque-keys.git@d45d0bd8d64c69531be69178b9505b5d38806ce0#egg=opaque-keys
git+https://github.com/edx/opaque-keys.git@d45d0bd8d64c69531be69178b9505b5d38806ce0#egg=opaque-keys
# custom opaque-key implementations for ccx
# custom opaque-key implementations for ccx
...
...
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