mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-02-17 17:02:18 -05:00
Adding ‘left game’ counts to overall campaign view. This is the number of players that left the game after playing the given level.
156 lines
5.9 KiB
CoffeeScript
156 lines
5.9 KiB
CoffeeScript
template = require 'templates/editor/campaign/campaign-analytics-modal'
|
|
utils = require 'core/utils'
|
|
ModalView = require 'views/core/ModalView'
|
|
|
|
# TODO: jquery-ui datepicker doesn't work well in this view
|
|
# TODO: the date format handling is confusing (yyyy-mm-dd <=> yyyymmdd)
|
|
|
|
module.exports = class CampaignAnalyticsModal extends ModalView
|
|
id: 'campaign-analytics-modal'
|
|
template: template
|
|
plain: true
|
|
|
|
events:
|
|
'click #reload-button': 'onClickReloadButton'
|
|
|
|
constructor: (options, @campaignHandle, @campaignCompletions) ->
|
|
super options
|
|
@getCampaignAnalytics() unless @campaignCompletions?.levels?
|
|
|
|
getRenderData: ->
|
|
c = super()
|
|
c.campaignCompletions = @campaignCompletions
|
|
c
|
|
|
|
afterRender: ->
|
|
super()
|
|
$("#input-startday").datepicker dateFormat: "yy-mm-dd"
|
|
$("#input-endday").datepicker dateFormat: "yy-mm-dd"
|
|
|
|
onClickReloadButton: () =>
|
|
startDay = $('#input-startday').val()
|
|
endDay = $('#input-endday').val()
|
|
delete @campaignCompletions.levels
|
|
@campaignCompletions.startDay = startDay
|
|
@campaignCompletions.endDay = endDay
|
|
@render()
|
|
@getCampaignAnalytics startDay, endDay
|
|
|
|
getCampaignAnalytics: (startDay, endDay) =>
|
|
if startDay?
|
|
startDayDashed = startDay
|
|
startDay = startDay.replace(/-/g, '')
|
|
else
|
|
startDay = utils.getUTCDay -14
|
|
startDayDashed = "#{startDay[0..3]}-#{startDay[4..5]}-#{startDay[6..7]}"
|
|
if endDay?
|
|
endDayDashed = endDay
|
|
endDay = endDay.replace(/-/g, '')
|
|
else
|
|
endDay = utils.getUTCDay -1
|
|
endDayDashed = "#{endDay[0..3]}-#{endDay[4..5]}-#{endDay[6..7]}"
|
|
@campaignCompletions.startDay = startDayDashed
|
|
@campaignCompletions.endDay = endDayDashed
|
|
|
|
# Chain these together so we can calculate relative metrics (e.g. left game per second)
|
|
@getCampaignLevelCompletions startDay, endDay, () =>
|
|
@render()
|
|
@getCompaignLevelDrops startDay, endDay, () =>
|
|
@render()
|
|
@getCampaignAveragePlaytimes startDayDashed, endDayDashed, () =>
|
|
@render()
|
|
|
|
getCampaignAveragePlaytimes: (startDay, endDay, doneCallback) =>
|
|
# Fetch level average playtimes
|
|
# Needs date format yyyy-mm-dd
|
|
success = (data) =>
|
|
return if @destroyed
|
|
# console.log 'getCampaignAveragePlaytimes success', data
|
|
levelAverages = {}
|
|
for item in data
|
|
levelAverages[item.level] ?= []
|
|
levelAverages[item.level].push item.average
|
|
for level in @campaignCompletions.levels
|
|
if levelAverages[level.level]
|
|
if levelAverages[level.level].length > 0
|
|
total = _.reduce levelAverages[level.level], ((sum, num) -> sum + num)
|
|
level.averagePlaytime = (total / levelAverages[level.level].length).toFixed(2)
|
|
if level.averagePlaytime > 0 and level.dropped > 0
|
|
level.droppedPerSecond = (level.dropped / level.averagePlaytime).toFixed(2)
|
|
else
|
|
level.averagePlaytime = 0.0
|
|
|
|
sortedLevels = _.cloneDeep @campaignCompletions.levels
|
|
sortedLevels = _.filter sortedLevels, ((a) -> a.droppedPerSecond > 0), @
|
|
sortedLevels.sort (a, b) -> b.droppedPerSecond - a.droppedPerSecond
|
|
@campaignCompletions.top3DropPerSecond = _.pluck sortedLevels[0..2], 'level'
|
|
doneCallback()
|
|
|
|
levelSlugs = _.pluck @campaignCompletions.levels, 'level'
|
|
|
|
request = @supermodel.addRequestResource 'playtime_averages', {
|
|
url: '/db/level/-/playtime_averages'
|
|
data: {startDay: startDay, endDay: endDay, slugs: levelSlugs}
|
|
method: 'POST'
|
|
success: success
|
|
}, 0
|
|
request.load()
|
|
|
|
getCampaignLevelCompletions: (startDay, endDay, doneCallback) =>
|
|
# Needs date format yyyymmdd
|
|
success = (data) =>
|
|
return if @destroyed
|
|
# console.log 'getCampaignLevelCompletions success', data
|
|
mapFn = (item) ->
|
|
item.completionRate = if item.started > 0 then (item.finished / item.started * 100).toFixed(2) else 0.0
|
|
item
|
|
@campaignCompletions.levels = _.map data, mapFn, @
|
|
|
|
sortedLevels = _.cloneDeep @campaignCompletions.levels
|
|
sortedLevels = _.filter sortedLevels, ((a) -> a.finished >= 10), @
|
|
if sortedLevels.length >= 3
|
|
sortedLevels.sort (a, b) -> b.completionRate - a.completionRate
|
|
@campaignCompletions.top3 = _.pluck sortedLevels[0..2], 'level'
|
|
@campaignCompletions.bottom3 = _.pluck sortedLevels[sortedLevels.length - 4...sortedLevels.length - 1], 'level'
|
|
|
|
doneCallback()
|
|
|
|
# TODO: Why do we need this url dash?
|
|
request = @supermodel.addRequestResource 'campaign_completions', {
|
|
url: '/db/analytics_perday/-/campaign_completions'
|
|
data: {startDay: startDay, endDay: endDay, slug: @campaignHandle}
|
|
method: 'POST'
|
|
success: success
|
|
}, 0
|
|
request.load()
|
|
|
|
getCompaignLevelDrops: (startDay, endDay, doneCallback) =>
|
|
# Fetch level drops
|
|
# Needs date format yyyymmdd
|
|
success = (data) =>
|
|
return if @destroyed
|
|
# console.log 'getCompaignLevelDrops success', data
|
|
levelDrops = {}
|
|
for item in data
|
|
levelDrops[item.level] ?= item.dropped
|
|
for level in @campaignCompletions.levels
|
|
level.dropped = levelDrops[level.level] ? 0
|
|
level.dropPercentage = (level.dropped / level.started * 100).toFixed(2) if level.started > 0
|
|
|
|
sortedLevels = _.cloneDeep @campaignCompletions.levels
|
|
sortedLevels = _.filter sortedLevels, ((a) -> a.dropPercentage > 0), @
|
|
if sortedLevels.length >= 3
|
|
sortedLevels.sort (a, b) -> b.dropPercentage - a.dropPercentage
|
|
@campaignCompletions.top3DropPercentage = _.pluck sortedLevels[0..2], 'level'
|
|
doneCallback()
|
|
|
|
return unless @campaignCompletions?.levels?
|
|
levelSlugs = _.pluck @campaignCompletions.levels, 'level'
|
|
|
|
request = @supermodel.addRequestResource 'level_drops', {
|
|
url: '/db/analytics_perday/-/level_drops'
|
|
data: {startDay: startDay, endDay: endDay, slugs: levelSlugs}
|
|
method: 'POST'
|
|
success: success
|
|
}, 0
|
|
request.load()
|