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.
- data/CHANGELOG.md +12 -0
- data/CONTRIBUTING.md +33 -0
- data/Guardfile +10 -0
- data/README.md +105 -23
- data/Rakefile +3 -11
- data/TODO.md +12 -0
- data/bin/redis_analytics_dashboard +1 -1
- data/config.ru +13 -0
- data/lib/redis_analytics.rb +5 -1
- data/lib/redis_analytics/analytics.rb +17 -203
- data/lib/redis_analytics/api.rb +60 -0
- data/lib/redis_analytics/configuration.rb +47 -16
- data/lib/redis_analytics/dashboard.rb +28 -89
- data/lib/redis_analytics/dashboard/public/{favicon.ico → img/favicon.ico} +0 -0
- data/lib/redis_analytics/dashboard/public/javascripts/{bootstrap.min.js → vendor/bootstrap/bootstrap.min.js} +0 -0
- data/lib/redis_analytics/dashboard/public/javascripts/{jquery-1.9.1.min.js → vendor/jquery-1.9.1.min.js} +0 -0
- data/lib/redis_analytics/dashboard/public/javascripts/{jquery-jvectormap-1.2.2.min.js → vendor/jquery-jvectormap-1.2.2.min.js} +0 -0
- data/lib/redis_analytics/dashboard/public/javascripts/{jquery-jvectormap-world-mill-en.js → vendor/jquery-jvectormap-world-mill-en.js} +0 -0
- data/lib/redis_analytics/dashboard/public/javascripts/{morris.min.js → vendor/morris.min.js} +0 -0
- data/lib/redis_analytics/dashboard/public/javascripts/{raphael-min.js → vendor/raphael-min.js} +0 -0
- data/lib/redis_analytics/dashboard/views/activity.erb +7 -0
- data/lib/redis_analytics/dashboard/views/dialogs/unique_visits.erb +41 -0
- data/lib/redis_analytics/dashboard/views/dialogs/visits.erb +40 -0
- data/lib/redis_analytics/dashboard/views/footer.erb +1 -3
- data/lib/redis_analytics/dashboard/views/header.erb +17 -42
- data/lib/redis_analytics/dashboard/views/layout.erb +5 -22
- data/lib/redis_analytics/dashboard/views/visits.erb +38 -143
- data/lib/redis_analytics/dashboard/views/visits_js.erb +110 -247
- data/lib/redis_analytics/dashboard/views/widgets/bounce_rate.erb +3 -0
- data/lib/redis_analytics/dashboard/views/widgets/browsers_donut.erb +8 -0
- data/lib/redis_analytics/dashboard/views/widgets/first_visits.erb +3 -0
- data/lib/redis_analytics/dashboard/views/widgets/page_depth.erb +3 -0
- data/lib/redis_analytics/dashboard/views/widgets/referers_donut.erb +8 -0
- data/lib/redis_analytics/dashboard/views/widgets/total_page_views.erb +3 -0
- data/lib/redis_analytics/dashboard/views/widgets/total_visits.erb +3 -0
- data/lib/redis_analytics/dashboard/views/widgets/unique_visits_line.erb +26 -0
- data/lib/redis_analytics/dashboard/views/widgets/visit_duration.erb +3 -0
- data/lib/redis_analytics/dashboard/views/widgets/visit_spark.erb +23 -0
- data/lib/redis_analytics/dashboard/views/widgets/visitor_recency_slices.erb +39 -0
- data/lib/redis_analytics/dashboard/views/widgets/visits_area.erb +30 -0
- data/lib/redis_analytics/dashboard/views/widgets/visits_donut.erb +8 -0
- data/lib/redis_analytics/dashboard/views/widgets/world_map.erb +50 -0
- data/lib/redis_analytics/filter.rb +33 -0
- data/lib/redis_analytics/helpers.rb +36 -30
- data/lib/redis_analytics/metrics.rb +96 -0
- data/lib/redis_analytics/time_ext.rb +72 -2
- data/lib/redis_analytics/tracker.rb +13 -5
- data/lib/redis_analytics/version.rb +1 -1
- data/lib/redis_analytics/visit.rb +122 -0
- data/redis_analytics.gemspec +19 -14
- data/spec/lib/redis_analytics/analytics_spec.rb +59 -0
- data/spec/lib/redis_analytics/configuration_spec.rb +158 -0
- data/spec/lib/redis_analytics/dashboard_spec.rb +32 -0
- data/spec/lib/redis_analytics/filter_spec.rb +34 -0
- data/spec/lib/redis_analytics/tracker_spec.rb +20 -0
- data/spec/spec_helper.rb +13 -6
- data/spec/support/fakeredis.rb +1 -0
- data/wsd.png +0 -0
- metadata +268 -126
- data/lib/redis_analytics/config.ru +0 -10
- 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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
49
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
-
|
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.
|
106
|
-
case '<%=range%>':
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
133
|
-
|
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
|
178
|
-
document.
|
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
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
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
|
|