public
Description: A simple application written in merb to help you manage ad serving across multiple sites
Clone URL: git://github.com/kneath/greed.git
Basic reporting on the Dashboard
kneath (author)
Sun May 11 22:18:10 -0700 2008
commit  5f97998a36ef6d4af5a6b18ed73e976b29a17a99
tree    43b24e6fb938e876d6c3a4c7128fce8398df6f44
parent  45bab61ace1174c37cbfeea8c44c83cb0f45fcde
...
3
4
5
 
6
7
8
...
3
4
5
6
7
8
9
0
@@ -3,6 +3,7 @@ class Dashboard < Application
0
   before :authenticate
0
   
0
   def index
0
+ @days = Report.days_from_range(Date.today - 30, Date.today)
0
     render
0
   end
0
   
...
1
2
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
5
6
...
1
2
 
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
0
@@ -1,5 +1,28 @@
0
 module Merb
0
     module DashboardHelper
0
-
0
+ def google_bar_graph(collection, x_method, y_method, options = {})
0
+ options[:size] ||= "580x200"
0
+ options[:color] ||= "c6d9fd"
0
+
0
+ max = collection.max{ |a,b| a.send(y_method) <=> b.send(y_method) }.send(y_method)
0
+ labels = []
0
+ collection.each do |item|
0
+ labels << item.send(x_method)
0
+ end
0
+
0
+ query = "http://chart.apis.google.com/chart?cht=bvs&chs=#{options[:size]}&chco=#{options[:color]}"
0
+ query << "&chd=t:" + collection.collect{|d| d.send(y_method) }.join(",")
0
+ query << "&chds=0,#{max}"
0
+ query << "&chxt=x,y"
0
+ query << "&chxl=0:|#{labels.join('|')}|1:|0|#{number_with_delimiter max/4}|#{number_with_delimiter max*2/4}|#{number_with_delimiter max*3/4}|#{number_with_delimiter max}"
0
+ query << "&chg=" + [5000, 25, 1, 3].join(',')
0
+ '<img src="' + query + '" alt="Graph" />'
0
+ end
0
+
0
+ def ctr(clicks, impressions)
0
+ num = clicks.to_f/impressions.to_f*100
0
+ num = 0 if num.nan?
0
+ number_to_percentage(num, :precision => 2)
0
+ end
0
     end
0
 end
0
\ No newline at end of file
...
28
29
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
32
...
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
0
@@ -28,5 +28,74 @@ module Merb
0
       "<form action=\"#{url}\" method=\"post\" class=\"destroy\"><button type=\"submit\" class=\"destroy\">#{text}</button></form>"
0
     end
0
     
0
+ # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You
0
+ # can customize the format using optional <em>delimiter</em> and <em>separator</em> parameters.
0
+ #
0
+ # ==== Options
0
+ # * <tt>delimiter</tt> - Sets the thousands delimiter (defaults to ",").
0
+ # * <tt>separator</tt> - Sets the separator between the units (defaults to ".").
0
+ #
0
+ # ==== Examples
0
+ # number_with_delimiter(12345678) # => 12,345,678
0
+ # number_with_delimiter(12345678.05) # => 12,345,678.05
0
+ # number_with_delimiter(12345678, ".") # => 12.345.678
0
+ #
0
+ # number_with_delimiter(98765432.98, " ", ",")
0
+ # # => 98 765 432,98
0
+ def number_with_delimiter(number, delimiter=",", separator=".")
0
+ begin
0
+ parts = number.to_s.split('.')
0
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
0
+ parts.join separator
0
+ rescue
0
+ number
0
+ end
0
+ end
0
+
0
+ # Formats a +number+ as a percentage string (e.g., 65%). You can customize the
0
+ # format in the +options+ hash.
0
+ #
0
+ # ==== Options
0
+ # * <tt>:precision</tt> - Sets the level of precision (defaults to 3).
0
+ # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
0
+ #
0
+ # ==== Examples
0
+ # number_to_percentage(100) # => 100.000%
0
+ # number_to_percentage(100, :precision => 0) # => 100%
0
+ #
0
+ # number_to_percentage(302.24398923423, :precision => 5)
0
+ # # => 302.24399%
0
+ def number_to_percentage(number, options = {})
0
+ options = options.stringify_keys
0
+ precision = options["precision"] || 3
0
+ separator = options["separator"] || "."
0
+
0
+ begin
0
+ number = number_with_precision(number, precision)
0
+ parts = number.split('.')
0
+ if parts.at(1).nil?
0
+ parts[0] + "%"
0
+ else
0
+ parts[0] + separator + parts[1].to_s + "%"
0
+ end
0
+ rescue
0
+ number
0
+ end
0
+ end
0
+
0
+ # Formats a +number+ with the specified level of +precision+ (e.g., 112.32 has a precision of 2). The default
0
+ # level of precision is 3.
0
+ #
0
+ # ==== Examples
0
+ # number_with_precision(111.2345) # => 111.235
0
+ # number_with_precision(111.2345, 2) # => 111.23
0
+ # number_with_precision(13, 5) # => 13.00000
0
+ # number_with_precision(389.32314, 0) # => 389
0
+ def number_with_precision(number, precision=3)
0
+ "%01.#{precision}f" % ((Float(number) * (10 ** precision)).round.to_f / 10 ** precision)
0
+ rescue
0
+ number
0
+ end
0
+
0
   end
