redis_analytics 0.1.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/CHANGELOG.md +12 -0
  2. data/CONTRIBUTING.md +33 -0
  3. data/Guardfile +10 -0
  4. data/README.md +105 -23
  5. data/Rakefile +3 -11
  6. data/TODO.md +12 -0
  7. data/bin/redis_analytics_dashboard +1 -1
  8. data/config.ru +13 -0
  9. data/lib/redis_analytics.rb +5 -1
  10. data/lib/redis_analytics/analytics.rb +17 -203
  11. data/lib/redis_analytics/api.rb +60 -0
  12. data/lib/redis_analytics/configuration.rb +47 -16
  13. data/lib/redis_analytics/dashboard.rb +28 -89
  14. data/lib/redis_analytics/dashboard/public/{favicon.ico → img/favicon.ico} +0 -0
  15. data/lib/redis_analytics/dashboard/public/javascripts/{bootstrap.min.js → vendor/bootstrap/bootstrap.min.js} +0 -0
  16. data/lib/redis_analytics/dashboard/public/javascripts/{jquery-1.9.1.min.js → vendor/jquery-1.9.1.min.js} +0 -0
  17. data/lib/redis_analytics/dashboard/public/javascripts/{jquery-jvectormap-1.2.2.min.js → vendor/jquery-jvectormap-1.2.2.min.js} +0 -0
  18. data/lib/redis_analytics/dashboard/public/javascripts/{jquery-jvectormap-world-mill-en.js → vendor/jquery-jvectormap-world-mill-en.js} +0 -0
  19. data/lib/redis_analytics/dashboard/public/javascripts/{morris.min.js → vendor/morris.min.js} +0 -0
  20. data/lib/redis_analytics/dashboard/public/javascripts/{raphael-min.js → vendor/raphael-min.js} +0 -0
  21. data/lib/redis_analytics/dashboard/views/activity.erb +7 -0
  22. data/lib/redis_analytics/dashboard/views/dialogs/unique_visits.erb +41 -0
  23. data/lib/redis_analytics/dashboard/views/dialogs/visits.erb +40 -0
  24. data/lib/redis_analytics/dashboard/views/footer.erb +1 -3
  25. data/lib/redis_analytics/dashboard/views/header.erb +17 -42
  26. data/lib/redis_analytics/dashboard/views/layout.erb +5 -22
  27. data/lib/redis_analytics/dashboard/views/visits.erb +38 -143
  28. data/lib/redis_analytics/dashboard/views/visits_js.erb +110 -247
  29. data/lib/redis_analytics/dashboard/views/widgets/bounce_rate.erb +3 -0
  30. data/lib/redis_analytics/dashboard/views/widgets/browsers_donut.erb +8 -0
  31. data/lib/redis_analytics/dashboard/views/widgets/first_visits.erb +3 -0
  32. data/lib/redis_analytics/dashboard/views/widgets/page_depth.erb +3 -0
  33. data/lib/redis_analytics/dashboard/views/widgets/referers_donut.erb +8 -0
  34. data/lib/redis_analytics/dashboard/views/widgets/total_page_views.erb +3 -0
  35. data/lib/redis_analytics/dashboard/views/widgets/total_visits.erb +3 -0
  36. data/lib/redis_analytics/dashboard/views/widgets/unique_visits_line.erb +26 -0
  37. data/lib/redis_analytics/dashboard/views/widgets/visit_duration.erb +3 -0
  38. data/lib/redis_analytics/dashboard/views/widgets/visit_spark.erb +23 -0
  39. data/lib/redis_analytics/dashboard/views/widgets/visitor_recency_slices.erb +39 -0
  40. data/lib/redis_analytics/dashboard/views/widgets/visits_area.erb +30 -0
  41. data/lib/redis_analytics/dashboard/views/widgets/visits_donut.erb +8 -0
  42. data/lib/redis_analytics/dashboard/views/widgets/world_map.erb +50 -0
  43. data/lib/redis_analytics/filter.rb +33 -0
  44. data/lib/redis_analytics/helpers.rb +36 -30
  45. data/lib/redis_analytics/metrics.rb +96 -0
  46. data/lib/redis_analytics/time_ext.rb +72 -2
  47. data/lib/redis_analytics/tracker.rb +13 -5
  48. data/lib/redis_analytics/version.rb +1 -1
  49. data/lib/redis_analytics/visit.rb +122 -0
  50. data/redis_analytics.gemspec +19 -14
  51. data/spec/lib/redis_analytics/analytics_spec.rb +59 -0
  52. data/spec/lib/redis_analytics/configuration_spec.rb +158 -0
  53. data/spec/lib/redis_analytics/dashboard_spec.rb +32 -0
  54. data/spec/lib/redis_analytics/filter_spec.rb +34 -0
  55. data/spec/lib/redis_analytics/tracker_spec.rb +20 -0
  56. data/spec/spec_helper.rb +13 -6
  57. data/spec/support/fakeredis.rb +1 -0
  58. data/wsd.png +0 -0
  59. metadata +268 -126
  60. data/lib/redis_analytics/config.ru +0 -10
  61. data/spec/redis_analytics_spec.rb +0 -57
