Commit de10b96f4dcfabc3b676033f474ffe7e4853b8c5

Authored by Felipe Bormann
1 parent 5d37117c

improved styling as well as displaying most active users as well as most accessed subjects

analytics/static/.sass-cache/9bdb779ec82a4a96f72be09b83b7c997addd0129/general.sassc
No preview for this file type
analytics/static/analytics/general.css
@@ -63,8 +63,8 @@ @@ -63,8 +63,8 @@
63 color: #009688; } 63 color: #009688; }
64 64
65 .selector { 65 .selector {
66 - width: 80%;  
67 - height: 40px; 66 + width: 90%;
  67 + height: 20%;
68 color: white; 68 color: white;
69 padding-left: 5px; 69 padding-left: 5px;
70 background-color: #009688; 70 background-color: #009688;
@@ -74,4 +74,21 @@ @@ -74,4 +74,21 @@
74 padding-top: 10px; 74 padding-top: 10px;
75 font-size: 16px; } 75 font-size: 16px; }
76 76
  77 +.middle-chart article {
  78 + text-align: center; }
  79 +
  80 +.most-accessed-list {
  81 + background-color: #52b7bd;
  82 + width: 80%;
  83 + margin-left: 2%;
  84 + margin-top: 2%;
  85 + padding-left: 0;
  86 + color: white;
  87 + transition: width 2s, height 2s, background-color 2s, transform 2s; }
  88 + .most-accessed-list li {
  89 + padding-left: 1%; }
  90 +
  91 +.most-accessed-item:hover {
  92 + background-color: #3aa7ad; }
  93 +
77 /*# sourceMappingURL=general.css.map */ 94 /*# sourceMappingURL=general.css.map */
analytics/static/analytics/general.css.map
1 { 1 {
2 "version": 3, 2 "version": 3,
3 -"mappings": "AAEA,YAAY;EACR,MAAM,EAAE,iBAAiB;EACzB,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,QAAQ,EAAE,IAAI;EACd,KAAK,EAAE,IAAI;;AAEf,sBAAsB;EAClB,MAAM,EAAE,GAAG;EACX,OAAO,EAAE,KAAK;EACd,yBAAE;IACE,KAAK,EAbC,OAAO;EAejB,yBAAE;IACE,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,WAAW;IACpB,KAAK,EAAE,GAAG;IACV,MAAM,EAAE,GAAG;IAEX,4BAAE;MACE,YAAY,EAAE,EAAE;MAChB,KAAK,EAAE,GAAG;MACV,KAAK,EAAE,KAAK;MAEZ,yCAAY;QACR,gBAAgB,EAAE,OAAO;QACzB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,MAAM;QAClB,aAAa,EAAE,IAAI;MAEvB,gCAAG;QACC,gBAAgB,EAAE,OAAO;QACzB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,MAAM;QAClB,aAAa,EAAE,IAAI;;AAInC,sBAAsB;EAClB,UAAU,EAAE,2CAA2C;EACvD,MAAM,EAAE,IAAI;EACZ,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,OAAO;EACd,WAAW,EAAE,GAAG;EAChB,UAAU,EAAE,IAAI;EAEhB,yBAAE;IACE,WAAW,EAAE,EAAE;;AAEvB,eAAe;EACX,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;AAEhB,UAAU;EACN,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,OAAO;EACd,KAAK,EAAE,IAAI;;AAIf,SAAS;EACL,KAAK,EAAE,OAAO;EACd,SAAS,EAAE,IAAI;;AAGnB,mBAAmB;EACf,UAAU,EAAE,iCAAmC;;AAEnD,MAAM;EACF,KAAK,EAAE,GAAG;EACV,KAAK,EAAE,IAAI;EACX,SAAE;IACE,KAAK,EA1EC,OAAO;;AA4ErB,SAAS;EACL,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,KAAK;EACZ,YAAY,EAAE,GAAG;EACjB,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,iBAAiB;EAChC,WAAC;IACG,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,IAAI", 3 +"mappings": "AAEA,YAAY;EACR,MAAM,EAAE,iBAAiB;EACzB,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,QAAQ,EAAE,IAAI;EACd,KAAK,EAAE,IAAI;;AAEf,sBAAsB;EAClB,MAAM,EAAE,GAAG;EACX,OAAO,EAAE,KAAK;EACd,yBAAE;IACE,KAAK,EAbC,OAAO;EAejB,yBAAE;IACE,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,WAAW;IACpB,KAAK,EAAE,GAAG;IACV,MAAM,EAAE,GAAG;IAEX,4BAAE;MACE,YAAY,EAAE,EAAE;MAChB,KAAK,EAAE,GAAG;MACV,KAAK,EAAE,KAAK;MAEZ,yCAAY;QACR,gBAAgB,EAAE,OAAO;QACzB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,MAAM;QAClB,aAAa,EAAE,IAAI;MAEvB,gCAAG;QACC,gBAAgB,EAAE,OAAO;QACzB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,MAAM;QAClB,aAAa,EAAE,IAAI;;AAInC,sBAAsB;EAClB,UAAU,EAAE,2CAA2C;EACvD,MAAM,EAAE,IAAI;EACZ,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,OAAO;EACd,WAAW,EAAE,GAAG;EAChB,UAAU,EAAE,IAAI;EAEhB,yBAAE;IACE,WAAW,EAAE,EAAE;;AAEvB,eAAe;EACX,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;AAEhB,UAAU;EACN,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,OAAO;EACd,KAAK,EAAE,IAAI;;AAIf,SAAS;EACL,KAAK,EAAE,OAAO;EACd,SAAS,EAAE,IAAI;;AAGnB,mBAAmB;EACf,UAAU,EAAE,iCAAmC;;AAEnD,MAAM;EACF,KAAK,EAAE,GAAG;EACV,KAAK,EAAE,IAAI;EACX,SAAE;IACE,KAAK,EA1EC,OAAO;;AA4ErB,SAAS;EACL,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,GAAG;EACX,KAAK,EAAE,KAAK;EACZ,YAAY,EAAE,GAAG;EACjB,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,iBAAiB;EAChC,WAAC;IACG,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,IAAI;;AAInB,qBAAO;EACH,UAAU,EAAE,MAAM;;AAE1B,mBAAmB;EACf,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,GAAG;EACV,WAAW,EAAE,EAAE;EACf,UAAU,EAAE,EAAE;EACd,YAAY,EAAE,CAAC;EACf,KAAK,EAAE,KAAK;EACZ,UAAU,EAAE,sDAAsD;EAElE,sBAAE;IACE,YAAY,EAAE,EAAE;;AAExB,yBAAyB;EACrB,gBAAgB,EAAE,OAAO",
4 "sources": ["general.sass"], 4 "sources": ["general.sass"],
5 "names": [], 5 "names": [],
6 "file": "general.css" 6 "file": "general.css"
analytics/static/analytics/general.sass
@@ -75,8 +75,8 @@ $title-color: #009688 @@ -75,8 +75,8 @@ $title-color: #009688
75 color: $title-color 75 color: $title-color
76 76
77 .selector 77 .selector
78 - width: 80%  
79 - height: 40px 78 + width: 90%
  79 + height: 20%
80 color: white 80 color: white
81 padding-left: 5px 81 padding-left: 5px
82 background-color: #009688 82 background-color: #009688
@@ -84,4 +84,24 @@ $title-color: #009688 @@ -84,4 +84,24 @@ $title-color: #009688
84 border-radius: 0px 20px 20px 0px 84 border-radius: 0px 20px 20px 0px
85 p 85 p
86 padding-top: 10px 86 padding-top: 10px
87 - font-size: 16px  
88 \ No newline at end of file 87 \ No newline at end of file
  88 + font-size: 16px
  89 +
  90 +
  91 +.middle-chart
  92 + article
  93 + text-align: center
  94 +
  95 +.most-accessed-list
  96 + background-color: #52b7bd
  97 + width: 80%
  98 + margin-left: 2%
  99 + margin-top: 2%
  100 + padding-left: 0
  101 + color: white
  102 + transition: width 2s, height 2s, background-color 2s, transform 2s
  103 +
  104 + li
  105 + padding-left: 1%
  106 +
  107 +.most-accessed-item:hover
  108 + background-color: #3aa7ad
89 \ No newline at end of file 109 \ No newline at end of file
analytics/static/analytics/js/behavior.js
@@ -13,8 +13,23 @@ var selectors_options = { @@ -13,8 +13,23 @@ var selectors_options = {
13 }, 13 },
14 loadData: function(e){ 14 loadData: function(e){
15 if (e){ 15 if (e){
16 - if (e.attributes['data-url'].value == "subjects"){  
17 - var url = "/analytics/most_accessed_subjects"; 16 + opened = $(e).attr('opened');
  17 + if (typeof opened !== typeof undefined && opened !== false){
  18 + selectors_options.deleteChildren(e);
  19 + }else {
  20 + switch(e.attributes['data-url'].value){
  21 + case "subjects":
  22 + var url = "/analytics/most_accessed_subjects";
  23 + break;
  24 + case "categories":
  25 + var url = "/analytics/most_accessed_categories";
  26 + break;
  27 + case "resources":
  28 + var url = "/analytics/most_accessed_resources";
  29 + break;
  30 +
  31 + }
  32 +
18 } 33 }
19 } 34 }
20 if(url){ 35 if(url){
@@ -32,16 +47,29 @@ var selectors_options = { @@ -32,16 +47,29 @@ var selectors_options = {
32 }, 47 },
33 modifyElement: function(e, data){ 48 modifyElement: function(e, data){
34 var string_build = ""; 49 var string_build = "";
35 - string_build += "<ul>"; 50 + string_build += '<ul class="most-accessed-list" style="display:none;">';
36 51
37 data.forEach(function(datum){ 52 data.forEach(function(datum){
38 string_build += '<li class="most-accessed-item">' +datum.name+ ' ' + datum.count+ '</li>'; 53 string_build += '<li class="most-accessed-item">' +datum.name+ ' ' + datum.count+ '</li>';
39 }); 54 });
40 string_build += "</ul>"; 55 string_build += "</ul>";
41 56
42 - $(e).append(string_build);  
43 -  
44 - e.attributes.open = True; 57 + $(e).after(string_build);
  58 + var new_elem = $(e).next();
  59 + new_elem.slideDown();
  60 + $(e).attr("opened", true);
  61 +
  62 + },
  63 + deleteChildren: function(e){
  64 + console.log("delete children");
  65 + var most_accessed_list = $(e).next();
  66 + $(most_accessed_list).animate(
  67 + {height: 0,
  68 + opacity: 0.1
  69 + }, 1000, function(){
  70 + $(this).remove(); //remove list from UI
  71 + });
45 72
  73 + $(e).removeAttr("opened"); //remove attribute so it can call API again
46 }, 74 },
47 }; 75 };
analytics/static/analytics/js/charts.js
@@ -91,7 +91,7 @@ var charts = { @@ -91,7 +91,7 @@ var charts = {
91 91
92 build_bubble_user: function(url){ 92 build_bubble_user: function(url){
93 $.get(url, function(dataset){ 93 $.get(url, function(dataset){
94 - var width = 600; 94 + var width = 300;
95 var height = 300; 95 var height = 300;
96 96
97 97
@@ -121,7 +121,7 @@ var charts = { @@ -121,7 +121,7 @@ var charts = {
121 121
122 var color = d3.scaleOrdinal(d3.schemeCategory20); 122 var color = d3.scaleOrdinal(d3.schemeCategory20);
123 //adding new div to carousel-inner div 123 //adding new div to carousel-inner div
124 - var new_div = d3.select(".carousel-inner").append("div").attr("class","item"); 124 + var new_div = d3.select(".middle-chart").append("div").attr("class","item");
125 var radiusScale = d3.scaleSqrt().domain([min(), max()]).range([10,50]); 125 var radiusScale = d3.scaleSqrt().domain([min(), max()]).range([10,50]);
126 var svg = new_div.append("svg").attr("width", width).attr("height", height) 126 var svg = new_div.append("svg").attr("width", width).attr("height", height)
127 .style("margin","auto") 127 .style("margin","auto")
@@ -131,17 +131,7 @@ var charts = { @@ -131,17 +131,7 @@ var charts = {
131 .attr("width", width) 131 .attr("width", width)
132 .attr("height", height); 132 .attr("height", height);
133 133
134 - //adding svg title  
135 -  
136 - svg.append("text")  
137 - .attr("text-anchor", "middle")  
138 - .attr("x", width/2 )  
139 - .attr("y", 30)  
140 - .style("font-size", "30px")  
141 - .text("Usuários mais ativos no Amadeus")  
142 - .attr("fill", "#003333")  
143 - .style("font-weight", "bold")  
144 - .style("font-style", "italic"); 134 +
145 135
146 var simulation = d3.forceSimulation() 136 var simulation = d3.forceSimulation()
147 .force("x", d3.forceX(width/2).strength(0.05)) 137 .force("x", d3.forceX(width/2).strength(0.05))
@@ -158,6 +148,29 @@ var charts = { @@ -158,6 +148,29 @@ var charts = {
158 .append("g") 148 .append("g")
159 .attr("class",".user-dot"); 149 .attr("class",".user-dot");
160 150
  151 +
  152 + var defs = groups.append('svg:defs');
  153 +
  154 + var gradient = defs.append("linearGradient")
  155 + .attr("id", "svgGradient")
  156 + .attr("x1", "0%")
  157 + .attr("x2", "100%")
  158 + .attr("y1", "0%")
  159 + .attr("y2", "100%");
  160 +
  161 + gradient.append("stop")
  162 + .attr('class', 'start')
  163 + .attr("offset", "0%")
  164 + .attr("stop-color", "#007991")
  165 + .attr("stop-opacity", 1);
  166 +
  167 + gradient.append("stop")
  168 + .attr('class', 'end')
  169 + .attr("offset", "100%")
  170 + .attr("stop-color", "#78ffd6")
  171 + .attr("stop-opacity", 1);
  172 +
  173 +
161 //Create circles to be drawn 174 //Create circles to be drawn
162 var circles = groups 175 var circles = groups
163 .append('circle') 176 .append('circle')
@@ -167,7 +180,9 @@ var charts = { @@ -167,7 +180,9 @@ var charts = {
167 180
168 .attr("fill", function(d){ 181 .attr("fill", function(d){
169 return 'url('+'#'+'user_'+d['user_id']+')'; 182 return 'url('+'#'+'user_'+d['user_id']+')';
170 - }); 183 + })
  184 + .attr("stroke", "url(#svgGradient)") //using id setted by the svg
  185 + .attr("stroke-width", 3);
171 186
172 187
173 188
@@ -175,7 +190,7 @@ var charts = { @@ -175,7 +190,7 @@ var charts = {
175 groups.append("text") 190 groups.append("text")
176 .text(function(d){ 191 .text(function(d){
177 return d['user'] +'('+ d['count'] + ')'; 192 return d['user'] +'('+ d['count'] + ')';
178 - }).attr("fill", "#FFFFFF") 193 + }).attr("fill", "#000000")
179 .attr("id", function(d){ 194 .attr("id", function(d){
180 return "user_tooltip_"+d['user_id']; 195 return "user_tooltip_"+d['user_id'];
181 }).style("display", "none"); 196 }).style("display", "none");
@@ -190,7 +205,6 @@ var charts = { @@ -190,7 +205,6 @@ var charts = {
190 $("#"+"user_tooltip_"+d['user_id']).hide(); 205 $("#"+"user_tooltip_"+d['user_id']).hide();
191 }); 206 });
192 207
193 - var defs = groups.append('svg:defs');  
194 208
195 //Attching images to bubbles 209 //Attching images to bubbles
196 defs.append("svg:pattern") 210 defs.append("svg:pattern")
@@ -217,11 +231,13 @@ var charts = { @@ -217,11 +231,13 @@ var charts = {
217 .attr("y", 0); 231 .attr("y", 0);
218 232
219 233
  234 +
220 235
221 //simulation 236 //simulation
222 simulation.nodes(dataset) 237 simulation.nodes(dataset)
223 .on('tick', ticked); //so all data points are attached to it 238 .on('tick', ticked); //so all data points are attached to it
224 239
  240 + console.log("finished simulation");
225 function ticked(){ 241 function ticked(){
226 groups.attr("transform", function(d){ 242 groups.attr("transform", function(d){
227 return "translate(" + d.x + "," + d.y + ")"; 243 return "translate(" + d.x + "," + d.y + ")";
@@ -234,10 +250,10 @@ var charts = { @@ -234,10 +250,10 @@ var charts = {
234 250
235 most_accessed_subjects: function(url){ 251 most_accessed_subjects: function(url){
236 $.get(url, function(dataset){ 252 $.get(url, function(dataset){
237 - var width = 800; 253 + var width = 200;
238 var height = 300; 254 var height = 300;
239 255
240 - var new_div = d3.select(".carousel-inner").append("div").attr("class","item"); 256 + var new_div = d3.select(".carousel-inner").append("div").attr("test","ok");
241 257
242 var svg = new_div.append("svg").attr("width", "100%").attr("height", height) 258 var svg = new_div.append("svg").attr("width", "100%").attr("height", height)
243 .style("margin","auto") 259 .style("margin","auto")
@@ -417,7 +433,10 @@ var charts = { @@ -417,7 +433,10 @@ var charts = {
417 } 433 }
418 } 434 }
419 435
420 -charts.most_used_tags('/analytics/most_used_tags');  
421 -//charts.build_resource('/topics/count_resources/');  
422 -//charts.build_bubble_user('/users/get_users_log/');  
423 -//charts.most_accessed_subjects('/subjects/most_accessed_subjects');  
424 \ No newline at end of file 436 \ No newline at end of file
  437 +
  438 +$(document).ready(function(){
  439 + charts.most_used_tags('/analytics/most_used_tags');
  440 + //charts.build_resource('/topics/count_resources/');
  441 + charts.build_bubble_user('/analytics/most_active_users/');
  442 + //charts.most_accessed_subjects('/subjects/most_accessed_subjects');
  443 +});
analytics/templates/analytics/general.html
@@ -72,7 +72,7 @@ @@ -72,7 +72,7 @@
72 72
73 <div id="left-data-selector"> 73 <div id="left-data-selector">
74 74
75 - <div class="selector"> 75 + <div class="selector" data-url="categories">
76 <p> {% trans "most accessed categories" %} </p> 76 <p> {% trans "most accessed categories" %} </p>
77 </div> 77 </div>
78 78
@@ -80,7 +80,7 @@ @@ -80,7 +80,7 @@
80 <p> {% trans "most accessed subjects" %} </p> 80 <p> {% trans "most accessed subjects" %} </p>
81 </div> 81 </div>
82 82
83 - <div class="selector"> 83 + <div class="selector" data-url="resources">
84 <p> {% trans "most accessed resource" %} </p> 84 <p> {% trans "most accessed resource" %} </p>
85 </div> 85 </div>
86 86
@@ -91,6 +91,7 @@ @@ -91,6 +91,7 @@
91 <article> 91 <article>
92 <h4>{% trans "most active users" %}</h4> 92 <h4>{% trans "most active users" %}</h4>
93 </article> 93 </article>
  94 +
94 </div> 95 </div>
95 <div class="chart right-chart"> 96 <div class="chart right-chart">
96 97
analytics/tests/test_general_dashboard.py
@@ -88,7 +88,7 @@ class APIDashBoardTest(TestCase): @@ -88,7 +88,7 @@ class APIDashBoardTest(TestCase):
88 88
89 89
90 def test_most_accessed_categories(self): 90 def test_most_accessed_categories(self):
91 - self.fail("finish the test") 91 + self.fail("finish test on categories")
92 92
93 def test_most_active_users(self): 93 def test_most_active_users(self):
94 self.fail("finish the test") 94 self.fail("finish the test")
analytics/urls.py
@@ -8,4 +8,7 @@ urlpatterns = [ @@ -8,4 +8,7 @@ urlpatterns = [
8 #"api" callls 8 #"api" callls
9 url(r'^most_used_tags/$', views.most_used_tags, name="most_used_tags"), 9 url(r'^most_used_tags/$', views.most_used_tags, name="most_used_tags"),
10 url(r'^most_accessed_subjects/$', views.most_accessed_subjects, name="most_accessed_subjects"), 10 url(r'^most_accessed_subjects/$', views.most_accessed_subjects, name="most_accessed_subjects"),
  11 + url(r'^most_accessed_categories/$', views.most_accessed_categories, name = "most_accessed_categories"),
  12 + url(r'^most_accessed_resources/$', views.most_accessed_resource_kind, name= "most_accessed_resources"),
  13 + url(r'^most_active_users/$', views.most_active_users, name= "most_active_users"),
11 ] 14 ]
12 \ No newline at end of file 15 \ No newline at end of file
analytics/views.py
@@ -79,15 +79,38 @@ def most_accessed_subjects(request): @@ -79,15 +79,38 @@ def most_accessed_subjects(request):
79 def most_accessed_categories(request): 79 def most_accessed_categories(request):
80 data = {} 80 data = {}
81 81
82 - data = Log.objects.filter('category') 82 + data = Log.objects.filter(resource = 'category')
83 categories = {} 83 categories = {}
84 for datum in data: 84 for datum in data:
85 if datum.context: 85 if datum.context:
86 - pass  
87 - return None 86 + category_id = datum.context['category_id']
  87 + if category_id in categories.keys():
  88 + categories[category_id]['count'] = categories[category_id]['count'] + 1
  89 + else:
  90 + categories[category_id] = {'name': datum.context['category_name'], 'count': 1 }
  91 +
  92 + categories = sorted(categories.values(), key = lambda x: x['count'], reverse = True)
  93 + categories = categories[:5]
  94 + return JsonResponse(categories, safe= False)
88 95
89 def most_accessed_resource_kind(request): 96 def most_accessed_resource_kind(request):
90 - return None 97 + resources_names = [cls.__name__ for cls in Resource.__subclasses__()]
  98 + print(resources_names)
  99 + resources = {}
  100 +
  101 + mapping = {}
  102 + mapping['pdffile'] = str(_('PDF File'))
  103 + mapping['goals'] = str(_('Topic Goals'))
  104 + mapping['link'] = str(_('Link to Website'))
  105 + mapping['filelink'] = str(_('File Link'))
  106 + mapping['webconference'] = str(_('Web Conference'))
  107 + mapping['ytvideo'] = str(_('YouTube Video'))
  108 + mapping['webpage'] = str(_('WebPage'))
  109 +
  110 +
  111 +
  112 +
  113 + return JsonResponse(resources, safe = False)
91 114
92 115
93 def most_active_users(request): 116 def most_active_users(request):