From: Tom Rees Date: Fri, 29 Mar 2013 15:27:55 +0000 Subject: [304] most_popular_datasets can render a preview image X-Git-Url: http://maxious.lambdacomplex.org/git/?p=ckanext-ga-report.git&a=commitdiff&h=dad5ea149da26fbd35e6dec1563a22a929d43e81 --- [304] most_popular_datasets can render a preview image --- --- a/ckanext/ga_report/controller.py +++ b/ckanext/ga_report/controller.py @@ -191,25 +191,11 @@ q = model.Session.query(GA_Stat).\ filter(GA_Stat.stat_name==k).\ order_by(GA_Stat.period_name) - # Run the query on all months to gather graph data - graph = {} - for stat in q: - graph[ stat.key ] = graph.get(stat.key,{ - 'name':stat.key, - 'data': [] - }) - graph[ stat.key ]['data'].append({ - 'x':_get_unix_epoch(stat.period_name), - 'y':float(stat.value) - }) - setattr(c, v+'_graph', json.dumps( _to_rickshaw(graph.values(),percentageMode=True) )) - # Buffer the tabular data if c.month: entries = [] q = q.filter(GA_Stat.period_name==c.month).\ order_by('ga_stat.value::int desc') - d = collections.defaultdict(int) for e in q.all(): d[e.key] += int(e.value) @@ -218,6 +204,23 @@ entries.append((key,val,)) entries = sorted(entries, key=operator.itemgetter(1), reverse=True) + # Run a query on all months to gather graph data + graph_query = model.Session.query(GA_Stat).\ + filter(GA_Stat.stat_name==k).\ + order_by(GA_Stat.period_name) + graph_dict = {} + for stat in graph_query: + graph_dict[ stat.key ] = graph_dict.get(stat.key,{ + 'name':stat.key, + 'data': [] + }) + graph_dict[ stat.key ]['data'].append({ + 'x':_get_unix_epoch(stat.period_name), + 'y':float(stat.value) + }) + graph = [ graph_dict[x[0]] for x in entries ] + setattr(c, v+'_graph', json.dumps( _to_rickshaw(graph,percentageMode=True) )) + # Get the total for each set of values and then set the value as # a percentage of the total if k == 'Social sources': @@ -298,7 +301,7 @@ c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month]) c.top_publishers, graph_data = _get_top_publishers() - c.top_publishers_graph = json.dumps( _to_rickshaw(graph_data.values()) ) + c.top_publishers_graph = json.dumps( _to_rickshaw(graph_data) ) return render('ga_report/publisher/index.html') @@ -390,70 +393,73 @@ .filter(model.Package.name==GA_Url.package_id)\ .filter(GA_Url.url.like('/dataset/%'))\ .filter(GA_Url.package_id.in_(top_package_names)) - graph_data = {} + graph_dict = {} for entry,package in graph_query: if not package: continue if entry.period_name=='All': continue - graph_data[package.id] = graph_data.get(package.id,{ + graph_dict[package.name] = graph_dict.get(package.name,{ 'name':package.title, 'data':[] }) - graph_data[package.id]['data'].append({ + graph_dict[package.name]['data'].append({ 'x':_get_unix_epoch(entry.period_name), 'y':int(entry.pageviews), }) - - c.graph_data = json.dumps( _to_rickshaw(graph_data.values()) ) + graph = [ graph_dict[x] for x in top_package_names ] + + c.graph_data = json.dumps( _to_rickshaw(graph) ) return render('ga_report/publisher/read.html') def _to_rickshaw(data, percentageMode=False): if data==[]: return data - # Create a consistent x-axis - num_points = [ len(package['data']) for package in data ] + # Create a consistent x-axis between all series + num_points = [ len(series['data']) for series in data ] ideal_index = num_points.index( max(num_points) ) - x_axis = [ point['x'] for point in data[ideal_index]['data'] ] - for package in data: - xs = [ point['x'] for point in package['data'] ] - assert set(xs).issubset( set(x_axis) ), (xs, x_axis) - # Zero pad any missing values + x_axis = [] + for series in data: + for point in series['data']: + x_axis.append(point['x']) + x_axis = sorted( list( set(x_axis) ) ) + # Zero pad any missing values + for series in data: + xs = [ point['x'] for point in series['data'] ] for x in set(x_axis).difference(set(xs)): - package['data'].append( {'x':x, 'y':0} ) - assert len(package['data'])==len(x_axis), (len(package['data']),len(x_axis),package['data'],x_axis,set(x_axis).difference(set(xs))) + series['data'].append( {'x':x, 'y':0} ) if percentageMode: + def get_totals(series_list): + totals = {} + for series in series_list: + for point in series['data']: + totals[point['x']] = totals.get(point['x'],0) + point['y'] + return totals # Transform data into percentage stacks - totals = {} - for x in x_axis: - for package in data: - for point in package['data']: - totals[ point['x'] ] = totals.get(point['x'],0) + point['y'] + totals = get_totals(data) # Roll insignificant series into a catch-all THRESHOLD = 0.01 - significant_series = [] - for package in data: - for point in package['data']: + raw_data = data + data = [] + for series in raw_data: + for point in series['data']: fraction = float(point['y']) / totals[point['x']] - if fraction>THRESHOLD and not (package in significant_series): - significant_series.append(package) - temp = {} - for package in data: - if package in significant_series: continue - for point in package['data']: - temp[point['x']] = temp.get(point['x'],0) + point['y'] - catch_all = { 'name':'Other','data': [ {'x':x,'y':y} for x,y in temp.items() ] } - # Roll insignificant series into one - data = significant_series - data.append(catch_all) + if not (series in data) and fraction>THRESHOLD: + data.append(series) + # Overwrite data with a set of intereting series + others = [ x for x in raw_data if not (x in data) ] + data.append({ + 'name':'Other', + 'data': [ {'x':x,'y':y} for x,y in get_totals(others).items() ] + }) # Turn each point into a percentage - for package in data: - for point in package['data']: + for series in data: + for point in series['data']: point['y'] = (point['y']*100) / totals[point['x']] # Sort the points - for package in data: - package['data'] = sorted( package['data'], key=lambda x:x['x'] ) + for series in data: + series['data'] = sorted( series['data'], key=lambda x:x['x'] ) # Strip the latest month's incomplete analytics - package['data'] = package['data'][:-1] + series['data'] = series['data'][:-1] return data @@ -485,7 +491,7 @@ department_ids.append(row[0]) top_publishers.append((g, row[1], row[2])) - graph = {} + graph = [] if limit is not None: # Query for a history graph of these publishers q = model.Session.query( @@ -497,15 +503,19 @@ .filter( GA_Url.url.like('/dataset/%') )\ .filter( GA_Url.package_id!='' )\ .group_by( GA_Url.department_id, GA_Url.period_name ) + graph_dict = {} for dept_id,period_name,views in q: - graph[dept_id] = graph.get( dept_id, { + graph_dict[dept_id] = graph_dict.get( dept_id, { 'name' : model.Group.get(dept_id).title, 'data' : [] }) - graph[dept_id]['data'].append({ + graph_dict[dept_id]['data'].append({ 'x': _get_unix_epoch(period_name), 'y': views }) + # Sort dict into ordered list + for id in department_ids: + graph.append( graph_dict[id] ) return top_publishers, graph --- a/ckanext/ga_report/ga_model.py +++ b/ckanext/ga_report/ga_model.py @@ -214,7 +214,7 @@ 'pageviews': views[key], 'visits': visits[key], 'department_id': publisher, - 'package_id': publisher + 'package_id': package } model.Session.add(GA_Url(**values)) model.Session.commit() --- a/ckanext/ga_report/helpers.py +++ b/ckanext/ga_report/helpers.py @@ -80,7 +80,7 @@ return base.render_snippet('ga_report/ga_popular_single.html', **context) -def most_popular_datasets(publisher, count=20): +def most_popular_datasets(publisher, count=20, preview_image=None): if not publisher: _log.error("No valid publisher passed to 'most_popular_datasets'") @@ -92,7 +92,8 @@ 'dataset_count': len(results), 'datasets': results, - 'publisher': publisher + 'publisher': publisher, + 'preview_image': preview_image } return base.render_snippet('ga_report/publisher/popular.html', **ctx) --- a/ckanext/ga_report/public/css/ga_report.css +++ b/ckanext/ga_report/public/css/ga_report.css @@ -2,6 +2,11 @@ padding: 1px 0 0 0; width: 108px; text-align: center; + /* Hack to hide the momentary flash of text + * before sparklines are fully rendered */ + font-size: 1px; + color: transparent; + overflow: hidden; } .rickshaw_chart_container { position: relative; @@ -16,16 +21,9 @@ bottom: 0; } .rickshaw_legend { - position: absolute; - right: 0; - top: 0; - margin-left: 15px; - padding: 0 5px; background: transparent; - max-width: 150px; - overflow: hidden; - background: rgba(0,0,0,0.05); - border-radius:5px; + width: 100%; + padding-top: 4px; } .rickshaw_y_axis { position: absolute; @@ -38,4 +36,29 @@ color: #000000 !important; font-weight: normal !important; } +.rickshaw_legend .instructions { + color: #000; + margin-bottom: 6px; +} +.rickshaw_legend .line .action { + display: none; +} +.rickshaw_legend .line .swatch { + display: block; + float: left; +} +.rickshaw_legend .line .label { + display: block; + white-space: normal; + float: left; + width: 200px; +} +.rickshaw_legend .line .label:hover { + text-decoration: underline; +} + +.ga-reports-table .td-numeric { + text-align: center; +} + --- a/ckanext/ga_report/public/scripts/ckanext_ga_reports.js +++ b/ckanext/ga_report/public/scripts/ckanext_ga_reports.js @@ -1,12 +1,26 @@ - var CKAN = CKAN || {}; CKAN.GA_Reports = {}; CKAN.GA_Reports.render_rickshaw = function( css_name, data, mode, colorscheme ) { + var graphLegends = $('#graph-legend-container'); + + if (!Modernizr.svg) { + $("#chart_"+css_name) + .html( '
Your browser does not support vector graphics. No graphs can be rendered.
') + .closest('.rickshaw_chart_container').css('height',50); + var myLegend = $('
') + .html('(Graph cannot be rendered)') + .appendTo(graphLegends); + return; + } + var myLegend = $('
').appendTo(graphLegends); + var palette = new Rickshaw.Color.Palette( { scheme: colorscheme } ); $.each(data, function(i, object) { object['color'] = palette.color(); }); + // Rickshaw renders the legend in reverse order... + data.reverse(); var graphElement = document.querySelector("#chart_"+css_name); @@ -21,22 +35,88 @@ graph: graph, orientation: 'left', tickFormat: Rickshaw.Fixtures.Number.formatKMBT, - element: document.getElementById('y_axis_'+css_name), + element: document.getElementById('y_axis_'+css_name) } ); var legend = new Rickshaw.Graph.Legend( { element: document.querySelector('#legend_'+css_name), graph: graph } ); - var hoverDetail = new Rickshaw.Graph.HoverDetail( { + var shelving = new Rickshaw.Graph.Behavior.Series.Toggle( { graph: graph, - formatter: function(series, x, y) { - var date = '' + new Date(x * 1000).toUTCString() + ''; - var swatch = ''; - var content = swatch + series.name + ": " + parseInt(y) + '
' + date; - return content; - } + legend: legend } ); + myLegend.prepend('
Click on a series below to isolate its graph:
'); graph.render(); }; +CKAN.GA_Reports.bind_sparklines = function() { + /* + * Bind to the 'totals' tab being on screen, when the + * Sparkline graphs should be drawn. + * Note that they cannot be drawn sooner. + */ + var created = false; + $('a[href="#totals"]').on( + 'shown', + function() { + if (!created) { + 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); + created = true; + } + $.sparkline_display_visible(); + } + ); +}; +CKAN.GA_Reports.bind_sidebar = function() { + /* + * Bind to changes in the tab behaviour: + * Show the correct rickshaw graph in the sidebar. + * Not to be called before all graphs load. + */ + $('a[data-toggle="hashtab"]').on( + 'shown', + function(e) { + var href = $(e.target).attr('href'); + var pane = $(href); + if (!pane.length) { console.err('bad href',href); return; } + var legend_name = "none"; + var graph = pane.find('.rickshaw_chart'); + if (graph.length) { + legend_name = graph.attr('id').replace('chart_',''); + } + legend_name = '#legend_'+legend_name; + $('#graph-legend-container > *').hide(); + $('#graph-legend-container .instructions').show(); + $(legend_name).show(); + } + ); + /* The first tab might already have been shown */ + $('li.active > a[data-toggle="hashtab"]').trigger('shown'); +}; + +CKAN.GA_Reports.bind_month_selector = function() { + var handler = function(e) { + var target = $(e.delegateTarget); + var form = target.closest('form'); + var url = form.attr('action')+'?month='+target.val()+window.location.hash; + window.location = url; + }; + var selectors = $('select[name="month"]'); + assert(selectors.length>0); + selectors.bind('change', handler); +}; + --- /dev/null +++ b/ckanext/ga_report/public/scripts/rickshaw_ie7_shim.js @@ -1,1 +1,109 @@ +/* + * Collection of shims to allow d3 and Rickshaw to load, error-free + * (but ultimately unusable) on Internet Explorer 7. The browser's + * API lacks several crucial functions which these libraries depend + * upon to load; we try to hide these errors from the user. + * + * With thanks to Array functions from: + * http://stackoverflow.com/questions/2790001/fixing-javascript-array-functions-in-internet-explorer-indexof-foreach-etc + * + * Use (Modernizr.svg==true) to detect whether it's okay to draw a graph. + */ +'use strict'; +window.Element = window.Element || {'prototype': {}}; +window.CSSStyleDeclaration = window.CSSStyleDeclaration || {'prototype':{}}; + +// Add ECMA262-5 method binding if not supported natively +// +if (!('bind' in Function.prototype)) { + Function.prototype.bind= function(owner) { + var that= this; + if (arguments.length<=1) { + return function() { + return that.apply(owner, arguments); + }; + } else { + var args= Array.prototype.slice.call(arguments, 1); + return function() { + return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments))); + }; + } + }; +} + +// Add ECMA262-5 string trim if not supported natively +// +if (!('trim' in String.prototype)) { + String.prototype.trim= function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }; +} + +// Add ECMA262-5 Array methods if not supported natively +// +if (!('indexOf' in Array.prototype)) { + Array.prototype.indexOf= function(find, i /*opt*/) { + if (i===undefined) i= 0; + if (i<0) i+= this.length; + if (i<0) i= 0; + for (var n= this.length; ithis.length-1) i= this.length-1; + for (i++; i-->0;) /* i++ because from-argument is sadly inclusive */ + if (i in this && this[i]===find) + return i; + return -1; + }; +} +if (!('forEach' in Array.prototype)) { + Array.prototype.forEach= function(action, that /*opt*/) { + for (var i= 0, n= this.length; ithis.window.xMax&&(b=!1),b}return!0},this.onUpdate=function(a){this.updateCallbacks.push(a)},this.registerRenderer=function(a){this._renderers=this._renderers||{},this._renderers[a.name]=a},this.configure=function(a){(a.width||a.height)&&this.setSize(a),Rickshaw.keys(this.defaults).forEach(function(b){this[b]=b in a?a[b]:b in this?this[b]:this.defaults[b]},this),this.setRenderer(a.renderer||this.renderer.name,a)},this.setRenderer=function(a,b){if(!this._renderers[a])throw"couldn't find renderer "+a;this.renderer=this._renderers[a],typeof b=="object"&&this.renderer.configure(b)},this.setSize=function(a){a=a||{};if(typeof window!==undefined)var b=window.getComputedStyle(this.element,null),c=parseInt(b.getPropertyValue("width")),d=parseInt(b.getPropertyValue("height"));this.width=a.width||c||400,this.height=a.height||d||250,this.vis&&this.vis.attr("width",this.width).attr("height",this.height)},this.initialize(a)},Rickshaw.namespace("Rickshaw.Fixtures.Color"),Rickshaw.Fixtures.Color=function(){this.schemes={},this.schemes.spectrum14=["#ecb796","#dc8f70","#b2a470","#92875a","#716c49","#d2ed82","#bbe468","#a1d05d","#e7cbe6","#d8aad6","#a888c2","#9dc2d3","#649eb9","#387aa3"].reverse(),this.schemes.spectrum2000=["#57306f","#514c76","#646583","#738394","#6b9c7d","#84b665","#a7ca50","#bfe746","#e2f528","#fff726","#ecdd00","#d4b11d","#de8800","#de4800","#c91515","#9a0000","#7b0429","#580839","#31082b"],this.schemes.spectrum2001=["#2f243f","#3c2c55","#4a3768","#565270","#6b6b7c","#72957f","#86ad6e","#a1bc5e","#b8d954","#d3e04e","#ccad2a","#cc8412","#c1521d","#ad3821","#8a1010","#681717","#531e1e","#3d1818","#320a1b"],this.schemes.classic9=["#423d4f","#4a6860","#848f39","#a2b73c","#ddcb53","#c5a32f","#7d5836","#963b20","#7c2626","#491d37","#2f254a"].reverse(),this.schemes.httpStatus={503:"#ea5029",502:"#d23f14",500:"#bf3613",410:"#efacea",409:"#e291dc",403:"#f457e8",408:"#e121d2",401:"#b92dae",405:"#f47ceb",404:"#a82a9f",400:"#b263c6",301:"#6fa024",302:"#87c32b",307:"#a0d84c",304:"#28b55c",200:"#1a4f74",206:"#27839f",201:"#52adc9",202:"#7c979f",203:"#a5b8bd",204:"#c1cdd1"},this.schemes.colorwheel=["#b5b6a9","#858772","#785f43","#96557e","#4682b4","#65b9ac","#73c03a","#cb513a"].reverse(),this.schemes.cool=["#5e9d2f","#73c03a","#4682b4","#7bc3b8","#a9884e","#c1b266","#a47493","#c09fb5"],this.schemes.munin=["#00cc00","#0066b3","#ff8000","#ffcc00","#330099","#990099","#ccff00","#ff0000","#808080","#008f00","#00487d","#b35a00","#b38f00","#6b006b","#8fb300","#b30000","#bebebe","#80ff80","#80c9ff","#ffc080","#ffe680","#aa80ff","#ee00cc","#ff8080","#666600","#ffbfff","#00ffcc","#cc6699","#999900"]},Rickshaw.namespace("Rickshaw.Fixtures.RandomData"),Rickshaw.Fixtures.RandomData=function(a){var b;a=a||1;var c=200,d=Math.floor((new Date).getTime()/1e3);this.addData=function(b){var e=Math.random()*100+15+c,f=b[0].length,g=1;b.forEach(function(b){var c=Math.random()*20,h=e/25+g++ +(Math.cos(f*g*11/960)+2)*15+(Math.cos(f/7)+2)*7+(Math.cos(f/17)+2)*1;b.push({x:f*a+d,y:h+c})}),c=e*.85}},Rickshaw.namespace("Rickshaw.Fixtures.Time"),Rickshaw.Fixtures.Time=function(){var a=(new Date).getTimezoneOffset()*60,b=this;this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],this.units=[{name:"decade",seconds:315576e3,formatter:function(a){return parseInt(a.getUTCFullYear()/10)*10}},{name:"year",seconds:31557600,formatter:function(a){return a.getUTCFullYear()}},{name:"month",seconds:2635200,formatter:function(a){return b.months[a.getUTCMonth()]}},{name:"week",seconds:604800,formatter:function(a){return b.formatDate(a)}},{name:"day",seconds:86400,formatter:function(a){return a.getUTCDate()}},{name:"6 hour",seconds:21600,formatter:function(a){return b.formatTime(a)}},{name:"hour",seconds:3600,formatter:function(a){return b.formatTime(a)}},{name:"15 minute",seconds:900,formatter:function(a){return b.formatTime(a)}},{name:"minute",seconds:60,formatter:function(a){return a.getUTCMinutes()}},{name:"15 second",seconds:15,formatter:function(a){return a.getUTCSeconds()+"s"}},{name:"second",seconds:1,formatter:function(a){return a.getUTCSeconds()+"s"}}],this.unit=function(a){return this.units.filter(function(b){return a==b.name}).shift()},this.formatDate=function(a){return a.toUTCString().match(/, (\w+ \w+ \w+)/)[1]},this.formatTime=function(a){return a.toUTCString().match(/(\d+:\d+):/)[1]},this.ceil=function(a,b){if(b.name=="month"){var c=new Date((a+b.seconds-1)*1e3),d=new Date(0);return d.setUTCFullYear(c.getUTCFullYear()),d.setUTCMonth(c.getUTCMonth()),d.setUTCDate(1),d.setUTCHours(0),d.setUTCMinutes(0),d.setUTCSeconds(0),d.setUTCMilliseconds(0),d.getTime()/1e3}if(b.name=="year"){var c=new Date((a+b.seconds-1)*1e3),d=new Date(0);return d.setUTCFullYear(c.getUTCFullYear()),d.setUTCMonth(0),d.setUTCDate(1),d.setUTCHours(0),d.setUTCMinutes(0),d.setUTCSeconds(0),d.setUTCMilliseconds(0),d.getTime()/1e3}return Math.ceil(a/b.seconds)*b.seconds}},Rickshaw.namespace("Rickshaw.Fixtures.Number"),Rickshaw.Fixtures.Number.formatKMBT=function(a){return a>=1e12?a/1e12+"T":a>=1e9?a/1e9+"B":a>=1e6?a/1e6+"M":a>=1e3?a/1e3+"K":a<1&&a>0?a.toFixed(2):a==0?"":a},Rickshaw.Fixtures.Number.formatBase1024KMGTP=function(a){return a>=0x4000000000000?a/0x4000000000000+"P":a>=1099511627776?a/1099511627776+"T":a>=1073741824?a/1073741824+"G":a>=1048576?a/1048576+"M":a>=1024?a/1024+"K":a<1&&a>0?a.toFixed(2):a==0?"":a},Rickshaw.namespace("Rickshaw.Color.Palette"),Rickshaw.Color.Palette=function(a){var b=new Rickshaw.Fixtures.Color;a=a||{},this.schemes={},this.scheme=b.schemes[a.scheme]||a.scheme||b.schemes.colorwheel,this.runningIndex=0,this.generatorIndex=0;if(a.interpolatedStopCount){var c=this.scheme.length-1,d,e,f=[];for(d=0;dc.graph.x.range()[1]){b.element&&(b.line.classList.add("offscreen"),b.element.style.display="none"),b.boxes.forEach(function(a){a.rangeElement&&a.rangeElement.classList.add("offscreen")});return}if(!b.element){var e=b.element=document.createElement("div");e.classList.add("annotation"),this.elements.timeline.appendChild(e),e.addEventListener("click",function(a){e.classList.toggle("active"),b.line.classList.toggle("active"),b.boxes.forEach(function(a){a.rangeElement&&a.rangeElement.classList.toggle("active")})},!1)}b.element.style.left=d+"px",b.element.style.display="block",b.boxes.forEach(function(a){var e=a.element;e||(e=a.element=document.createElement("div"),e.classList.add("content"),e.innerHTML=a.content,b.element.appendChild(e),b.line=document.createElement("div"),b.line.classList.add("annotation_line"),c.graph.element.appendChild(b.line),a.end&&(a.rangeElement=document.createElement("div"),a.rangeElement.classList.add("annotation_range"),c.graph.element.appendChild(a.rangeElement)));if(a.end){var f=d,g=Math.min(c.graph.x(a.end),c.graph.x.range()[1]);f>g&&(g=d,f=Math.max(c.graph.x(a.end),c.graph.x.range()[0]));var h=g-f;a.rangeElement.style.left=f+"px",a.rangeElement.style.width=h+"px",a.rangeElement.classList.remove("offscreen")}b.line.classList.remove("offscreen"),b.line.style.left=d+"px"})},this)},this.graph.onUpdate(function(){c.update()})},Rickshaw.namespace("Rickshaw.Graph.Axis.Time"),Rickshaw.Graph.Axis.Time=function(a){var b=this;this.graph=a.graph,this.elements=[],this.ticksTreatment=a.ticksTreatment||"plain",this.fixedTimeUnit=a.timeUnit;var c=new Rickshaw.Fixtures.Time;this.appropriateTimeUnit=function(){var a,b=c.units,d=this.graph.x.domain(),e=d[1]-d[0];return b.forEach(function(b){Math.floor(e/b.seconds)>=2&&(a=a||b)}),a||c.units[c.units.length-1]},this.tickOffsets=function(){var a=this.graph.x.domain(),b=this.fixedTimeUnit||this.appropriateTimeUnit(),d=Math.ceil((a[1]-a[0])/b.seconds),e=a[0],f=[];for(var g=0;gb.graph.x.range()[1])return;var c=document.createElement("div");c.style.left=b.graph.x(a.value)+"px",c.classList.add("x_tick"),c.classList.add(b.ticksTreatment);var d=document.createElement("div");d.classList.add("title"),d.innerHTML=a.unit.formatter(new Date(a.value*1e3)),c.appendChild(d),b.graph.element.appendChild(c),b.elements.push(c)})},this.graph.onUpdate(function(){b.render()})},Rickshaw.namespace("Rickshaw.Graph.Axis.Y"),Rickshaw.Graph.Axis.Y=function(a){var b=this,c=.1;this.initialize=function(a){this.graph=a.graph,this.orientation=a.orientation||"right";var c=a.pixelsPerTick||75;this.ticks=a.ticks||Math.floor(this.graph.height/c),this.tickSize=a.tickSize||4,this.ticksTreatment=a.ticksTreatment||"plain",a.element?(this.element=a.element,this.vis=d3.select(a.element).append("svg:svg").attr("class","rickshaw_graph y_axis"),this.element=this.vis[0][0],this.element.style.position="relative",this.setSize({width:a.width,height:a.height})):this.vis=this.graph.vis,this.graph.onUpdate(function(){b.render()})},this.setSize=function(a){a=a||{};if(!this.element)return;if(typeof window!="undefined"){var b=window.getComputedStyle(this.element.parentNode,null),d=parseInt(b.getPropertyValue("width"));if(!a.auto)var e=parseInt(b.getPropertyValue("height"))}this.width=a.width||d||this.graph.width*c,this.height=a.height||e||this.graph.height,this.vis.attr("width",this.width).attr("height",this.height*(1+c));var f=this.height*c;this.element.style.top=-1*f+"px"},this.render=function(){this.graph.height!==this._renderHeight&&this.setSize({auto:!0});var b=d3.svg.axis().scale(this.graph.y).orient(this.orientation);b.tickFormat(a.tickFormat||function(a){return a});if(this.orientation=="left")var d=this.height*c,e="translate("+this.width+", "+d+")";this.element&&this.vis.selectAll("*").remove(),this.vis.append("svg:g").attr("class",["y_ticks",this.ticksTreatment].join(" ")).attr("transform",e).call(b.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));var f=(this.orientation=="right"?1:-1)*this.graph.width;this.graph.vis.append("svg:g").attr("class","y_grid").call(b.ticks(this.ticks).tickSubdivide(0).tickSize(f)),this._renderHeight=this.graph.height},this.initialize(a)},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Highlight"),Rickshaw.Graph.Behavior.Series.Highlight=function(a){this.graph=a.graph,this.legend=a.legend;var b=this,c={};this.addHighlightEvents=function(a){a.element.addEventListener("mouseover",function(d){b.legend.lines.forEach(function(b){if(a===b)return;c[b.series.name]=c[b.series.name]||b.series.color,b.series.color=d3.interpolateRgb(b.series.color,d3.rgb("#d8d8d8"))(.8).toString()}),b.graph.update()},!1),a.element.addEventListener("mouseout",function(a){b.legend.lines.forEach(function(a){c[a.series.name]&&(a.series.color=c[a.series.name])}),b.graph.update()},!1)},this.legend&&this.legend.lines.forEach(function(a){b.addHighlightEvents(a)})},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Order"),Rickshaw.Graph.Behavior.Series.Order=function(a){this.graph=a.graph,this.legend=a.legend;var b=this;$(function(){$(b.legend.list).sortable({containment:"parent",tolerance:"pointer",update:function(a,c){var d=[];$(b.legend.list).find("li").each(function(a,b){if(!b.series)return;d.push(b.series)});for(var e=b.graph.series.length-1;e>=0;e--)b.graph.series[e]=d.shift();b.graph.update()}}),$(b.legend.list).disableSelection()}),this.graph.onUpdate(function(){var a=window.getComputedStyle(b.legend.element).height;b.legend.element.style.height=a})},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Toggle"),Rickshaw.Graph.Behavior.Series.Toggle=function(a){this.graph=a.graph,this.legend=a.legend;var b=this;this.addAnchor=function(a){var c=document.createElement("a");c.innerHTML="✔",c.classList.add("action"),a.element.insertBefore(c,a.element.firstChild),c.onclick=function(b){a.series.disabled?(a.series.enable(),a.element.classList.remove("disabled")):(a.series.disable(),a.element.classList.add("disabled"))};var d=a.element.getElementsByTagName("span")[0];d.onclick=function(c){var d=a.series.disabled;if(!d)for(var e=0;ee){j=k;break}f[0][k+1]<=e?k++:k--}var e=f[0][j].x,l=this.xFormatter(e),m=b.x(e),n=0,o=b.series.active().map(function(a){return{order:n++,series:a,name:a.name,value:a.stack[j]}}),p,q=function(a,b){return a.value.y0+a.value.y-(b.value.y0+b.value.y)},r=b.y.magnitude.invert(b.element.offsetHeight-d);o.sort(q).forEach(function(a){a.formattedYValue=this.yFormatter.constructor==Array?this.yFormatter[o.indexOf(a)](a.value.y):this.yFormatter(a.value.y),a.graphX=m,a.graphY=b.y(a.value.y0+a.value.y),r>a.value.y0&&rthis.window.xMax&&(b=!1),b}return!0},this.onUpdate=function(a){this.updateCallbacks.push(a)},this.registerRenderer=function(a){this._renderers=this._renderers||{},this._renderers[a.name]=a},this.configure=function(a){(a.width||a.height)&&this.setSize(a),Rickshaw.keys(this.defaults).forEach(function(b){this[b]=b in a?a[b]:b in this?this[b]:this.defaults[b]},this),this.setRenderer(a.renderer||this.renderer.name,a)},this.setRenderer=function(a,b){if(!this._renderers[a])throw"couldn't find renderer "+a;this.renderer=this._renderers[a],typeof b=="object"&&this.renderer.configure(b)},this.setSize=function(a){a=a||{};if(typeof window!==undefined)var b=window.getComputedStyle(this.element,null),c=parseInt(b.getPropertyValue("width")),d=parseInt(b.getPropertyValue("height"));this.width=a.width||c||400,this.height=a.height||d||250,this.vis&&this.vis.attr("width",this.width).attr("height",this.height)},this.initialize(a)},Rickshaw.namespace("Rickshaw.Fixtures.Color"),Rickshaw.Fixtures.Color=function(){this.schemes={},this.schemes.spectrum14=["#ecb796","#dc8f70","#b2a470","#92875a","#716c49","#d2ed82","#bbe468","#a1d05d","#e7cbe6","#d8aad6","#a888c2","#9dc2d3","#649eb9","#387aa3"].reverse(),this.schemes.spectrum2000=["#57306f","#514c76","#646583","#738394","#6b9c7d","#84b665","#a7ca50","#bfe746","#e2f528","#fff726","#ecdd00","#d4b11d","#de8800","#de4800","#c91515","#9a0000","#7b0429","#580839","#31082b"],this.schemes.spectrum2001=["#2f243f","#3c2c55","#4a3768","#565270","#6b6b7c","#72957f","#86ad6e","#a1bc5e","#b8d954","#d3e04e","#ccad2a","#cc8412","#c1521d","#ad3821","#8a1010","#681717","#531e1e","#3d1818","#320a1b"],this.schemes.classic9=["#423d4f","#4a6860","#848f39","#a2b73c","#ddcb53","#c5a32f","#7d5836","#963b20","#7c2626","#491d37","#2f254a"].reverse(),this.schemes.httpStatus={503:"#ea5029",502:"#d23f14",500:"#bf3613",410:"#efacea",409:"#e291dc",403:"#f457e8",408:"#e121d2",401:"#b92dae",405:"#f47ceb",404:"#a82a9f",400:"#b263c6",301:"#6fa024",302:"#87c32b",307:"#a0d84c",304:"#28b55c",200:"#1a4f74",206:"#27839f",201:"#52adc9",202:"#7c979f",203:"#a5b8bd",204:"#c1cdd1"},this.schemes.colorwheel=["#b5b6a9","#858772","#785f43","#96557e","#4682b4","#65b9ac","#73c03a","#cb513a"].reverse(),this.schemes.cool=["#5e9d2f","#73c03a","#4682b4","#7bc3b8","#a9884e","#c1b266","#a47493","#c09fb5"],this.schemes.munin=["#00cc00","#0066b3","#ff8000","#ffcc00","#330099","#990099","#ccff00","#ff0000","#808080","#008f00","#00487d","#b35a00","#b38f00","#6b006b","#8fb300","#b30000","#bebebe","#80ff80","#80c9ff","#ffc080","#ffe680","#aa80ff","#ee00cc","#ff8080","#666600","#ffbfff","#00ffcc","#cc6699","#999900"]},Rickshaw.namespace("Rickshaw.Fixtures.RandomData"),Rickshaw.Fixtures.RandomData=function(a){var b;a=a||1;var c=200,d=Math.floor((new Date).getTime()/1e3);this.addData=function(b){var e=Math.random()*100+15+c,f=b[0].length,g=1;b.forEach(function(b){var c=Math.random()*20,h=e/25+g++ +(Math.cos(f*g*11/960)+2)*15+(Math.cos(f/7)+2)*7+(Math.cos(f/17)+2)*1;b.push({x:f*a+d,y:h+c})}),c=e*.85}},Rickshaw.namespace("Rickshaw.Fixtures.Time"),Rickshaw.Fixtures.Time=function(){var a=(new Date).getTimezoneOffset()*60,b=this;this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],this.units=[{name:"decade",seconds:315576e3,formatter:function(a){return parseInt(a.getUTCFullYear()/10)*10}},{name:"year",seconds:31557600,formatter:function(a){return a.getUTCFullYear()}},{name:"month",seconds:2635200,formatter:function(a){return b.months[a.getUTCMonth()]}},{name:"week",seconds:604800,formatter:function(a){return b.formatDate(a)}},{name:"day",seconds:86400,formatter:function(a){return a.getUTCDate()}},{name:"6 hour",seconds:21600,formatter:function(a){return b.formatTime(a)}},{name:"hour",seconds:3600,formatter:function(a){return b.formatTime(a)}},{name:"15 minute",seconds:900,formatter:function(a){return b.formatTime(a)}},{name:"minute",seconds:60,formatter:function(a){return a.getUTCMinutes()}},{name:"15 second",seconds:15,formatter:function(a){return a.getUTCSeconds()+"s"}},{name:"second",seconds:1,formatter:function(a){return a.getUTCSeconds()+"s"}}],this.unit=function(a){return this.units.filter(function(b){return a==b.name}).shift()},this.formatDate=function(a){return a.toUTCString().match(/, (\w+ \w+ \w+)/)[1]},this.formatTime=function(a){return a.toUTCString().match(/(\d+:\d+):/)[1]},this.ceil=function(a,b){if(b.name=="month"){var c=new Date((a+b.seconds-1)*1e3),d=new Date(0);return d.setUTCFullYear(c.getUTCFullYear()),d.setUTCMonth(c.getUTCMonth()),d.setUTCDate(1),d.setUTCHours(0),d.setUTCMinutes(0),d.setUTCSeconds(0),d.setUTCMilliseconds(0),d.getTime()/1e3}if(b.name=="year"){var c=new Date((a+b.seconds-1)*1e3),d=new Date(0);return d.setUTCFullYear(c.getUTCFullYear()),d.setUTCMonth(0),d.setUTCDate(1),d.setUTCHours(0),d.setUTCMinutes(0),d.setUTCSeconds(0),d.setUTCMilliseconds(0),d.getTime()/1e3}return Math.ceil(a/b.seconds)*b.seconds}},Rickshaw.namespace("Rickshaw.Fixtures.Number"),Rickshaw.Fixtures.Number.formatKMBT=function(a){return a>=1e12?a/1e12+"T":a>=1e9?a/1e9+"B":a>=1e6?a/1e6+"M":a>=1e3?a/1e3+"K":a<1&&a>0?a.toFixed(2):a==0?"":a},Rickshaw.Fixtures.Number.formatBase1024KMGTP=function(a){return a>=0x4000000000000?a/0x4000000000000+"P":a>=1099511627776?a/1099511627776+"T":a>=1073741824?a/1073741824+"G":a>=1048576?a/1048576+"M":a>=1024?a/1024+"K":a<1&&a>0?a.toFixed(2):a==0?"":a},Rickshaw.namespace("Rickshaw.Color.Palette"),Rickshaw.Color.Palette=function(a){var b=new Rickshaw.Fixtures.Color;a=a||{},this.schemes={},this.scheme=b.schemes[a.scheme]||a.scheme||b.schemes.colorwheel,this.runningIndex=0,this.generatorIndex=0;if(a.interpolatedStopCount){var c=this.scheme.length-1,d,e,f=[];for(d=0;dc.graph.x.range()[1]){b.element&&(b.line.classList.add("offscreen"),b.element.style.display="none"),b.boxes.forEach(function(a){a.rangeElement&&a.rangeElement.classList.add("offscreen")});return}if(!b.element){var e=b.element=document.createElement("div");e.classList.add("annotation"),this.elements.timeline.appendChild(e),e.addEventListener("click",function(a){e.classList.toggle("active"),b.line.classList.toggle("active"),b.boxes.forEach(function(a){a.rangeElement&&a.rangeElement.classList.toggle("active")})},!1)}b.element.style.left=d+"px",b.element.style.display="block",b.boxes.forEach(function(a){var e=a.element;e||(e=a.element=document.createElement("div"),e.classList.add("content"),e.innerHTML=a.content,b.element.appendChild(e),b.line=document.createElement("div"),b.line.classList.add("annotation_line"),c.graph.element.appendChild(b.line),a.end&&(a.rangeElement=document.createElement("div"),a.rangeElement.classList.add("annotation_range"),c.graph.element.appendChild(a.rangeElement)));if(a.end){var f=d,g=Math.min(c.graph.x(a.end),c.graph.x.range()[1]);f>g&&(g=d,f=Math.max(c.graph.x(a.end),c.graph.x.range()[0]));var h=g-f;a.rangeElement.style.left=f+"px",a.rangeElement.style.width=h+"px",a.rangeElement.classList.remove("offscreen")}b.line.classList.remove("offscreen"),b.line.style.left=d+"px"})},this)},this.graph.onUpdate(function(){c.update()})},Rickshaw.namespace("Rickshaw.Graph.Axis.Time"),Rickshaw.Graph.Axis.Time=function(a){var b=this;this.graph=a.graph,this.elements=[],this.ticksTreatment=a.ticksTreatment||"plain",this.fixedTimeUnit=a.timeUnit;var c=new Rickshaw.Fixtures.Time;this.appropriateTimeUnit=function(){var a,b=c.units,d=this.graph.x.domain(),e=d[1]-d[0];return b.forEach(function(b){Math.floor(e/b.seconds)>=2&&(a=a||b)}),a||c.units[c.units.length-1]},this.tickOffsets=function(){var a=this.graph.x.domain(),b=this.fixedTimeUnit||this.appropriateTimeUnit(),d=Math.ceil((a[1]-a[0])/b.seconds),e=a[0],f=[];for(var g=0;gb.graph.x.range()[1])return;var c=document.createElement("div");c.style.left=b.graph.x(a.value)+"px",c.classList.add("x_tick"),c.classList.add(b.ticksTreatment);var d=document.createElement("div");d.classList.add("title"),d.innerHTML=a.unit.formatter(new Date(a.value*1e3)),c.appendChild(d),b.graph.element.appendChild(c),b.elements.push(c)})},this.graph.onUpdate(function(){b.render()})},Rickshaw.namespace("Rickshaw.Graph.Axis.Y"),Rickshaw.Graph.Axis.Y=function(a){var b=this,c=.1;this.initialize=function(a){this.graph=a.graph,this.orientation=a.orientation||"right";var c=a.pixelsPerTick||75;this.ticks=a.ticks||Math.floor(this.graph.height/c),this.tickSize=a.tickSize||4,this.ticksTreatment=a.ticksTreatment||"plain",a.element?(this.element=a.element,this.vis=d3.select(a.element).append("svg:svg").attr("class","rickshaw_graph y_axis"),this.element=this.vis[0][0],this.element.style.position="relative",this.setSize({width:a.width,height:a.height})):this.vis=this.graph.vis,this.graph.onUpdate(function(){b.render()})},this.setSize=function(a){a=a||{};if(!this.element)return;if(typeof window!="undefined"){var b=window.getComputedStyle(this.element.parentNode,null),d=parseInt(b.getPropertyValue("width"));if(!a.auto)var e=parseInt(b.getPropertyValue("height"))}this.width=a.width||d||this.graph.width*c,this.height=a.height||e||this.graph.height,this.vis.attr("width",this.width).attr("height",this.height*(1+c));var f=this.height*c;this.element.style.top=-1*f+"px"},this.render=function(){this.graph.height!==this._renderHeight&&this.setSize({auto:!0});var b=d3.svg.axis().scale(this.graph.y).orient(this.orientation);b.tickFormat(a.tickFormat||function(a){return a});if(this.orientation=="left")var d=this.height*c,e="translate("+this.width+", "+d+")";this.element&&this.vis.selectAll("*").remove(),this.vis.append("svg:g").attr("class",["y_ticks",this.ticksTreatment].join(" ")).attr("transform",e).call(b.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));var f=(this.orientation=="right"?1:-1)*this.graph.width;this.graph.vis.append("svg:g").attr("class","y_grid").call(b.ticks(this.ticks).tickSubdivide(0).tickSize(f)),this._renderHeight=this.graph.height},this.initialize(a)},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Highlight"),Rickshaw.Graph.Behavior.Series.Highlight=function(a){this.graph=a.graph,this.legend=a.legend;var b=this,c={};this.addHighlightEvents=function(a){a.element.addEventListener("mouseover",function(d){b.legend.lines.forEach(function(b){if(a===b)return;c[b.series.name]=c[b.series.name]||b.series.color,b.series.color=d3.interpolateRgb(b.series.color,d3.rgb("#d8d8d8"))(.8).toString()}),b.graph.update()},!1),a.element.addEventListener("mouseout",function(a){b.legend.lines.forEach(function(a){c[a.series.name]&&(a.series.color=c[a.series.name])}),b.graph.update()},!1)},this.legend&&this.legend.lines.forEach(function(a){b.addHighlightEvents(a)})},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Order"),Rickshaw.Graph.Behavior.Series.Order=function(a){this.graph=a.graph,this.legend=a.legend;var b=this;$(function(){$(b.legend.list).sortable({containment:"parent",tolerance:"pointer",update:function(a,c){var d=[];$(b.legend.list).find("li").each(function(a,b){if(!b.series)return;d.push(b.series)});for(var e=b.graph.series.length-1;e>=0;e--)b.graph.series[e]=d.shift();b.graph.update()}}),$(b.legend.list).disableSelection()}),this.graph.onUpdate(function(){var a=window.getComputedStyle(b.legend.element).height;b.legend.element.style.height=a})},Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Toggle"),Rickshaw.Graph.Behavior.Series.Toggle=function(a){this.graph=a.graph,this.legend=a.legend;var b=this;this.addAnchor=function(a){var c=document.createElement("a");c.innerHTML="✔",c.classList.add("action"),a.element.insertBefore(c,a.element.firstChild),c.onclick=function(b){a.series.disabled?(a.series.enable(),a.element.classList.remove("disabled")):(a.series.disable(),a.element.classList.add("disabled"))};var d=a.element.getElementsByTagName("span")[0];d.onclick=function(c){var d=a.series.disabled;if(!d)for(var e=0;ee){j=k;break}f[0][k+1]<=e?k++:k--}var e=f[0][j].x,l=this.xFormatter(e),m=b.x(e),n=0,o=b.series.active().map(function(a){return{order:n++,series:a,name:a.name,value:a.stack[j]}}),p,q=function(a,b){return a.value.y0+a.value.y-(b.value.y0+b.value.y)},r=b.y.magnitude.invert(b.element.offsetHeight-d);o.sort(q).forEach(function(a){a.formattedYValue=this.yFormatter.constructor==Array?this.yFormatter[o.indexOf(a)](a.value.y):this.yFormatter(a.value.y),a.graphX=m,a.graphY=b.y(a.value.y0+a.value.y),r>a.value.y0&&r0?this[0].data.forEach(function(b){a.data.push({x:b.x,y:0})}):a.data.length==0&&a.data.push({x:this.timeBase-(this.timeInterval||0),y:0}),this.push(a),this.legend&&this.legend.addLine(this.itemByName(a.name))},addData:function(a){var b=this.getIndex();Rickshaw.keys(a).forEach(function(a){this.itemByName(a)||this.addItem({name:a})},this),this.forEach(function(c){c.data.push({x:(b*this.timeInterval||1)+this.timeBase,y:a[c.name]||0})},this)},getIndex:function(){return this[0]&&this[0].data&&this[0].data.length?this[0].data.length:0},itemByName:function(a){for(var b=0;b0;d--)this.currentSize+=1,this.currentIndex+=1,this.forEach(function(a){a.data.unshift({x:((d-1)*this.timeInterval||1)+this.timeBase,y:0,i:d})},this)},addData:function($super,a){$super(a),this.currentSize+=1,this.currentIndex+=1;if(this.maxDataPoints!==undefined)while(this.currentSize>this.maxDataPoints)this.dropData()},dropData:function(){this.forEach(function(a){a.data.splice(0,1)}),this.currentSize-=1},getIndex:function(){return this.currentIndex}}); + --- a/ckanext/ga_report/templates/ga_report/ga_util.html +++ b/ckanext/ga_report/templates/ga_report/ga_util.html @@ -14,7 +14,7 @@ - +
@@ -24,7 +24,7 @@ - +
Name Source
${name} ${source}${count}${count}
@@ -34,44 +34,66 @@
-
- +
- + - +
Name% ${title}% ${title}
${name}${value}${value}
-
-
-
-
--- a/ckanext/ga_report/templates/ga_report/notes.html +++ /dev/null @@ -1,16 +1,1 @@ - -
  • -

    Notes

    -
      -
    • "Views" is the number of times a page was loaded in users' browsers.
    • -
    • "Downloads" is the number of times a user has clicked to download either an original or cached resource for a particular dataset. Download information is only available from 2nd December 2012, 'No data' is shown for records before that date.
    • -
    • These usage statistics are confined to users with javascript enabled, which excludes web crawlers and API calls.
    • -
    • The results are not shown when the number of views/visits is tiny. Where these relate to site pages, results are available in full in the CSV download. Where these relate to users' web browser information, results are not disclosed, for privacy reasons.
    • -
    -
  • - - --- a/ckanext/ga_report/templates/ga_report/publisher/index.html +++ b/ckanext/ga_report/templates/ga_report/publisher/index.html @@ -7,21 +7,17 @@ Usage by Publisher + -
  • -

    Download

    -

    - Download as CSV
    -

    -
  • - + ${ga_sidebar(download_link=h.url_for(controller='ckanext.ga_report.controller:GaDatasetReport',action='publisher_csv',month=c.month or 'all'))}
    - - + + + @@ -29,49 +25,43 @@
    -

    Site Usage

    +

    Site Usage ${usage_nav('Publishers')}

    - ${usage_nav('Publishers')} +
    - -
    + ${rickshaw_graph(c.top_publishers_graph,'publishers')} +
    - - ${month_selector(c.month, c.months, c.day)} - - + + ${month_selector(c.month, c.months, c.day)}
    - ${rickshaw_graph(c.top_publishers_graph,'publishers')} - - - - - +
    PublisherDataset Views
    + + + + - - - - + + + +
    PublisherDataset Views
    - ${h.link_to(publisher.title, h.url_for(controller='ckanext.ga_report.controller:GaDatasetReport', action='read_publisher', id=publisher.name) + (("?month=" + c.month) if c.month else ''))} - ${views}
    + ${h.link_to(publisher.title, h.url_for(controller='ckanext.ga_report.controller:GaDatasetReport', action='read_publisher', id=publisher.name) + (("?month=" + c.month) if c.month else ''))} + ${views}
    - - -
    - - +
    +
    - + --- a/ckanext/ga_report/templates/ga_report/publisher/popular.html +++ b/ckanext/ga_report/templates/ga_report/publisher/popular.html @@ -15,7 +15,12 @@ -

    ${h.link_to("More usage data for " + publisher.title, h.url_for(controller='ckanext.ga_report.controller:GaDatasetReport',action='read_publisher',id=publisher.name))}

    +

    + +
    + More usage data for ${publisher.title} +
    +

    --- a/ckanext/ga_report/templates/ga_report/publisher/read.html +++ b/ckanext/ga_report/templates/ga_report/publisher/read.html @@ -9,30 +9,31 @@ - - + + + -
  • -

    Download

    -

    - Download as CSV
    -

    -
  • - + ${ga_sidebar(download_link=h.url_for(controller='ckanext.ga_report.controller:GaDatasetReport',action='dataset_csv',id=c.publisher_name or 'all',month=c.month or 'all'))}
    -

    Site Usage

    +

    Site Usage ${usage_nav('Datasets')}

    - ${usage_nav('Datasets')} +
    +

    ${c.publisher.title}

    +

    No page views in this period

    + + + ${rickshaw_graph(c.graph_data,'dataset-downloads',debug=True)} +
    @@ -47,14 +48,8 @@
    - -

    ${c.publisher.title}

    - -

    No page views in this period

    - - ${rickshaw_graph(c.graph_data,'dataset-downloads',debug=True)} - +
    @@ -65,13 +60,14 @@ - - + +
    Dataset Views ${h.link_to(package.title or package.name, h.url_for(controller='package', action='read', id=package.name))} ${views}${downloads}${views}${downloads}
    +
    --- a/ckanext/ga_report/templates/ga_report/site/downloads.html +++ b/ckanext/ga_report/templates/ga_report/site/downloads.html @@ -8,19 +8,13 @@ Downloads -
  • -

    Download

    -

    - Download as CSV
    -

    -
  • - - + ${ga_sidebar(download_link=h.url_for(controller='ckanext.ga_report.controller:GaReport',action='csv_downloads',month=c.month or 'all'))}
    -

    Downloads

    - ${usage_nav('Downloads')} +

    Downloads ${usage_nav('Downloads')}

    + +
    @@ -38,6 +32,7 @@

    No data

    There is no download data available for this month

    +
    --- a/ckanext/ga_report/templates/ga_report/site/index.html +++ b/ckanext/ga_report/templates/ga_report/site/index.html @@ -9,82 +9,69 @@ - - + + + -
  • -

    Download

    -

    - Download as CSV
    -

    -
  • - - + ${ga_sidebar(download_link=h.url_for(controller='ckanext.ga_report.controller:GaReport',action='csv',month=c.month or 'all'))}
    -

    Site Usage

    - ${usage_nav('Site-wide')} +

    Site Usage ${usage_nav('Site-wide')}

    - -
    - - ${month_selector(c.month, c.months, c.day)} - - -
    - - +
    - + + + ${month_selector(c.month, c.months, c.day)} + +
    - + - +
    NameValueValue History
    ${name}${value}${value} ${','.join([y for x,y in graph])} @@ -97,59 +84,81 @@
    ${rickshaw_graph(c.browser_versions_graph,'browser-versions',mode='stack')}

    Note: Where a browser has a large number of versions, these have been grouped together.

    +
    + + ${month_selector(c.month, c.months, c.day)} +
    ${stat_table(c.browser_versions)}
    ${rickshaw_graph(c.browsers_graph,'browsers',mode='stack')} +
    + + ${month_selector(c.month, c.months, c.day)} +
    ${stat_table(c.browsers)}
    ${rickshaw_graph(c.os_graph,'os',mode='stack')} +
    + + ${month_selector(c.month, c.months, c.day)} +
    ${stat_table(c.os)}
    ${rickshaw_graph(c.os_versions_graph,'os_versions',mode='stack')} +
    + + ${month_selector(c.month, c.months, c.day)} +
    ${stat_table(c.os_versions)}

    Number of visits that were referred from social networks

    +
    + + ${month_selector(c.month, c.months, c.day)} +
    ${social_table(c.social_referrer_totals)}
    ${rickshaw_graph(c.social_networks_graph, 'social_networks',mode='stack')}

    Percentage of visits that were referred from these social networks

    +
    + + ${month_selector(c.month, c.months, c.day)} +
    ${stat_table(c.social_networks, 'Visits')}
    ${rickshaw_graph(c.languages_graph,'languages',mode='stack')} +
    + + ${month_selector(c.month, c.months, c.day)} +
    ${stat_table(c.languages)}
    ${rickshaw_graph(c.country_graph,'country',mode='stack')} +
    + + ${month_selector(c.month, c.months, c.day)} +
    ${stat_table(c.country)}
    +