@@ -1,29 +1,12 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
- <title>Redis Analytics - Dashboard</title>
5
- <!-- morris js -->
6
- <link rel="stylesheet" href="<%=$template_prefix%>/css/morris.css">
7
- <script src="<%=$template_prefix%>/javascripts/jquery-1.9.1.min.js"></script>
8
- <script src="<%=$template_prefix%>/javascripts/raphael-min.js"></script>
9
- <script src="<%=$template_prefix%>/javascripts/morris.min.js"></script>
10
-
11
- <script src="http://code.highcharts.com/stock/highstock.js"></script>
12
- <script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
13
-
14
- <!-- jvectormap -->
15
- <link rel="stylesheet" href="<%=$template_prefix%>/css/jquery-jvectormap-1.2.2.css" type="text/css" media="screen"/>
16
- <script src="<%=$template_prefix%>/javascripts/jquery-jvectormap-1.2.2.min.js"></script>
17
- <script src="<%=$template_prefix%>/javascripts/jquery-jvectormap-world-mill-en.js"></script>
18
-
19
-
20
- <!-- Bootstrap -->
21
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
22
- <link href="<%=$template_prefix%>/css/bootstrap.min.css" rel="stylesheet" media="screen">
23
- <link href="<%=$template_prefix%>/css/bootstrap-responsive.min.css" rel="stylesheet">
24
-
4
+ <title>Redis Analytics - Dashboard</title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <%= css :application, :media => 'screen' %>
7
+ <%= js :app %>
25
8
  </head>
26
- <body>
9
+ <body onload="changeTimeFrame('<%=@range%>')">
27
10
  <%= erb(:header, :layout => false) %>
28
11
  <!-- start yield -->
29
12
  <%=yield%>
@@ -1,176 +1,71 @@
1
1
  <div class="container-fluid">
2
2
  <div class="row-fluid">
3
3
  <div class="span6">
4
- <table class="table table-bordered table-hover">
5
- <tr>
6
- <td>
7
- <p class="text-center"><b>Visits</b><a href="#visits_modal" data-toggle="modal"><i class="pull-right icon-search"></i></a></p>
8
- <div id="visits_area" style="width:100%;height:160px;"></div>
9
- </td>
10
- </tr>
11
- </table>
4
+ <%= erb :'widgets/visits_area' %>
12
5
  </div>
13
6
  <div class="span2">
14
- <table class="table table-bordered table-hover">
15
- <tr>
16
- <td>
17
- <p class="text-center"><b>Total Visits</b></p>
18
- <div id="visits_donut" style="width:100%;height:160px;"></div>
19
- </td>
20
- </tr>
21
- </table>
7
+ <%= erb :'widgets/visits_donut' %>
22
8
  </div>
23
9
  <div class="span2">
24
- <table class="table table-bordered table-hover">
25
- <tr>
26
- <td>
27
- <p class="text-center"><b>Traffic Sources</b></p>
28
- <div id="referrers_donut" style="width:100%;height:160px;"></div>
29
- </td>
30
- </tr>
31
- </table>
10
+ <%= erb :'widgets/referers_donut' %>
32
11
  </div>
