in site/js/dev/ponymail_trends.js [20:234]
function showTrends(json, state) {
var now = new Date().getTime() / 1000
// Do we have a trend DOM object to edit?
var obj = document.getElementById('trends')
if (!obj) {
return;
}
// size down trend obj
obj.style.maxWidth = "660px"
// Make sure we actually have a timespan > 0 days to analyze.
if (state.tspan == 0) {
obj.innerHTML += "<h4>Invalid date range specified!</h4>"
return
}
// Add the timespan if it makes sense (has a beginning and end)
var daterange = ""
if (state.dfrom || state.dto) {
daterange = " between " + (state.dfrom ? state.dfrom.toDateString() : "beginning of time") + " and " + (state.dto ? state.dto.toDateString() : "now")
}
// Link back to list view if possible
var lname = json.list;
if (lname.search(/\*/) == -1) {
lname = "<a href='list.html?" + lname + "'>" + lname + "</a>"
}
// Set page title
var title = "<div><h2>Statistics for " + lname + "<br/><small>" + daterange + ":</small></h2>"
if ((state.query && state.query.length > 0) || (state.nquery && state.nquery.length > 0)) {
title += "<i>(NB: You are using a search query which may distort these results)"
}
title += "</div>"
obj.innerHTML = title
// for sake of displaying "N days" or just "days", make tspan empty string if null
if (state.tspan == null) {
state.tspan = ""
}
// save each daily stat for later canvas drawing
var daily = {}
// total emails sent in the past N days
var total_emails_current = 0;
var total_emails_past = 0;
// For each email, count the ones in this and the previous time span
for (var i in json.emails) {
var f = parseInt(json.emails[i].epoch/86400)
daily[f] = daily[f] ? daily[f]+1 : 1
if ((state.dfrom == null) || json.emails[i].epoch >= (state.dfrom.getTime()/1000)) {
total_emails_current++;
} else {
total_emails_past++;
}
}
// change since past timespan as relative number and percentage
var diff = total_emails_current-total_emails_past
var pct = parseInt((diff / total_emails_past)*100)
// Make div for emails sent
var emls_sent = document.createElement('div')
emls_sent.setAttribute("style", "float: left; margin: 10px; padding: 5px; text-align: left; border-radius: 8px; background: #F8684E; color: #FFF; font-family: sans-serif; width: 300px;")
emls_sent.innerHTML = "<h2 style='margin: 0px; padding: 0px; text-align: left;'><span class='glyphicon glyphicon-envelope'> </span> " + total_emails_current.toLocaleString() + "</h2><span style='font-size: 13px;'>Emails sent during these " + state.tspan + " days,<br/></span>"
// If a comparison with previous timespan makes sense (can be calculated), show it
if (!isNaN(pct)) {
if (total_emails_current >= total_emails_past) {
emls_sent.innerHTML += "<span style='font-size: 11px;'><b style='color:#00D0F1'>up</b> " + (total_emails_current-total_emails_past) + " (" + pct + "%) compared to previous " + state.tspan + " days.</span>"
} else {
emls_sent.innerHTML += "<span style='font-size: 11px;'><b style='color:#F9BA00'>down</b> " + (total_emails_past-total_emails_current) + " (" + pct + "%) compared to previous " + state.tspan + " days.</span>"
}
}
obj.appendChild(emls_sent)
// total topics started in the past 3 months
var total_topics_current = 0;
var total_topics_past = 0;
// For each thread, count the ones _started_ in this time span and the previous one
for (var i in json.thread_struct) {
if ((state.dfrom == null) || json.thread_struct[i].epoch >= (state.dfrom.getTime()/1000)) {
total_topics_current++;
} else {
total_topics_past++;
}
}
var diff = total_topics_current-total_topics_past
var pct = parseInt((diff / total_topics_past)*100)
// Make div for topics started
var topics_sent = document.createElement('div')
topics_sent.setAttribute("style", "float: left; margin: 10px; padding: 5px; text-align: left; border-radius: 8px; background: #F99A00; color: #FFF; font-family: sans-serif; width: 300px;")
topics_sent.innerHTML = "<h2 style='margin: 0px; padding: 0px; text-align: left;'><span class='glyphicon glyphicon-list-alt'> </span> " + total_topics_current.toLocaleString() + "</h2><span style='font-size: 13px;'>topics started during these " + state.tspan + " days,<br/></span>"
// If a comparison with previous timespan makes sense (can be calculated), show it
if (!isNaN(pct)) {
if (total_topics_current >= total_topics_past) {
topics_sent.innerHTML += "<span style='font-size: 11px;'><b style='color:#00D0F1'>up</b> " + (total_topics_current-total_topics_past) + " (" + pct + "%) compared to previous " + state.tspan + " days.</span>"
} else {
topics_sent.innerHTML += "<span style='font-size: 11px;'><b style='color:#F9BA00'>down</b> " + (total_topics_past-total_topics_current) + " (" + pct + "%) compared to previous " + state.tspan + " days.</span>"
}
}
obj.appendChild(topics_sent)
// people participating in the past 3 months
// As we can't just count them, we'll construct a hash and count the no. of elements in it
var total_people_current = 0;
var total_people_past = 0;
var hc = {}
var hp = {}
// For each email, add to the sender hash for current and previous time span. Count 'em later
for (var i in json.emails) {
if ((state.dfrom == null) || json.emails[i].epoch >= (state.dfrom.getTime()/1000)) {
hc[json.emails[i].from] = (hc[json.emails[i].from] ? hc[json.emails[i].from] : 0) + 1
} else {
hp[json.emails[i].from] = (hp[json.emails[i].from] ? hp[json.emails[i].from] : 0) + 1
}
}
// count elements in the hashes
for (var i in hc) { total_people_current++;}
for (var i in hp) { total_people_past++;}
var diff = total_people_current-total_people_past
var pct = parseInt((diff / total_people_past)*100)
// Make div for participants
var parts = document.createElement('div')
parts.setAttribute("style", "float: left; break-after: always; margin: 10px; padding: 5px; text-align: left; border-radius: 8px; background: #00A757; color: #FFF; font-family: sans-serif; width: 300px;")
parts.innerHTML = "<h2 style='margin: 0px; padding: 0px; text-align: left;'><span class='glyphicon glyphicon-user'> </span> " + total_people_current.toLocaleString() + "</h2><span style='font-size: 13px;'>Participants during these " + state.tspan + " days,</span><br/>"
// If a comparison with previous timespan makes sense (can be calculated), show it
if (!isNaN(pct)) {
if (total_people_current >= total_people_past) {
parts.innerHTML += "<span style='font-size: 11px;'><b style='color:#00D0F1'>up</b> " + (total_people_current-total_people_past) + " (" + pct + "%) compared to previous " + state.tspan + " days.</span>"
} else {
parts.innerHTML += "<span style='font-size: 11px;'><b style='color:#F9BA00'>down</b> " + (total_people_past-total_people_current) + " (" + pct + "%) compared to previous " + state.tspan + " days.</span>"
}
}
obj.appendChild(parts)
// Display charts if possible
if (state.dfrom && state.dto) {
if (!pm_config.trendPie) {
document.getElementById('trendCanvas').setAttribute("height", "340")
document.getElementById('top10pie').setAttribute("height", "0")
}
quokkaBars("trendCanvas",
['Previous timespan', 'Current timespan'],
[
["Emails sent", total_emails_past, total_emails_current],
["Topics started", total_topics_past, total_topics_current],
["Participants", total_people_past, total_people_current],
],
{ stack: false, curve: false, title: "Stats for the past " + state.tspan + " days (compared to previous timespan)", nox: false }
);
}
GetAsync('/api/stats.lua?list='+state.listname+'&domain='+state.domain+'&d=' + state.dspan + "&q=" + ((state.query && state.query.length > 0) ? state.query : "") + state.nquery, {tspan: state.tspan}, showTop)
// daily chart rendering with quokka
var days = []
for (var d in daily) {
days.push(d)
}
days.sort()
var arr = []
// Start from the beginning
var D = new Date(state.dfrom)
D.setDate(D.getDate()-state.tspan)
// For each day from $beginning to $now, push the no. of emails sent that day into an array
while (D <= state.dto) {
var day = new Date(D)
D.setDate(D.getDate()+1)
var d = parseInt(D.getTime()/86400/1000) // make correct pointer to daily[] array
// if in this timespan, color it blue
if (day.getTime() >= state.dfrom.getTime()) {
arr.push([day, daily[d] ? daily[d] : 0, '#00C0F1'])
// else, color it green
} else {
arr.push([day, daily[d] ? daily[d] : 0, '#2DC47B'])
}
}
// draw the chart
quokkaBars("dayCanvas", ['Current timespan', '', 'Previous timespan'], arr, {verts: false, title: "Daily email stats"})
// Add ngrams teaser
var obj = document.getElementById('ngrams')
obj.innerHTML = "Interested in more data? Try our <a href='ngrams.html?" + document.location.search.substr(1) + "'> n-grams page</a>!"
}