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 63 color: #009688; }
64 64  
65 65 .selector {
66   - width: 80%;
67   - height: 40px;
  66 + width: 90%;
  67 + height: 20%;
68 68 color: white;
69 69 padding-left: 5px;
70 70 background-color: #009688;
... ... @@ -74,4 +74,21 @@
74 74 padding-top: 10px;
75 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 94 /*# sourceMappingURL=general.css.map */
... ...
analytics/static/analytics/general.css.map
1 1 {
2 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 4 "sources": ["general.sass"],
5 5 "names": [],
6 6 "file": "general.css"
... ...
analytics/static/analytics/general.sass
... ... @@ -75,8 +75,8 @@ $title-color: #009688
75 75 color: $title-color
76 76  
77 77 .selector
78   - width: 80%
79   - height: 40px
  78 + width: 90%
  79 + height: 20%
80 80 color: white
81 81 padding-left: 5px
82 82 background-color: #009688
... ... @@ -84,4 +84,24 @@ $title-color: #009688
84 84 border-radius: 0px 20px 20px 0px
85 85 p
86 86 padding-top: 10px
87   - font-size: 16px
88 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 109 \ No newline at end of file
... ...
analytics/static/analytics/js/behavior.js
... ... @@ -13,8 +13,23 @@ var selectors_options = {
13 13 },
14 14 loadData: function(e){
15 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 35 if(url){
... ... @@ -32,16 +47,29 @@ var selectors_options = {
32 47 },
33 48 modifyElement: function(e, data){
34 49 var string_build = "";
35   - string_build += "<ul>";
  50 + string_build += '<ul class="most-accessed-list" style="display:none;">';
36 51  
37 52 data.forEach(function(datum){
38 53 string_build += '<li class="most-accessed-item">' +datum.name+ ' ' + datum.count+ '</li>';
39 54 });
40 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 91  
92 92 build_bubble_user: function(url){
93 93 $.get(url, function(dataset){
94   - var width = 600;
  94 + var width = 300;
95 95 var height = 300;
96 96  
97 97  
... ... @@ -121,7 +121,7 @@ var charts = {
121 121  
122 122 var color = d3.scaleOrdinal(d3.schemeCategory20);
123 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 125 var radiusScale = d3.scaleSqrt().domain([min(), max()]).range([10,50]);
126 126 var svg = new_div.append("svg").attr("width", width).attr("height", height)
127 127 .style("margin","auto")
... ... @@ -131,17 +131,7 @@ var charts = {
131 131 .attr("width", width)
132 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 136 var simulation = d3.forceSimulation()
147 137 .force("x", d3.forceX(width/2).strength(0.05))
... ... @@ -158,6 +148,29 @@ var charts = {
158 148 .append("g")
159 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 174 //Create circles to be drawn
162 175 var circles = groups
163 176 .append('circle')
... ... @@ -167,7 +180,9 @@ var charts = {
167 180  
168 181 .attr("fill", function(d){
169 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 190 groups.append("text")
176 191 .text(function(d){
177 192 return d['user'] +'('+ d['count'] + ')';
178   - }).attr("fill", "#FFFFFF")
  193 + }).attr("fill", "#000000")
179 194 .attr("id", function(d){
180 195 return "user_tooltip_"+d['user_id'];
181 196 }).style("display", "none");
... ... @@ -190,7 +205,6 @@ var charts = {
190 205 $("#"+"user_tooltip_"+d['user_id']).hide();
191 206 });
192 207  
193   - var defs = groups.append('svg:defs');
194 208  
195 209 //Attching images to bubbles
196 210 defs.append("svg:pattern")
... ... @@ -217,11 +231,13 @@ var charts = {
217 231 .attr("y", 0);
218 232  
219 233  
  234 +
220 235  
221 236 //simulation
222 237 simulation.nodes(dataset)
223 238 .on('tick', ticked); //so all data points are attached to it
224 239  
  240 + console.log("finished simulation");
225 241 function ticked(){
226 242 groups.attr("transform", function(d){
227 243 return "translate(" + d.x + "," + d.y + ")";
... ... @@ -234,10 +250,10 @@ var charts = {
234 250  
235 251 most_accessed_subjects: function(url){
236 252 $.get(url, function(dataset){
237   - var width = 800;
  253 + var width = 200;
238 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 258 var svg = new_div.append("svg").attr("width", "100%").attr("height", height)
243 259 .style("margin","auto")
... ... @@ -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 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 72  
73 73 <div id="left-data-selector">
74 74  
75   - <div class="selector">
  75 + <div class="selector" data-url="categories">
76 76 <p> {% trans "most accessed categories" %} </p>
77 77 </div>
78 78  
... ... @@ -80,7 +80,7 @@
80 80 <p> {% trans "most accessed subjects" %} </p>
81 81 </div>
82 82  
83   - <div class="selector">
  83 + <div class="selector" data-url="resources">
84 84 <p> {% trans "most accessed resource" %} </p>
85 85 </div>
86 86  
... ... @@ -91,6 +91,7 @@
91 91 <article>
92 92 <h4>{% trans "most active users" %}</h4>
93 93 </article>
  94 +
94 95 </div>
95 96 <div class="chart right-chart">
96 97  
... ...
analytics/tests/test_general_dashboard.py
... ... @@ -88,7 +88,7 @@ class APIDashBoardTest(TestCase):
88 88  
89 89  
90 90 def test_most_accessed_categories(self):
91   - self.fail("finish the test")
  91 + self.fail("finish test on categories")
92 92  
93 93 def test_most_active_users(self):
94 94 self.fail("finish the test")
... ...
analytics/urls.py
... ... @@ -8,4 +8,7 @@ urlpatterns = [
8 8 #"api" callls
9 9 url(r'^most_used_tags/$', views.most_used_tags, name="most_used_tags"),
10 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 15 \ No newline at end of file
... ...
analytics/views.py
... ... @@ -79,15 +79,38 @@ def most_accessed_subjects(request):
79 79 def most_accessed_categories(request):
80 80 data = {}
81 81  
82   - data = Log.objects.filter('category')
  82 + data = Log.objects.filter(resource = 'category')
83 83 categories = {}
84 84 for datum in data:
85 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 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 116 def most_active_users(request):
... ...