33
12
  <div class="span2">
34
- <table class="table table-bordered table-hover">
35
- <tr>
36
- <td>
37
- <p class="text-center"><b>Browser Info</b></p>
38
- <div id="browsers_donut" style="width:100%;height:160px;"></div>
39
- </td>
40
- </tr>
41
- </table>
13
+ <%= erb :'widgets/browsers_donut' %>
42
14
  </div>
43
-
44
15
  </div>
45
16
 
46
17
  <div class="row-fluid">
47
18
  <div class="span6">
48
- <table class="table table-bordered table-hover">
49
- <tr>
50
- <td>
51
- <p class="text-center"><b>Unique Visits - Current vs Previous <span id="compare_unit"><%=@range%></span></b><a href="#unique_visits_modal" data-toggle="modal"><i class="pull-right icon-search"></i></a></p>
52
- <div id="unique_visits_line" style="width:100%;height:160px;"></div>
53
- </td>
54
- </tr>
55
- </table>
56
- </div>
57
-
19
+ <%= erb :'widgets/unique_visits_line' %>
20
+ </div>
58
21
  <div class="span4">
59
- <table class="table table-bordered">
60
- <tr>
61
- <td>
62
- <p class="text-center"><b>Visitor Map</b></p>
63
- <div id="world-map" class="info" style="width: 100%px; height: 160px"></div>
64
- </td>
65
- </tr>
66
- </table>
22
+ <%= erb :'widgets/world_map' %>
67
23
  </div>
68
24
 
69
25
  <div class="span2">
70
- <table class="table table-bordered table-hover">
71
- <tr>
72
- <td>
73
- <p class="text-center"><b>Visit Recency</b></p>
74
- <div style="height:160px;">
75
- <div style="margin:5px;">
76
- <%p @data[@range][:visitor_recency_slices].inspect %>
77
- <% @data[@range][:visitor_recency_slices].each_with_index do |((k, v), i), c| %>
78
- <% p = ((i.to_f/@data[@range][:visitor_recency_slices].map{|x| x[1]}.sum) * 100).round rescue '0' %>
79
- <div id="recency_<%=c%>_num" title="<%=i.to_i%> visits">
80
- <small class="muted"><%=(k == 0 ? 'Less than' : "#{k}")%> <%=('-' unless k == 0 or v == '*')%> <%=(v == '*' ? ' or more' : "#{v}")%> days (<span id="recency_<%=c%>_cent"><%=p%></span>%)</small>
81
- <div class="progress" style="height: 8px; margin-bottom:10px;">
82
- <div id="recency_<%=c%>" class="bar" style="width: <%=p%>%;"></div>
83
- </div>
84
- </div>
85
- <% end %>
86
- </div>
87
- </div>
88
- </td>
89
- </tr>
90
- </table>
26
+ <%= erb :'widgets/visitor_recency_slices' %>
91
27
  </div>
92
28
  </div>
93
29
 
94
30
  <div class="row-fluid">
95
31
  <div class="span6">
96
32
  <table class="table table-bordered table-hover">
97
- <colgroup>
98
- <col style="width: 33%"></col>
99
- <col style="width: 33%"></col>
100
- <col style="width: 33%"></col>
101
- </colgroup>
102
- <tr>
103
- <td>
104
- <h4 id="total_visits"><%=@data[@range][:total_visits]%><br/><small class="muted">visits</small></h4>
105
- </td>
106
- <td>
107
- <h4 id="total_page_views"><%=@data[@range][:total_page_views]%><br/><small class="muted">page views</small></h4>
108
- </td>
109
- <td>
110
- <h4 id="page_depth"><%=parse_float((@data[@range][:total_page_views].to_f/@data[@range][:total_visits].to_f).round(2))%><br/><small class="muted">pages per visit</small></h4>
111
- </td>
112
- </tr>
113
- <!-- <tr> -->
114
- <!-- <td colspan="3"> -->
115
- <!-- <div id="visits_spark" style="width:100%;height:90px;"></div> -->
116
- <!-- </td> -->
117
- <!-- </tr> -->
33
+ <colgroup>
34
+ <col style="width: 33%"></col>
35
+ <col style="width: 33%"></col>
36
+ <col style="width: 33%"></col>
37
+ </colgroup>
38
+ <tr>
39
+ <td><%= erb :'widgets/total_visits' %></td>
40
+ <td><%= erb :'widgets/total_page_views' %></td>
41
+ <td><%= erb :'widgets/page_depth' %></td>
42
+ </tr>
43
+ <!--
44
+ <tr colspan="3">
45
+ <td>
46
+ <%# erb :'widgets/visit_spark' %>
47
+ </td>
48
+ </tr>
49
+ -->
118
50
  </table>
