--- a/ckanext/ga_report/controller.py +++ b/ckanext/ga_report/controller.py @@ -1,6 +1,7 @@ import re import csv import sys +import json import logging import operator import collections @@ -21,6 +22,10 @@ d = strptime(strdate, '%Y-%m') return '%s %s' % (calendar.month_name[d.tm_mon], d.tm_year) +def _get_unix_epoch(strdate): + from time import strptime,mktime + d = strptime(strdate, '%Y-%m') + return int(mktime(d)) def _month_details(cls, stat_key=None): ''' @@ -107,11 +112,26 @@ return key, val + # Query historic values for sparkline rendering + graph_query = model.Session.query(GA_Stat)\ + .filter(GA_Stat.stat_name=='Totals')\ + .order_by(GA_Stat.period_name) + graph_data = {} + for x in graph_query: + graph_data[x.key] = graph_data.get(x.key,[]) + key, val = clean_key(x.key,float(x.value)) + tooltip = '%s: %s' % (_get_month_name(x.period_name), val) + graph_data[x.key].append( (tooltip,x.value) ) + # Trim the latest month, as it looks like a huge dropoff + for key in graph_data: + graph_data[key] = graph_data[key][:-1] + c.global_totals = [] if c.month: for e in entries: key, val = clean_key(e.key, e.value) - c.global_totals.append((key, val)) + sparkline = graph_data[e.key] + c.global_totals.append((key, val, sparkline)) else: d = collections.defaultdict(list) for e in entries: @@ -121,9 +141,10 @@ v = sum(v) else: v = float(sum(v))/float(len(v)) + sparkline = graph_data[k] key, val = clean_key(k,v) - c.global_totals.append((key, val)) + c.global_totals.append((key, val, sparkline)) c.global_totals = sorted(c.global_totals, key=operator.itemgetter(0)) keys = { @@ -161,7 +182,29 @@ for k, v in keys.iteritems(): q = model.Session.query(GA_Stat).\ - filter(GA_Stat.stat_name==k) + filter(GA_Stat.stat_name==k).\ + order_by(GA_Stat.period_name) + # Run the query on all months to gather graph data + series = {} + x_axis = set() + for stat in q: + x_val = _get_unix_epoch(stat.period_name) + series[ stat.key ] = series.get(stat.key,{}) + series[ stat.key ][x_val] = float(stat.value) + x_axis.add(x_val) + # Common x-axis for all series. Exclude this month (incomplete data) + x_axis = sorted(list(x_axis))[:-1] + # Buffer a rickshaw dataset from the series + def create_graph(series_name, series_data): + return { + 'name':series_name, + 'data':[ {'x':x,'y':series_data.get(x,0)} for x in x_axis ] + } + rickshaw = [ create_graph(name,data) for name, data in series.items() ] + rickshaw = sorted(rickshaw,key=lambda x:x['data'][-1]['y']) + setattr(c, v+'_graph', json.dumps(rickshaw)) + + # Buffer the tabular data if c.month: entries = [] q = q.filter(GA_Stat.period_name==c.month).\ @@ -178,7 +221,7 @@ # Get the total for each set of values and then set the value as # a percentage of the total if k == 'Social sources': - total = sum([x for n,x in c.global_totals if n == 'Total visits']) + total = sum([x for n,x,graph in c.global_totals if n == 'Total visits']) else: total = sum([num for _,num in entries]) setattr(c, v, [(k,_percent(v,total)) for k,v in entries ])