Add bounced classification

This commit is contained in:
Jakob Borg 2015-07-15 13:45:33 +02:00
parent 0890b49e78
commit ca9d3b597e
3 changed files with 21 additions and 10 deletions

View File

@ -75,6 +75,7 @@ func setupDB(db *sql.DB) error {
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS UserMovement ( _, err = db.Exec(`CREATE TABLE IF NOT EXISTS UserMovement (
Day TIMESTAMP NOT NULL, Day TIMESTAMP NOT NULL,
Added INTEGER NOT NULL, Added INTEGER NOT NULL,
Bounced INTEGER NOT NULL,
Removed INTEGER NOT NULL Removed INTEGER NOT NULL
)`) )`)
if err != nil { if err != nil {
@ -169,20 +170,26 @@ func aggregateUserMovement(db *sql.DB) (int64, error) {
day time.Time day time.Time
added int added int
removed int removed int
bounced int
} }
var sumRows []sumRow var sumRows []sumRow
for t := minTs; t.Before(time.Now().Truncate(24 * time.Hour)); t = t.AddDate(0, 0, 1) { for t := minTs; t.Before(time.Now().Truncate(24 * time.Hour)); t = t.AddDate(0, 0, 1) {
var added, removed int var added, removed, bounced int
old := t.Before(time.Now().AddDate(0, 0, -14))
for id, first := range firstSeen { for id, first := range firstSeen {
last := lastSeen[id] last := lastSeen[id]
if first.Equal(t) && last.Equal(t) && old {
bounced++
continue
}
if first.Equal(t) { if first.Equal(t) {
added++ added++
} }
if last == t && t.Before(time.Now().AddDate(0, 0, -14)) { if last == t && old {
removed++ removed++
} }
} }
sumRows = append(sumRows, sumRow{t, added, removed}) sumRows = append(sumRows, sumRow{t, added, removed, bounced})
} }
tx, err := db.Begin() tx, err := db.Begin()
@ -194,7 +201,7 @@ func aggregateUserMovement(db *sql.DB) (int64, error) {
return 0, err return 0, err
} }
for _, r := range sumRows { for _, r := range sumRows {
if _, err := tx.Exec("INSERT INTO UserMovement (Day, Added, Removed) VALUES ($1, $2, $3)", r.day, r.added, r.removed); err != nil { if _, err := tx.Exec("INSERT INTO UserMovement (Day, Added, Removed, Bounced) VALUES ($1, $2, $3, $4)", r.day, r.added, r.removed, r.bounced); err != nil {
tx.Rollback() tx.Rollback()
return 0, err return 0, err
} }

View File

@ -576,28 +576,31 @@ func getSummary(db *sql.DB) (summary, error) {
} }
func getMovement(db *sql.DB) ([][]interface{}, error) { func getMovement(db *sql.DB) ([][]interface{}, error) {
rows, err := db.Query(`SELECT Day, Added, Removed FROM UserMovement WHERE Day > now() - '1 year'::INTERVAL ORDER BY Day`) rows, err := db.Query(`SELECT Day, Added, Removed, Bounced FROM UserMovement WHERE Day > now() - '1 year'::INTERVAL ORDER BY Day`)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer rows.Close() defer rows.Close()
res := [][]interface{}{ res := [][]interface{}{
{"Day", "Joined", "Left"}, {"Day", "Joined", "Left", "Bounced"},
} }
for rows.Next() { for rows.Next() {
var day time.Time var day time.Time
var added, removed int var added, removed, bounced int
err := rows.Scan(&day, &added, &removed) err := rows.Scan(&day, &added, &removed, &bounced)
if err != nil { if err != nil {
return nil, err return nil, err
} }
row := []interface{}{day.Format("2006-01-02"), added, -removed} row := []interface{}{day.Format("2006-01-02"), added, -removed, bounced}
if removed == 0 { if removed == 0 {
row[2] = nil row[2] = nil
} }
if bounced == 0 {
row[3] = nil
}
res = append(res, row) res = append(res, row)
} }

View File

@ -70,6 +70,7 @@ found in the LICENSE file.
for (var i = 1; i < rows[0].length; i++){ for (var i = 1; i < rows[0].length; i++){
data.addColumn('number', rows[0][i]); data.addColumn('number', rows[0][i]);
} }
for (var i = 1; i < rows.length; i++){ for (var i = 1; i < rows.length; i++){
rows[i][0] = new Date(rows[i][0]); rows[i][0] = new Date(rows[i][0]);
if (rows[i][1] > 500) { if (rows[i][1] > 500) {
@ -107,7 +108,7 @@ found in the LICENSE file.
<h4>Users Joining and Leaving per Day</h4> <h4>Users Joining and Leaving per Day</h4>
<p> <p>
This is the total number of unique users joining and leaving per day. A user is counted as "joined" on first the day their unique ID is seen, and as "left" on the last day the unique ID was seen before a two weeks or longer absence. This is the total number of unique users joining and leaving per day. A user is counted as "joined" on first the day their unique ID is seen, and as "left" on the last day the unique ID was seen before a two weeks or longer absence. "Bounced" refers to users who joined and left on the same day.
</p> </p>
<div class="img-thumbnail" id="movementChart" style="width: 1130px; height: 400px; padding: 10px;"></div> <div class="img-thumbnail" id="movementChart" style="width: 1130px; height: 400px; padding: 10px;"></div>
<p class="text-muted"> <p class="text-muted">