119
51
  </div>
120
52
  <div class="span6">
121
53
  <table class="table table-bordered table-hover">
122
- <colgroup>
123
- <col style="width: 33%"></col>
124
- <col style="width: 33%"></col>
125
- <col style="width: 33%"></col>
126
- </colgroup>
127
- <tr>
128
- <td>
129
- <h4 id="bounce_rate"><%=parse_float((((@data[@range][:total_visits].to_f-@data[@range][:total_second_page_views].to_f)/@data[@range][:total_visits].to_f)*100).round(2))%>%<br/><small class="muted">bounce rate</small></h4>
130
- </td>
131
- <td>
132
- <h4 id="visit_duration"><%=Time.at(@data[@range][:avg_visit_time].round(2)).gmtime.strftime("%R:%S")%><br/><small class="muted">avg time spent</small></h4>
133
- </td>
134
- <td>
135
- <h4 id="new_visits"><%=parse_float(((@data[@range][:total_new_visits].to_f/@data[@range][:total_visits].to_f)*100).round(2))%>%<br/><small class="muted">new visits</small></h4>
136
- </td>
137
- </tr>
54
+ <colgroup>
55
+ <col style="width: 33%"></col>
56
+ <col style="width: 33%"></col>
57
+ <col style="width: 33%"></col>
58
+ </colgroup>
59
+ <tr>
60
+ <td><%= erb :'widgets/bounce_rate' %></td>
61
+ <td><%= erb :'widgets/visit_duration' %></td>
62
+ <td><%= erb :'widgets/first_visits' %></td>
63
+ </tr>
138
64
  </table>
139
65
  </div>
140
-
141
- </div>
142
-
143
-
144
- </div>
145
-
146
- <!-- Visits Modal -->
147
- <div id="visits_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
148
- <div class="modal-header">
149
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
150
- <h3 id="myModalLabel">Daily Visits</h3>
151
- </div>
152
- <div class="modal-body">
153
- <div id="visits_detail" style="width:900px;height:400px;"></div>
154
- </div>
155
- <div class="modal-footer">
156
- <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
157
- <!-- <button class="btn btn-primary">Save changes</button> -->
158
- </div>
159
- </div>
160
-
161
- <!-- Unique Visits Modal -->
162
- <div id="unique_visits_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
163
- <div class="modal-header">
164
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
165
- <h3 id="myModalLabel">Daily Unique Visits</h3>
166
- </div>
167
- <div class="modal-body">
168
- <div id="unique_visits_detail" style="width:900px;height:400px;"></div>
169
- </div>
170
- <div class="modal-footer">
171
- <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
172
- <!-- <button class="btn btn-primary">Save changes</button> -->
173
66
  </div>
174
67
  </div>
175
68
 
176
- <%=erb(:visits_js)%>
69
+ <%# erb :'dialogs/visits' %>
70
+ <%# erb :'dialogs/unique_visits' %>
71
+ <%= erb :visits_js %>
@@ -1,262 +1,125 @@
1
1
  <script type="text/javascript" language="text/javascript">
