Feature #162: Added sparkline graphs to the overview of analytics. Could be query optimised.
--- a/ckanext/ga_report/controller.py
+++ b/ckanext/ga_report/controller.py
@@ -107,11 +107,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 +136,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 = {
@@ -178,7 +194,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 ])
--- a/ckanext/ga_report/templates/ga_report/site/index.html
+++ b/ckanext/ga_report/templates/ga_report/site/index.html
@@ -6,6 +6,17 @@
<xi:include href="../ga_util.html" />
<py:def function="page_title">Site usage</py:def>
+
+ <py:def function="optional_head">
+ <script type="text/javascript" src="/scripts/vendor/jquery.sparkline.modified.js"></script>
+ <style type="text/css">
+ .table-condensed td.sparkline-cell {
+ padding: 1px 0 0 0;
+ width: 108px;
+ text-align: center;
+ }
+ </style>
+ </py:def>
<py:match path="primarysidebar">
<li class="widget-container boxed widget_text">
@@ -69,11 +80,17 @@
<tr>
<th>Name</th>
<th>Value</th>
+ <th>History</th>
</tr>
- <py:for each="name, value in c.global_totals">
+ <py:for each="name, value, graph in c.global_totals">
<tr>
<td>${name}</td>
<td>${value}</td>
+ <td class="sparkline-cell">
+ <span class="sparkline" sparkTooltips="${','.join([x for x,y in graph])}">
+ ${','.join([y for x,y in graph])}
+ </span>
+ </td>
</tr>
</py:for>
</table>
@@ -115,18 +132,29 @@
</div>
- <xi:include href="../../layout.html" />
<py:def function="optional_footer">
- <script type='text/javascript'>
- $('.dropdown-toggle').dropdown();
- $('.nav-tabs li a').click(function (e) {
- e.preventDefault();
- $(this).tab('show');
- })
- alert(window.location.hash);
+ <script type="text/javascript">
+ $(function() {
+ var sparkOptions = {
+ enableTagOptions: true,
+ type: 'line',
+ width: 100,
+ height: 26,
+ chartRangeMin: 0,
+ spotColor: '',
+ maxSpotColor: '',
+ minSpotColor: '',
+ highlightSpotColor: '000000',
+ lineColor: '3F8E6D',
+ fillColor: 'B7E66B'
+ };
+ $('.sparkline').sparkline('html',sparkOptions);
+ });
</script>
</py:def>
+
+ <xi:include href="../../layout.html" />
</html>