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