2
-
3
- visits_area = Morris.Area({
4
- element: 'visits_area',
5
- xkey: 'date',
6
- data: <%=@data[@range][:visits_new_visits_plot].to_json%>,
7
- ykeys: ['new_visits', 'returning_visits'],
8
- labels: ['New Visits', 'Returning Visits'],
9
- ymax: 'auto',
10
- //events: ['2013-03-02', '2013-03-03'],
11
- grid: true,
12
- eventStrokeWidth: 2,
13
- eventLineColors: ['#ccc', '#eee'],
14
- smooth: true,
15
- hideHover: 'auto',
16
- parseTime: false,
17
- lineWidth: 1,
18
- pointSize: 0,
19
- // xLabels: 'day',
20
- xLabelFormat: function(x) {return '';},
21
-
22
- // hoverCallback: function(index, series)
23
- // {
24
- // h = series.data[index];
25
- // d = Date(h.x);
26
- // return(d + '<br>' + h.new_visits);
27
- // },
28
- pointFillColors: ['#fff'],
29
- pointStrokeColors: ['#000'],
30
- });
31
-
32
- visits_donut = Morris.Donut({
33
- element: 'visits_donut',
34
- data: <%=@data[@range][:visits_new_visits_donut].to_json%>
35
- });
36
-
37
- referrers_donut = Morris.Donut({
38
- element: 'referrers_donut',
39
- data: <%=@data[@range][:referrers_donut].to_json%>
40
- });
41
-
42
- browsers_donut = Morris.Donut({
43
- element: 'browsers_donut',
44
- data: <%=@data[@range][:browsers_donut].to_json%>
45
- });
46
-
47
- unique_visits_line = Morris.Line({
48
- element: 'unique_visits_line',
49
- xkey: 'unit',
50
- data: <%=@data[@range][:unique_visits].to_json%>,
51
- ykeys: ['unique_visits_this', 'unique_visits_last'],
52
- labels: ['Current', 'Previous'],
53
- ymax: 'auto',
54
- hideHover: 'auto',
55
- parseTime: false,
56
- lineWidth: 1,
57
- pointSize: 0,
58
- grid: true,
59
- pointFillColors: ['#fff'],
60
- pointStrokeColors: ['#000'],
61
- // hoverCallback: function(index, series)
62
- // {
63
- // h = series.data[index];
64
- // this_week_color = series.lineColors[0];
65
- // last_week_color = series.lineColors[1];
66
- // html = '';
67
- // html += '<font style="color:' + this_week_color + '">This ' + h.unit + ': ' + h.unique_visits_this + '</font>';
68
- // html += '<br/>';
69
- // html += '<font style="color:' + last_week_color + '">Last ' + h.unit + ': ' + h.unique_visits_last + '</font>';
70
- // return html;
71
- // },
72
-
73
- });
74
-
75
- // visits_spark = Morris.Line({
76
- // element: 'visits_spark',
77
- // xkey: 'date',
78
- // data: <%=@data[@range][:visits_page_views_plot].to_json%>,
79
- // ykeys: ['visits', 'page_views'],
80
- // labels: ['Visits', 'Page Views'],
81
- // xLabelFormat: function(x){return '';},
82
- // yLabelFormat: function(x){return '';},
83
- // hoverCallback: function(i,x){return x.data[i].date + '<br/>' + 'Page Views: ' + x.data[i].page_views + '<br/>Visits: ' + x.data[i].visits;},
84
- // ymax: 'auto',
85
- // ymin: 0,
86
- // smooth: true,
87
- // hideHover: 'auto',
88
- // parseTime: false,
89
- // lineWidth: 2,
90
- // pointSize: 0,
91
- // grid: false,
92
- // pointFillColors: ['#fff'],
93
- // pointStrokeColors: ['#000']
94
- // });
95
-
96
- function setSessionCookie(name,value) {
97
- document.cookie = name+"="+value+"; path=/";
98
- }
99
-
100
2
  function changeTimeFrame(range)
