<!doctype html> <html> <head> <title>ClessyStats</title> <script> // Pegasus 0.3.2 (https://github.com/typicode/pegasus) function p(a,b){return b=new XMLHttpRequest,b.open("GET",a),a=[],b.onreadystatechange=b.then=function(c,d,e,f){if(c&&c.call&&(a=[,c,d]),4==b.readyState&&(e=a[0|b.status/200])){try{f=JSON.parse(b.responseText)}catch(g){f=null}e(f,b)}},b.send(),b}; // uAMD function req(q,c){var D={};C=D.length=q.length;q.map(function(Q,i){Q(function(d){D[i]=d;C--;if(!C)c.apply(0,D);})});} function Qapi(u){return p(u).then} function Qready(cb){window.onload=cb} </script> <script src="Chart.bundle.min.js"></script> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0, user-scalable=yes, target-densitydpi=device-dpi, minimal-ui" /> <link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Raleway:300' rel='stylesheet' type='text/css'> <style> body { font-family: 'Source Sans Pro', sans-serif; background-color: #f3f3f3; margin: 0; padding: 0.5rem; } section { display: flex; flex-wrap: wrap; } article { flex: 320px; background-color: #fff; margin: 0.1rem; padding: 0.5rem; } article header { font-family: 'Raleway', sans-serif; font-size: 1.2rem; font-weight: 300; margin-bottom: 0.5rem; text-align: center; } table { margin: 0 auto; max-width: 100%; } #totalmsg { text-align: center; padding-bottom: 1rem; } #usermsg i { font-size: 0.8rem; font-style: normal; } #usermsg tr:nth-child(even) { background-color: #fafafa; } #usermsg td { text-align: center; padding: 0.3rem 0; word-break: break-word; } #usermsg th { padding: 0.3rem 0.5rem; } #usermsg td:first-child, #usermsg td:nth-child(4) { text-align: left; padding: 0.3rem 0.6rem; } canvas { width: 100%; } </style> </head> <body> <main> <section> <article id="typecont"> <header>Messaggi divisi per tipo</header> <center> <canvas id="chart-type" height="300"></canvas> <div id="type-legend"></div> </center> </article> <article id="wdaycont"> <header>Attività per giorno della settimana</header> <center> <canvas id="chart-wday" height="300"></canvas> </center> </article> <article id="hourcont"> <header>Attività per ora del giorno</header> <center> <canvas id="chart-hour" height="300"></canvas> </center> </article> </section> <section> <article id="daycont"> <header>Attività per giorno</header> <center> <canvas id="chart-day" height="350"></canvas> </center> </article> </section> <section> <article> <header>Ma quanto scrivete?</header> <div id="totalmsg"> In totale sono stati scritti circa <b><span id="totalcount"></span> messaggi</b>. </div> <table id="usermsg"> <tr> <th width="40%">Nickname</th> <th width="20%">Messaggi totali</th> <th width="20%">% dei messaggi</th> <th width="40%">Mamo</th> </tr> </table> </article> </section> </main> <script> // Utility functions function toArray(o){var a=[];for(k in o){a.push([k,o[k]]);}return a} function sortMessages(a,b){return b[1]-a[1]} function mkRow(c){var a="createElement",r=document[a]("tr");c.map(function(C){var A=document[a]("td");A.innerHTML=C;r.appendChild(A)});return r;} months=["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"]; function dayfmt(d){var p=d.split("-");return[p[2],months[parseInt(p[1])-1],p[0]].join(" ")} function reorder(d){var k=[],K=[],t={},v=[],i=0,p;for(x in d){p=x.split("-");p=parseInt(p[0])*1e4+parseInt(p[1])*1e2+parseInt(p[2]);t[p]=x;k.push(p);}k.sort();for (;i<k.length;i++){K.push(t[k[i]]);v.push(d[t[k[i]]]);}return[k,K,v]} // Load from backend req([ Qapi("https://stats.crunchy.rocks/stats"), Qapi("https://stats.crunchy.rocks/users"), Qapi("https://stats.crunchy.rocks/words"), Qready ], function(stats, users, words) { var font = "'Source Sans Pro', sans-serif"; Chart.defaults.global.defaultFontFamily = font; Chart.defaults.global.legend.labels.fontFamily = font; Chart.defaults.global.title.fontFamily = font; Chart.defaults.global.responsive = false; Chart.defaults.global.maintainAspectRatio = false; Chart.defaults.scale.ticks.fontFamily = font; /* Get chart canvas elements */ var typecvs = document.getElementById("chart-type"); var typectx = typecvs.getContext("2d"); var wdaycvs = document.getElementById("chart-wday"); var wdayctx = wdaycvs.getContext("2d"); var hourcvs = document.getElementById("chart-hour"); var hourctx = hourcvs.getContext("2d"); var daycvs = document.getElementById("chart-day"); var dayctx = daycvs.getContext("2d"); /* Create charts */ var typechart = new Chart(typectx, { type:'pie', data: { labels: ["Testuali", "Clip audio", "Immagini/Foto", "Sticker", "Video", "Messaggio vocale", "Contatto", "Locazione", "File generico"], datasets: [{ data: stats.ByType, backgroundColor: ["#F7464A","#46BFBD","#FDB45C","#949FB1","#4D5360","#EE46F7","#46F7D7","#BFF746"], hoverBackgroundColor: ["#FF5A5E","#5AD3D1","#FFC870","#A8B3C5","#616774","#F75AFF","#5AFFE1","#BEF746"] }] } }); //document.getElementById("type-legend").innerHTML = typechart.generateLegend(); var wdaychart = new Chart(wdayctx, { type:'bar', data: { labels: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"], datasets: [{ label: "Messaggi", fillColor: "rgba(151,187,205,0.5)", strokeColor: "rgba(151,187,205,0.8)", highlightFill: "rgba(151,187,205,0.75)", highlightStroke: "rgba(151,187,205,1)", data: stats.ByWeekday }] }, options: { legend: { display: false } } }); var hourchart = new Chart(hourctx, { type: 'bar', data: { labels: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"], datasets: [{ label: "Messaggi", fillColor: "rgba(151,187,205,0.5)", strokeColor: "rgba(151,187,205,0.8)", highlightFill: "rgba(151,187,205,0.75)", highlightStroke: "rgba(151,187,205,1)", data: stats.ByHour }] }, options: { legend: { display: false } } }); // Remove bogus data delete stats.ByDay["1970-1-1"] // Reorder rest byday = reorder(stats.ByDay); var daychart = new Chart(dayctx, { type: 'line', data: { labels: byday[1].map(dayfmt), datasets: [{ label: "Messaggi", fill: true, backgroundColor: "rgba(220,220,220,0.2)", borderColor: "rgba(220,220,220,1)", borderCapStyle: 'cloud', borderDash: [], borderDashOffset: 0.0, borderJoinStyle: 'miter', pointBorderColor: "rgba(220,220,220,1)", pointBackgroundColor: "#fff", pointBackgroundColor: "#fff", pointBorderWidth: 1, pointHoverRadius: 5, pointHoverBackgroundColor: "rgba(220,220,220,1)", pointHoverBorderColor: "rgba(220,220,220,1)", pointHoverBorderWidth: 2, tension: 0.1, fillColor: "rgba(151,187,205,0.5)", strokeColor: "rgba(151,187,205,0.8)", highlightFill: "rgba(151,187,205,0.75)", highlightStroke: "rgba(151,187,205,1)", data: byday[2] }] }, options: { legend: { display: false } } }); /* Total stats */ document.getElementById("totalcount").innerHTML = stats.TotalCount; /* User stats */ // Count words var userFreq = {}; for (w in words) { for (user in words[w]) { if (!userFreq[user]) { userFreq[user] = []; } userFreq[user].push([w, words[w][user]]); } } for (user in userFreq) { userFreq[user].sort(sortMessages); } function formatwords(n){return userFreq[n]?userFreq[n].slice(0,3).map(function(i){return i[0]}).join(" "):""} function percent(a){return Math.round(a/stats.TotalCount*1e4)/1e2} function nick(a){return users[a]?users[a]+" <i>("+a+")</i>":a} function enrich(a){return [nick(a[0]), a[1], percent(a[1]), formatwords(a[0])]} function append(a){usertable.appendChild(a)} var userlist = toArray(stats.ByUserCount).sort(sortMessages); var usertable = document.getElementById("usermsg"); userlist.map(enrich).map(mkRow).map(append); /* Hand-made responsiveness */ margin = 100; window.onresize = function() { typecvs.width = typecvs.clientWidth; typecvs.height = 300; typechart.resize(); wdaycvs.width = wdaycvs.clientWidth; wdaycvs.height = 300; wdaychart.resize(); hourcvs.width = hourcvs.clientWidth; hourcvs.height = 300; hourchart.resize(); daycvs.width = daycvs.clientWidth; daycvs.height = 350; daychart.resize(); } window.onresize(); }); </script> </body> </html>