function showTrends()

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>!"
}