101
3
  {
102
- var mapObject = $('#world-map').vectorMap('get', 'mapObject');
103
- switch(range)
104
- {
105
- <% Rack::RedisAnalytics.time_range_formats.map{|x| x[0].to_s}.each do |range| %>
106
- case '<%=range%>':
107
- setSessionCookie("_rarng", "<%=range%>");
108
- visits_area.setData(<%=@data[range.to_sym][:visits_new_visits_plot].to_json%>);
109
- unique_visits_line.setData(<%=@data[range.to_sym][:unique_visits].to_json%>);
110
-
111
- $("#total_visits")[0].innerHTML = '<%=@data[range.to_sym][:total_visits]%> <small class="muted">visits</small>';
112
- $("#total_page_views")[0].innerHTML = '<%=@data[range.to_sym][:total_page_views]%> <small class="muted">page views</small>';
113
- $("#page_depth")[0].innerHTML = '<%=parse_float((@data[range.to_sym][:total_page_views].to_f/@data[range.to_sym][:total_visits].to_f).round(2))%> <small class="muted">pages per visit</small>';
114
- $("#bounce_rate")[0].innerHTML = '<%=parse_float((((@data[range.to_sym][:total_visits].to_f-@data[range.to_sym][:total_second_page_views].to_f)/@data[range.to_sym][:total_visits].to_f)*100).round(2))%>% <small class="muted">bounce rate</small>';
115
- $("#visit_duration")[0].innerHTML = '<%=Time.at(@data[range.to_sym][:avg_visit_time].round(2)).gmtime.strftime("%R:%S")%> <small class="muted">avg time spent</small>';
116
- $("#new_visits")[0].innerHTML = '<%=parse_float(((@data[range.to_sym][:total_new_visits].to_f/@data[range.to_sym][:total_visits].to_f)*100).round(2))%>% <small class="muted">new visits</small></h4>';
117
-
118
- visits_donut = Morris.Donut({element: 'visits_donut', data: <%=@data[range.to_sym][:visits_new_visits_donut].to_json%>});
119
- browsers_donut = Morris.Donut({element: 'browsers_donut', data: <%=@data[range.to_sym][:browsers_donut].to_json%>});
120
- referrers_donut = Morris.Donut({element: 'referrers_donut', data: <%=@data[range.to_sym][:referrers_donut].to_json%>});
121
- mapObject.series.regions[0].setValues(<%=@data[range.to_sym][:country_map].to_json%>);
122
-
123
- $("#compare_unit")[0].innerHTML = '<%=range%>';
124
-
125
- <% @data[range.to_sym][:visitor_recency_slices].each_with_index do |((k, v), i), c| %>
126
- <% p = ((i.to_f/@data[range.to_sym][:visitor_recency_slices].map{|x| x[1]}.sum) * 100).round rescue '0' %>
127
- <%= "$('#recency_#{c}')[0].style.width = '#{p}%';" %>
128
- <%= "$('#recency_#{c}_num')[0].title = '#{i.to_i} visits';" %>
129
- <%= "$('#recency_#{c}_cent')[0].innerHTML = '#{p}';" %>
130
- <% end %>
4
+ var mapObject = $('#world-map').vectorMap('get', 'mapObject');
5
+ switch(range)
6
+ {
7
+ <% Rack::RedisAnalytics.time_range_formats.each do |range, unit, time_format| %>
8
+ case '<%=range%>':
9
+ setSessionCookie("_rarng", "<%=range%>");
10
+
11
+ // both time range graphs powered by time range data
12
+ $.ajax({
13
+ url: '<%=Rack::RedisAnalytics.api_endpoint + "/data?p=unique_visits,first_visits,repeat_visits&unit_count=#{(1.send(range)/1.send(unit)).round}&unit=#{unit}"%>',
14
+ dataType: "json",
15
+ success: function(data) {
16
+ visits_area.setData(data);
17
+ unique_visits_line.setData(data);
18
+ }
19
+ });
131
20
 
132
- break;
133
- <% end %>
134
- }
21
+ // aggregate data powers the 3 donuts
22
+ $.ajax({
23
+ url: '<%=Rack::RedisAnalytics.api_endpoint + "/data?p=first_visits,repeat_visits,browser,referrer,page_views,second_page_views,visit_time,recency&unit_count=#{(1.send(range)/1.send(unit)).round}&unit=#{unit}&aggregate=yes"%>',
24
+ dataType: "json",
25
+ success: function(data) {
26
+
27
+ // parse visits data from json
28
+ var visits_json_data = []
29
+ var first_visits = data[0].first_visits;
30
+ var repeat_visits = data[1].repeat_visits;
31
+ var total_visits = first_visits + repeat_visits;
32
+ var page_views = data[4].page_views;
33
+ var second_page_views = data[5].second_page_views;
34
+ var page_depth = (page_views/total_visits).toFixed(2);
35
+ var bounce_rate = (((total_visits - second_page_views)/total_visits) * 100).toFixed(2);
36
+ var percent_first_visits = ((first_visits / total_visits) * 100).toFixed(2);
37
+ var total_visit_time = data[6].visit_time;
38
+ var avg_visit_time = ((total_visit_time / total_visits)).toFixed(2);
39
+ var total_recency = data[7].recency;
40
+
41
+ if(total_visits != 0)
42
+ visits_json_data.push({'label': 'First Visits', 'value': first_visits});
43
+ if(total_visits != 0)
44
+ visits_json_data.push({'label': 'Repeat Visits', 'value': repeat_visits});
45
+ visits_donut = Morris.Donut({element: 'visits_donut', data: visits_json_data});
46
+ $("#total_visits")[0].innerHTML = total_visits + ' <small class="muted">visits</small>';
47
+ $("#total_page_views")[0].innerHTML = page_views + ' <small class="muted">page views</small>';
48
+ $("#page_depth")[0].innerHTML = (isNaN(page_depth) ? '?' : page_depth) + ' <small class="muted">pages per visit</small>';
49
+ $("#bounce_rate")[0].innerHTML = (isNaN(bounce_rate) ? '?' : bounce_rate + '%') + ' <small class="muted">bounce rate</small>';
50
+ $("#visit_duration")[0].innerHTML = (isNaN(avg_visit_time) ? '?' : avg_visit_time + ' sec') + ' <small class="muted">avg time spent</small>';
51
+ $("#first_visits")[0].innerHTML = (isNaN(percent_first_visits) ? '?' : percent_first_visits + '%') + ' <small class="muted">new visits</small></h4>';
52
+
53
+ // parse browser data from json
54
+ var browsers_json_data = [];
55
+ for(var i in data[2].browser)
56
+ {
57
+ var browser_data = {}
58
+ browser_data[i] = data[2].browser[i];
59
+ browser_data['label'] = i;
60
+ browser_data['value'] = data[2].browser[i];
61
+ browsers_json_data.push(browser_data);
62
+ }
63
+ browsers_donut = Morris.Donut({element: 'browsers_donut', data: browsers_json_data});
64
+
65
+ // parse referrer data from json
66
+ var referrers_json_data = [];
67
+ for(var i in data[3].referrer)
68
+ {
69
+ var referrer_data = {}
70
+ referrer_data['label'] = i;
71
+ referrer_data['value'] = data[3].referrer[i];
72
+ referrers_json_data.push(referrer_data);
73
+ }
74
+ referrers_donut = Morris.Donut({element: 'referrers_donut', data: referrers_json_data});
75
+ var rec_day = !isNaN(total_recency['d']) ? total_recency['d'] : 0;
76
+ var rec_week = !isNaN(total_recency['w']) ? total_recency['w'] : 0;
77
+ var rec_month = !isNaN(total_recency['m']) ? total_recency['m'] : 0;
78
+ var rec_other = !isNaN(total_recency['o']) ? total_recency['o'] : 0;
79
+ var rec_total = rec_day + rec_week + rec_month + rec_other;
80
+
81
+ if(rec_total > 0)
82
+ {
83
+ $("#recency_d_bar")[0].style.width = $("#recency_d_cent")[0].innerHTML = (rec_day/rec_total) * 100 + '%';
84
+ $("#recency_w_bar")[0].style.width = $("#recency_w_cent")[0].innerHTML = (rec_week/rec_total) * 100 + '%';
85
+ $("#recency_m_bar")[0].style.width = $("#recency_m_cent")[0].innerHTML = (rec_month/rec_total) * 100 + '%';
86
+ $("#recency_o_bar")[0].style.width = $("#recency_o_cent")[0].innerHTML = (rec_other/rec_total) * 100 + '%';
87
+
88
+ $("#recency_d")[0].title = rec_day + ' visits';
89
+ $("#recency_w")[0].title = rec_week + ' visits';
90
+ $("#recency_m")[0].title = rec_month + ' visits';
91
+ $("#recency_o")[0].title = rec_other + ' visits';
92
+ }
93
+
94
+ }
95
+ });
96
+
97
+
98
+ break;
99
+ <% end %>
100
+ }
135
101
  }
