mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 23:58:02 -05:00
Add completion % to campaign analytics
This commit is contained in:
parent
15be292573
commit
61180c640d
4 changed files with 28 additions and 24 deletions
|
@ -28,5 +28,8 @@
|
|||
top: 1%
|
||||
padding: 3px 8px
|
||||
|
||||
#analytics-modal .modal-content
|
||||
background-color: white
|
||||
#analytics-modal
|
||||
.modal-dialog
|
||||
width: 75%
|
||||
.modal-content
|
||||
background-color: white
|
||||
|
|
|
@ -65,6 +65,7 @@ block outer_content
|
|||
td Finished
|
||||
td Dropped
|
||||
td Drop %
|
||||
td Completion %
|
||||
tbody
|
||||
- for (var i = 0; i < campaignDropOffs.levels.length; i++)
|
||||
tr
|
||||
|
@ -75,6 +76,7 @@ block outer_content
|
|||
td= campaignDropOffs.levels[i].finished
|
||||
td= campaignDropOffs.levels[i].finishDropped
|
||||
td= campaignDropOffs.levels[i].finishDropRate
|
||||
td= campaignDropOffs.levels[i].completionRate
|
||||
else
|
||||
button.btn.btn-default.disabled#analytics-button Analytics Loading...
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ module.exports = class CampaignEditorView extends RootView
|
|||
@listenToOnce @levels, 'sync', @onFundamentalLoaded
|
||||
@listenToOnce @achievements, 'sync', @onFundamentalLoaded
|
||||
|
||||
_.delay @getCampaignDropOffs, 1000
|
||||
_.delay @getCampaignCompletions, 1000
|
||||
|
||||
loadThangTypeNames: ->
|
||||
# Load the names of the ThangTypes that this level's Treema nodes might want to display.
|
||||
|
@ -240,7 +240,7 @@ module.exports = class CampaignEditorView extends RootView
|
|||
if achievement.hasLocalChanges()
|
||||
@toSave.add achievement
|
||||
|
||||
getCampaignDropOffs: =>
|
||||
getCampaignCompletions: =>
|
||||
# Fetch last 7 days of campaign drop-off rates
|
||||
|
||||
startDay = new Date()
|
||||
|
@ -254,14 +254,15 @@ module.exports = class CampaignEditorView extends RootView
|
|||
mapFn = (item) ->
|
||||
item.startDropRate = (item.startDropped / item.started * 100).toFixed(2)
|
||||
item.finishDropRate = (item.finishDropped / item.finished * 100).toFixed(2)
|
||||
item.completionRate = (item.finished / item.started * 100).toFixed(2)
|
||||
item
|
||||
@campaignDropOffs.levels = _.map @campaignDropOffs.levels, mapFn, @
|
||||
@campaignDropOffs.startDay = startDay
|
||||
@render()
|
||||
|
||||
# TODO: Why do we need this url dash?
|
||||
request = @supermodel.addRequestResource 'campaign_drop_offs', {
|
||||
url: '/db/analytics_log_event/-/campaign_drop_offs'
|
||||
request = @supermodel.addRequestResource 'campaign_completions', {
|
||||
url: '/db/analytics_log_event/-/campaign_completions'
|
||||
data: {startDay: startDay, slug: @campaignHandle}
|
||||
method: 'POST'
|
||||
success: success
|
||||
|
|
|
@ -21,11 +21,11 @@ class AnalyticsLogEventHandler extends Handler
|
|||
instance
|
||||
|
||||
getByRelationship: (req, res, args...) ->
|
||||
return @getLevelCompletionsBySlugs(req, res) if args[1] is 'level_completions'
|
||||
return @getCampaignDropOffs(req, res) if args[1] is 'campaign_drop_offs'
|
||||
return @getLevelCompletionsBySlug(req, res) if args[1] is 'level_completions'
|
||||
return @getCampaignCompletionsBySlug(req, res) if args[1] is 'campaign_completions'
|
||||
super(arguments...)
|
||||
|
||||
getLevelCompletionsBySlugs: (req, res) ->
|
||||
getLevelCompletionsBySlug: (req, res) ->
|
||||
# Returns an array of per-day level starts and finishes
|
||||
# Parameters:
|
||||
# slug - level slug
|
||||
|
@ -97,8 +97,8 @@ class AnalyticsLogEventHandler extends Handler
|
|||
@levelCompletionsCache[cacheKey] = completions[level]
|
||||
@sendSuccess res, completions[levelSlug]
|
||||
|
||||
getCampaignDropOffs: (req, res) ->
|
||||
# Returns a dictionary of per-campaign level start and finish drop-offs
|
||||
getCampaignCompletionsBySlug: (req, res) ->
|
||||
# Returns a dictionary of per-campaign level starts, finishes, and drop-offs
|
||||
# Drop-off: last started or finished level event
|
||||
# Parameters:
|
||||
# slugs - array of campaign slugs
|
||||
|
@ -128,7 +128,7 @@ class AnalyticsLogEventHandler extends Handler
|
|||
cacheKey += 'e' + endDay if endDay?
|
||||
return @sendSuccess res, campaignDropOffs if campaignDropOffs = @campaignDropOffsCache[cacheKey]
|
||||
|
||||
calculateDropOffs = (campaigns) =>
|
||||
getCompletions = (campaigns) =>
|
||||
# Calculate campaign drop off rates
|
||||
# Input:
|
||||
# campaigns - per-campaign dictionary of ordered level slugs
|
||||
|
@ -180,7 +180,7 @@ class AnalyticsLogEventHandler extends Handler
|
|||
levelProgression[level].finishDropped++ if i is userProgression[user].length - 1
|
||||
|
||||
# Put in campaign order
|
||||
campaignRates = {}
|
||||
completions = {}
|
||||
for level of levelProgression
|
||||
for campaign of campaigns
|
||||
if level in campaigns[campaign]
|
||||
|
@ -188,14 +188,14 @@ class AnalyticsLogEventHandler extends Handler
|
|||
startDropped = levelProgression[level].startDropped
|
||||
finished = levelProgression[level].finished
|
||||
finishDropped = levelProgression[level].finishDropped
|
||||
campaignRates[campaign] ?=
|
||||
completions[campaign] ?=
|
||||
levels: []
|
||||
# overall:
|
||||
# started: 0,
|
||||
# startDropped: 0,
|
||||
# finished: 0,
|
||||
# finishDropped: 0
|
||||
campaignRates[campaign].levels.push
|
||||
completions[campaign].levels.push
|
||||
level: level
|
||||
started: started
|
||||
startDropped: startDropped
|
||||
|
@ -204,19 +204,19 @@ class AnalyticsLogEventHandler extends Handler
|
|||
break
|
||||
|
||||
# Sort level data by campaign order
|
||||
for campaign of campaignRates
|
||||
campaignRates[campaign].levels.sort (a, b) ->
|
||||
for campaign of completions
|
||||
completions[campaign].levels.sort (a, b) ->
|
||||
if campaigns[campaign].indexOf(a.level) < campaigns[campaign].indexOf(b.level) then return -1 else 1
|
||||
|
||||
# Return all campaign data for simplicity
|
||||
# Cache other individual campaigns too, since we have them
|
||||
@campaignDropOffsCache[cacheKey] = campaignRates
|
||||
for campaign of campaignRates
|
||||
@campaignDropOffsCache[cacheKey] = completions
|
||||
for campaign of completions
|
||||
cacheKey = campaign
|
||||
cacheKey += 's' + startDay if startDay?
|
||||
cacheKey += 'e' + endDay if endDay?
|
||||
@campaignDropOffsCache[cacheKey] = campaignRates
|
||||
@sendSuccess res, campaignRates
|
||||
@campaignDropOffsCache[cacheKey] = completions
|
||||
@sendSuccess res, completions
|
||||
|
||||
getLevelData = (campaigns, campaignLevelIDs) =>
|
||||
# Get level data and replace levelIDs with level slugs in campaigns
|
||||
|
@ -239,10 +239,8 @@ class AnalyticsLogEventHandler extends Handler
|
|||
for campaign of campaigns
|
||||
mapFn = (item) -> levelSlugMap[item]
|
||||
campaigns[campaign] = _.map campaigns[campaign], mapFn, @
|
||||
# Forest campaign levels are reversed for some reason
|
||||
campaigns[campaign].reverse() if campaign is 'forest'
|
||||
|
||||
calculateDropOffs campaigns
|
||||
getCompletions campaigns
|
||||
|
||||
getCampaignData = () =>
|
||||
# Get campaign data
|
||||
|
|
Loading…
Reference in a new issue