mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 01:55:38 -05:00
Remove old user analytics page
This commit is contained in:
parent
d445024cb6
commit
722540f3be
4 changed files with 2 additions and 229 deletions
|
@ -34,7 +34,6 @@ module.exports = class CocoRouter extends Backbone.Router
|
||||||
'admin/employers': go('admin/EmployersListView')
|
'admin/employers': go('admin/EmployersListView')
|
||||||
'admin/files': go('admin/FilesView')
|
'admin/files': go('admin/FilesView')
|
||||||
'admin/analytics': go('admin/AnalyticsView')
|
'admin/analytics': go('admin/AnalyticsView')
|
||||||
'admin/analytics/users': go('admin/AnalyticsUsersView')
|
|
||||||
'admin/analytics/subscriptions': go('admin/AnalyticsSubscriptionsView')
|
'admin/analytics/subscriptions': go('admin/AnalyticsSubscriptionsView')
|
||||||
'admin/level-sessions': go('admin/LevelSessionsView')
|
'admin/level-sessions': go('admin/LevelSessionsView')
|
||||||
'admin/users': go('admin/UsersView')
|
'admin/users': go('admin/UsersView')
|
||||||
|
|
|
@ -48,12 +48,11 @@ block content
|
||||||
li
|
li
|
||||||
a(href="/admin/pending-patches", data-i18n="resources.patches") Patches
|
a(href="/admin/pending-patches", data-i18n="resources.patches") Patches
|
||||||
if me.isAdmin()
|
if me.isAdmin()
|
||||||
li Analytics
|
li
|
||||||
|
a(href="/admin/analytics") Analytics
|
||||||
ul
|
ul
|
||||||
li
|
li
|
||||||
a(href="/admin/analytics/subscriptions") Subscriptions
|
a(href="/admin/analytics/subscriptions") Subscriptions
|
||||||
li
|
|
||||||
a(href="/admin/analytics/users") Users (needs updating)
|
|
||||||
|
|
||||||
if me.isAdmin()
|
if me.isAdmin()
|
||||||
hr
|
hr
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
extends /templates/base
|
|
||||||
|
|
||||||
block content
|
|
||||||
|
|
||||||
h1(data-i18n="admin.growth_title") Users
|
|
||||||
if me.isAdmin()
|
|
||||||
if crunchingData
|
|
||||||
h4 Crunching Data..
|
|
||||||
else
|
|
||||||
h2 Registered Users
|
|
||||||
h3 Per-Day
|
|
||||||
h4 Totals
|
|
||||||
svg.perDayTotal
|
|
||||||
h4 Added
|
|
||||||
svg.perDayAdded
|
|
||||||
table.table.table-striped.table-bordered.table-condensed
|
|
||||||
-for (var i = 0; i < usersPerDay.length; i++)
|
|
||||||
tr
|
|
||||||
td= usersPerDay[i].date
|
|
||||||
td= usersPerDay[i].added
|
|
||||||
td= usersPerDay[i].total
|
|
||||||
h3 Per-Month
|
|
||||||
h4 Totals
|
|
||||||
svg.perMonthTotal
|
|
||||||
h4 Added
|
|
||||||
svg.perMonthAdded
|
|
||||||
table.table.table-striped.table-bordered.table-condensed
|
|
||||||
-for (var i = 0; i < usersPerMonth.length; i++)
|
|
||||||
tr
|
|
||||||
td= usersPerMonth[i].date
|
|
||||||
td= usersPerMonth[i].added
|
|
||||||
td= usersPerMonth[i].total
|
|
|
@ -1,193 +0,0 @@
|
||||||
RootView = require 'views/core/RootView'
|
|
||||||
template = require 'templates/admin/analytics-users'
|
|
||||||
RealTimeCollection = require 'collections/RealTimeCollection'
|
|
||||||
|
|
||||||
require 'vendor/d3'
|
|
||||||
|
|
||||||
# Growth View ###################
|
|
||||||
#
|
|
||||||
# Display interesting growth data.
|
|
||||||
#
|
|
||||||
# Currently shows:
|
|
||||||
# Registered user totals and added, per-day and per-month
|
|
||||||
# 7-day moving average for registered users added per-day
|
|
||||||
#
|
|
||||||
# TODO: @padding isn't applied correctly
|
|
||||||
# TODO: aggregate recent data if missing?
|
|
||||||
#
|
|
||||||
|
|
||||||
module.exports = class AnalyticsUsersView extends RootView
|
|
||||||
id: 'admin-analytics-users-view'
|
|
||||||
template: template
|
|
||||||
height: 300
|
|
||||||
width: 1000
|
|
||||||
xAxisGuideHeight: 80
|
|
||||||
yAxisGuideWidth: 60
|
|
||||||
padding: 10
|
|
||||||
|
|
||||||
constructor: (options) ->
|
|
||||||
super options
|
|
||||||
@usersPerMonth = new RealTimeCollection 'growth/users/registered/per-month'
|
|
||||||
@usersPerMonth.on 'add', @refreshData
|
|
||||||
@usersPerDay = new RealTimeCollection 'growth/users/registered/per-day'
|
|
||||||
@usersPerDay.on 'add', @refreshData
|
|
||||||
|
|
||||||
destroy: ->
|
|
||||||
@usersPerMonth.off 'add', @refreshData
|
|
||||||
@usersPerDay.off 'add', @refreshData
|
|
||||||
|
|
||||||
refreshData: =>
|
|
||||||
@render()
|
|
||||||
|
|
||||||
getRenderData: ->
|
|
||||||
c = super()
|
|
||||||
c.crunchingData = @usersPerMonth.length is 0 and @usersPerDay.length is 0
|
|
||||||
c.usersPerDay = []
|
|
||||||
# @usersPerDay.each (item) ->
|
|
||||||
# c.usersPerDay.push date: item.get('id'), added: item.get('added'), total: item.get('total')
|
|
||||||
c.usersPerMonth = []
|
|
||||||
# @usersPerMonth.each (item) ->
|
|
||||||
# c.usersPerMonth.push date: item.get('id'), added: item.get('added'), total: item.get('total')
|
|
||||||
c
|
|
||||||
|
|
||||||
afterRender: ->
|
|
||||||
super()
|
|
||||||
if me.isAdmin()
|
|
||||||
@createPerDayChart()
|
|
||||||
@createPerMonthChart()
|
|
||||||
|
|
||||||
createPerDayChart: ->
|
|
||||||
addedData = []
|
|
||||||
totalData = []
|
|
||||||
@usersPerDay.each (item) ->
|
|
||||||
addedData.push id: item.get('id'), value: item.get('added')
|
|
||||||
totalData.push id: item.get('id'), value: item.get('total')
|
|
||||||
@createLineChart ".perDayTotal", totalData, 1000
|
|
||||||
@createLineChart ".perDayAdded", addedData, 10, true
|
|
||||||
|
|
||||||
createPerMonthChart: ->
|
|
||||||
addedData = []
|
|
||||||
totalData = []
|
|
||||||
@usersPerMonth.each (item) ->
|
|
||||||
addedData.push id: item.get('id'), value: item.get('added')
|
|
||||||
totalData.push id: item.get('id'), value: item.get('total')
|
|
||||||
@createLineChart ".perMonthTotal", totalData, 1000
|
|
||||||
@createLineChart ".perMonthAdded", addedData, 1000
|
|
||||||
|
|
||||||
createLineChart: (selector, data, guidelineSpacing, sevenDayAverage=false) ->
|
|
||||||
return unless data.length > 1
|
|
||||||
|
|
||||||
minVal = d3.min(data, (d) -> d.value)
|
|
||||||
maxVal = d3.max(data, (d) -> d.value)
|
|
||||||
|
|
||||||
widthSpacing = (@width - @yAxisGuideWidth - @padding) / (data.length - 1)
|
|
||||||
|
|
||||||
y = d3.scale.linear()
|
|
||||||
.domain([minVal, maxVal])
|
|
||||||
.range([@height - @xAxisGuideHeight - 2 * @padding, 0])
|
|
||||||
|
|
||||||
points = []
|
|
||||||
for i in [0...data.length]
|
|
||||||
points.push id: data[i].id, x: i * widthSpacing + @yAxisGuideWidth, y: y(data[i].value) + @padding
|
|
||||||
|
|
||||||
links = []
|
|
||||||
for i in [0...points.length - 1]
|
|
||||||
if points[i] and points[i + 1]
|
|
||||||
links.push start: points[i], end: points[i + 1]
|
|
||||||
|
|
||||||
guidelines = []
|
|
||||||
diff = maxVal - minVal
|
|
||||||
interval = Math.floor(diff / 5)
|
|
||||||
for i in [0..4]
|
|
||||||
yVal = i * interval + minVal
|
|
||||||
yVal = Math.floor(yVal / guidelineSpacing) * guidelineSpacing
|
|
||||||
guidelines.push start: {id: yVal, x: 0, y: y(yVal)}, end: {id: yVal, x: @width, y: y(yVal)}
|
|
||||||
|
|
||||||
sevenPoints = []
|
|
||||||
sevenLinks = []
|
|
||||||
if sevenDayAverage
|
|
||||||
sevenTotal = 0
|
|
||||||
for i in [0...data.length]
|
|
||||||
sevenTotal += data[i].value
|
|
||||||
if i > 5
|
|
||||||
sevenAvg = sevenTotal / 7
|
|
||||||
sevenPoints.push x: i * widthSpacing + @yAxisGuideWidth, y: y(sevenAvg) + @padding
|
|
||||||
if i > 6
|
|
||||||
sevenTotal -= data[i - 7].value
|
|
||||||
for i in [0...sevenPoints.length - 1]
|
|
||||||
if sevenPoints[i] and sevenPoints[i + 1]
|
|
||||||
sevenLinks.push start: sevenPoints[i], end: sevenPoints[i + 1]
|
|
||||||
|
|
||||||
chart = d3.select(selector)
|
|
||||||
.attr("width", @width)
|
|
||||||
.attr("height", @height)
|
|
||||||
|
|
||||||
chart.selectAll(".circle")
|
|
||||||
.data(points)
|
|
||||||
.enter()
|
|
||||||
.append("circle")
|
|
||||||
.attr("cx", (d) -> d.x )
|
|
||||||
.attr("cy", (d) -> d.y )
|
|
||||||
.attr("r", "2px")
|
|
||||||
.attr("fill", "black")
|
|
||||||
|
|
||||||
chart.selectAll(".text")
|
|
||||||
.data(points)
|
|
||||||
.enter()
|
|
||||||
.append("text")
|
|
||||||
.attr("dy", ".35em")
|
|
||||||
.attr("transform", (d, i) => "translate(" + d.x + "," + @height + ") rotate(270)")
|
|
||||||
.text((d) ->
|
|
||||||
if d.id.length is 8
|
|
||||||
return "#{parseInt(d.id[4..5])}/#{parseInt(d.id[6..7])}/#{d.id[0..3]}"
|
|
||||||
else
|
|
||||||
return "#{parseInt(d.id[4..5])}/#{d.id[0..3]}"
|
|
||||||
)
|
|
||||||
|
|
||||||
chart.selectAll('.line')
|
|
||||||
.data(links)
|
|
||||||
.enter()
|
|
||||||
.append("line")
|
|
||||||
.attr("x1", (d) -> d.start.x )
|
|
||||||
.attr("y1", (d) -> d.start.y )
|
|
||||||
.attr("x2", (d) -> d.end.x )
|
|
||||||
.attr("y2", (d) -> d.end.y )
|
|
||||||
.style("stroke", "rgb(6,120,155)")
|
|
||||||
|
|
||||||
chart.selectAll(".circle")
|
|
||||||
.data(sevenPoints)
|
|
||||||
.enter()
|
|
||||||
.append("circle")
|
|
||||||
.attr("cx", (d) -> d.x )
|
|
||||||
.attr("cy", (d) -> d.y )
|
|
||||||
.attr("r", "2px")
|
|
||||||
.attr("fill", "purple")
|
|
||||||
|
|
||||||
chart.selectAll('.line')
|
|
||||||
.data(sevenLinks)
|
|
||||||
.enter()
|
|
||||||
.append("line")
|
|
||||||
.attr("x1", (d) -> d.start.x )
|
|
||||||
.attr("y1", (d) -> d.start.y )
|
|
||||||
.attr("x2", (d) -> d.end.x )
|
|
||||||
.attr("y2", (d) -> d.end.y )
|
|
||||||
.style("stroke", "rgb(200,0,0)")
|
|
||||||
|
|
||||||
chart.selectAll('.line')
|
|
||||||
.data(guidelines)
|
|
||||||
.enter()
|
|
||||||
.append("line")
|
|
||||||
.attr("x1", (d) -> d.start.x )
|
|
||||||
.attr("y1", (d) -> d.start.y )
|
|
||||||
.attr("x2", (d) -> d.end.x )
|
|
||||||
.attr("y2", (d) -> d.end.y )
|
|
||||||
.style("stroke", "rgb(140,140,140)")
|
|
||||||
|
|
||||||
chart.selectAll(".text")
|
|
||||||
.data(guidelines)
|
|
||||||
.enter()
|
|
||||||
.append("text")
|
|
||||||
.attr("x", (d) -> d.start.x)
|
|
||||||
.attr("y", (d) -> d.start.y - 6)
|
|
||||||
.attr("dy", ".35em")
|
|
||||||
.text((d) -> d.start.id)
|
|
Loading…
Reference in a new issue