136
102
 
137
- // Map Overlay
138
-
139
- var geoLocationData = <%=@data[@range][:country_map].to_json%>;
140
-
141
- $(function(){
142
- $('#world-map').vectorMap({
143
- map: 'world_mill_en',
144
- min: 0,
145
- backgroundColor: '#fff',
146
- regionStyle: {
147
- initial: {
148
- fill: '#ddd',
149
- "fill-opacity": 1,
150
- stroke: 'none',
151
- "stroke-width": 0,
152
- "stroke-opacity": 1
153
- },
154
- hover: {
155
- fill: '#bbb',
156
- "fill-opacity": 0.8
157
- },
158
- selected: {
159
- fill: 'yellow'
160
- },
161
- selectedHover: {
162
- }
163
- },
164
- series: {
165
- regions: [{
166
- scale: ['#C8EEFF', '#0071A4'],
167
- values: geoLocationData,
168
- normalizeFunction: 'polynomial'
169
- }]
170
- },
171
- onLabelShow: function(e, el, code){
172
- el.html(el.html()+' (GDP - '+geoLocationData[code]+')');
173
- }
174
- });
175
- });
176
103
 
177
- function onDownload() {
178
- document.location = 'data:Application/octet-stream,' +
179
- encodeURIComponent(convertToCSV(<%=@data[@range][:visits_new_visits_plot].to_json%>));
104
+ function setSessionCookie(name,value) {
105
+ document.cookie = name+"="+value+"; path=/";
180
106
  }
181
107
 
182
108
  function convertToCSV(objArray) {
183
- var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
184
- var str = '';
185
-
186
- for (var i = 0; i < array.length; i++) {
187
- var line = '';
188
- for (var index in array[i]) {
189
- if (line != '') line += ','
190
-
191
- line += array[i][index];
192
- }
193
-
194
- str += line + '\r\n';
195
- }
196
-
197
- return str;
198
- };
199
-
200
- $('#visits_modal').on('show', function () {
201
-
202
- colors = Highcharts.getOptions().colors;
203
-
204
- // create the chart when all data is loaded
205
- $(function(){
206
-
207
- $('#visits_detail').highcharts('StockChart', {
208
- chart: {
209
- },
210
-
211
- // tooltip: {
212
- // pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
213
- // valueDecimals: 2
214
- // },
215
- yAxis: {
216
- allowDecimals: false
217
- },
218
- xAxis: {
219
- allowDecimals: false
220
- },
221
-
222
- series: [{
223
- name: 'Visits',
224
- data: <%=@data[:all_visits].to_json%>
225
- }]
226
- });
227
- });
228
- });
109
+ var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
110
+ var str = '';
111
+ for (var i = 0; i < array.length; i++) {
112
+ var line = '';
113
+ for (var index in array[i]) {
114
+ if (line != '') line += ','
115
+ line += array[i][index];
116
+ }
117
+ str += line + '\r\n';
118
+ }
119
+ return str;
120
+ };
229
121
 
230
122
 
231
- $('#unique_visits_modal').on('show', function () {
232
-
233
- colors = Highcharts.getOptions().colors;
234
-
235
- // create the chart when all data is loaded
236
- $(function(){
237
-
238
- $('#unique_visits_detail').highcharts('StockChart', {
239
- chart: {
240
- },
241
-
242
- // tooltip: {
243
- // pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
244
- // valueDecimals: 2
245
- // },
246
- yAxis: {
247
- allowDecimals: false
248
- },
249
- xAxis: {
250
- allowDecimals: false
251
- },
252
-
253
- series: [{
254
- name: 'Unique Visits',
255
- data: <%=@data[:all_unique_visits].to_json%>
256
- }]
257
- });
258
- });
259
- });
260
123
 
261
124
  </script>
262
125