0
 end
...
1
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
...
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0
@@ -1 +1,20 @@
0
-You're in index of the Dashboard
0
\ No newline at end of file
0
+<h1>Overview</h1>
0
+
0
+<h3>Impressions in the past 30 days</h3>
0
+<p><%= google_bar_graph(@days, :short_date, :impressions) %></p>
0
+<table>
0
+ <tr>
0
+ <th>Date</th>
0
+ <th>Impressions</th>
0
+ <th>Clicks</th>
0
+ <th>CTR</th>
0
+ </tr>
0
+ <% for day in @days %>
0
+ <tr>
0
+ <td><%= day.date.to_formatted_s(:general) %></td>
0
+ <td><%= number_with_delimiter day.impressions %></td>
0
+ <td><%= number_with_delimiter day.clicks %></td>
0
+ <td><%= ctr(day.clicks, day.impressions) %></td>
0
+ </tr>
0
+ <% end %>
0
+</table>
0
\ No newline at end of file
...
31
32
33
34
 
35
36
...
31
32
33
 
34
35
36
0
@@ -31,5 +31,5 @@ Merb::Router.prepare do |r|
0
   r.default_routes
0
   
0
   # Change this for your home page to be available at /
0
- # r.match('/').to(:controller => 'whatever', :action =>'index')
0
+ r.match('/').to(:controller => 'dashboard', :action =>'index')
0
 end
0
\ No newline at end of file
...
60
61
62
 
 
 
 
 
 
 
 
 
 
 
63
64
65
...
359
360
361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
363
...
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
...
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
0
@@ -60,6 +60,17 @@ h2 em{
0
   color:#444;
0
 }
0
 
0
+h3{
0
+ font-size:14px;
0
+}
0
+
0
+h4{
0
+ font-size:12px;
0
+ font-weight:normal;
0
+ color:#666;
0
+ text-transform:uppercase;
0
+}
0
+
0
 a{
0
   color:#0077aa;
0
   text-decoration:none;
0
@@ -359,4 +370,30 @@ ul.full-width-spots li{
0
 }
0
 html>body*#wrap .spots button.destroy{
0
   top:10px;
0
+}
0
+
0
+/*------------------------------------------------------------------------------------
0
+ Tables
0
+------------------------------------------------------------------------------------*/
0
+
0
+table{
0
+ width:100%;
0
+ border-spacing:0;
0
+ border-collapse:collapse;
0
+ border:1px solid #eee;
0
+ border-right:none;
0
+ border-bottom:none;
0
+}
0
+
0
+table th, table td{
0
+ padding:2px 5px;
0
+ text-align:left;
0
+ border:1px solid #eee;
0
+ border-top:none;
0
+ border-left:none;
0
+}
0
+
0
+table th{
0
+ text-transform:uppercase;
0
+ border-bottom:2px solid #eee;
0
 }
0
\ No newline at end of file

Comments

    No one has commented yet.