FIX: time to first response metric

This commit is contained in:
Régis Hanol
2015-08-04 18:23:56 +02:00
parent 98fa098e6f
commit 64dd28d885
2 changed files with 75 additions and 85 deletions

View File

@ -1,14 +1,12 @@
import round from "discourse/lib/round"; import round from "discourse/lib/round";
const Report = Discourse.Model.extend({ const Report = Discourse.Model.extend({
reportUrl: function() { reportUrl: Discourse.computed.fmt("type", "/admin/reports/%@"),
return("/admin/reports/" + this.get('type'));
}.property('type'),
valueAt(numDaysAgo) { valueAt(numDaysAgo) {
if (this.data) { if (this.data) {
var wantedDate = moment().subtract(numDaysAgo, 'days').format('YYYY-MM-DD'); const wantedDate = moment().subtract(numDaysAgo, "days").format("YYYY-MM-DD");
var item = this.data.find( function(d) { return d.x === wantedDate; } ); const item = this.data.find(d => d.x === wantedDate);
if (item) { if (item) {
return item.y; return item.y;
} }
@ -16,128 +14,117 @@ const Report = Discourse.Model.extend({
return 0; return 0;
}, },
sumDays(startDaysAgo, endDaysAgo) { valueFor(startDaysAgo, endDaysAgo) {
if (this.data) { if (this.data) {
var earliestDate = moment().subtract(endDaysAgo, 'days').startOf('day'); const earliestDate = moment().subtract(endDaysAgo, "days").startOf("day");
var latestDate = moment().subtract(startDaysAgo, 'days').startOf('day'); const latestDate = moment().subtract(startDaysAgo, "days").startOf("day");
var d, sum = 0; var d, sum = 0, count = 0;
_.each(this.data,function(datum){ _.each(this.data, datum => {
d = moment(datum.x); d = moment(datum.x);
if(d >= earliestDate && d <= latestDate) { if (d >= earliestDate && d <= latestDate) {
sum += datum.y; sum += datum.y;
count++;
} }
}); });
if (this.get("method") === "average") { sum /= count; }
return round(sum, -2); return round(sum, -2);
} }
}, },
todayCount: function() { todayCount: function() { return this.valueAt(0); }.property("data"),
return this.valueAt(0); yesterdayCount: function() { return this.valueAt(1); }.property("data"),
}.property('data'), sevenDaysAgoCount: function() { return this.valueAt(7); }.property("data"),
thirtyDaysAgoCount: function() { return this.valueAt(30); }.property("data"),
yesterdayCount: function() { lastSevenDaysCount: function() { return this.valueFor(1, 7); }.property("data"),
return this.valueAt(1); lastThirtyDaysCount: function() { return this.valueFor(1, 30); }.property("data"),
}.property('data'),
lastSevenDaysCount: function() {
return this.sumDays(1,7);
}.property('data'),
lastThirtyDaysCount: function() {
return this.sumDays(1,30);
}.property('data'),
sevenDaysAgoCount: function() {
return this.valueAt(7);
}.property('data'),
thirtyDaysAgoCount: function() {
return this.valueAt(30);
}.property('data'),
yesterdayTrend: function() { yesterdayTrend: function() {
var yesterdayVal = this.valueAt(1); const yesterdayVal = this.valueAt(1);
var twoDaysAgoVal = this.valueAt(2); const twoDaysAgoVal = this.valueAt(2);
if ( yesterdayVal > twoDaysAgoVal ) { if (yesterdayVal > twoDaysAgoVal) {
return 'trending-up'; return "trending-up";
} else if ( yesterdayVal < twoDaysAgoVal ) { } else if (yesterdayVal < twoDaysAgoVal) {
return 'trending-down'; return "trending-down";
} else { } else {
return 'no-change'; return "no-change";
} }
}.property('data'), }.property("data"),
sevenDayTrend: function() { sevenDayTrend: function() {
var currentPeriod = this.sumDays(1,7); const currentPeriod = this.valueFor(1, 7);
var prevPeriod = this.sumDays(8,14); const prevPeriod = this.valueFor(8, 14);
if ( currentPeriod > prevPeriod ) { if (currentPeriod > prevPeriod) {
return 'trending-up'; return "trending-up";
} else if ( currentPeriod < prevPeriod ) { } else if (currentPeriod < prevPeriod) {
return 'trending-down'; return "trending-down";
} else { } else {
return 'no-change'; return "no-change";
} }
}.property('data'), }.property("data"),
thirtyDayTrend: function() { thirtyDayTrend: function() {
if( this.get('prev30Days') ) { if (this.get("prev30Days")) {
var currentPeriod = this.sumDays(1,30); const currentPeriod = this.valueFor(1, 30);
if( currentPeriod > this.get('prev30Days') ) { if (currentPeriod > this.get("prev30Days")) {
return 'trending-up'; return "trending-up";
} else if ( currentPeriod < this.get('prev30Days') ) { } else if (currentPeriod < this.get("prev30Days")) {
return 'trending-down'; return "trending-down";
} }
} }
return 'no-change'; return "no-change";
}.property('data', 'prev30Days'), }.property("data", "prev30Days"),
icon: function() { icon: function() {
switch( this.get('type') ) { switch (this.get("type")) {
case 'flags': case "flags": return "flag";
return 'flag'; case "likes": return "heart";
case 'likes': default: return null;
return 'heart';
default:
return null;
} }
}.property('type'), }.property("type"),
method: function() {
if (this.get("type") === "time_to_first_response") {
return "average";
} else {
return "sum";
}
}.property("type"),
percentChangeString(val1, val2) { percentChangeString(val1, val2) {
var val = ((val1 - val2) / val2) * 100; const val = ((val1 - val2) / val2) * 100;
if( isNaN(val) || !isFinite(val) ) { if (isNaN(val) || !isFinite(val)) {
return null; return null;
} else if( val > 0 ) { } else if (val > 0) {
return '+' + val.toFixed(0) + '%'; return "+" + val.toFixed(0) + "%";
} else { } else {
return val.toFixed(0) + '%'; return val.toFixed(0) + "%";
} }
}, },
changeTitle(val1, val2, prevPeriodString) { changeTitle(val1, val2, prevPeriodString) {
var title = ''; const percentChange = this.percentChangeString(val1, val2);
var percentChange = this.percentChangeString(val1, val2); var title = "";
if( percentChange ) { if (percentChange) { title += percentChange + " change. "; }
title += percentChange + ' change. '; title += "Was " + val2 + " " + prevPeriodString + ".";
}
title += 'Was ' + val2 + ' ' + prevPeriodString + '.';
return title; return title;
}, },
yesterdayCountTitle: function() { yesterdayCountTitle: function() {
return this.changeTitle( this.valueAt(1), this.valueAt(2),'two days ago'); return this.changeTitle(this.valueAt(1), this.valueAt(2), "two days ago");
}.property('data'), }.property("data"),
sevenDayCountTitle: function() { sevenDayCountTitle: function() {
return this.changeTitle( this.sumDays(1,7), this.sumDays(8,14), 'two weeks ago'); return this.changeTitle(this.valueFor(1, 7), this.valueFor(8, 14), "two weeks ago");
}.property('data'), }.property("data"),
thirtyDayCountTitle: function() { thirtyDayCountTitle: function() {
return this.changeTitle( this.sumDays(1,30), this.get('prev30Days'), 'in the previous 30 day period'); return this.changeTitle(this.valueFor(1, 30), this.get("prev30Days"), "in the previous 30 day period");
}.property('data'), }.property("data"),
dataReversed: function() { dataReversed: function() {
return this.get('data').toArray().reverse(); return this.get("data").toArray().reverse();
}.property('data') }.property("data")
}); });

View File

@ -14,8 +14,11 @@ test("counts", function() {
equal(report.get('todayCount'), 5); equal(report.get('todayCount'), 5);
equal(report.get('yesterdayCount'), 4); equal(report.get('yesterdayCount'), 4);
equal(report.sumDays(2, 4), 6, "adds the values for the given range of days, inclusive"); equal(report.valueFor(2, 4), 6, "adds the values for the given range of days, inclusive");
equal(report.get('lastSevenDaysCount'), 307, "sums 7 days excluding today"); equal(report.get('lastSevenDaysCount'), 307, "sums 7 days excluding today");
report.set("method", "average");
equal(report.valueFor(2, 4), 2, "averages the values for the given range of days");
}); });
test("percentChangeString", function() { test("percentChangeString", function() {