angular.module("FICApp", ["ngSanitize", "ngAnimate"]) .controller("EventsController", function($scope, $rootScope, $http, $interval) { $scope.events = []; var refreshEvents = function() { // Update times var time = angular.fromJson(sessionStorage.time); var now = Date.now(); if (time) now += time.cu - time.he; now = new Date(now); $scope.events.forEach(function(ev) { ev.since = now - ev.time; }); $http.get("./events.json").then(function(response) { // Don't make anything if the page hasn't changed if ($scope.lasteventsetag != undefined && $scope.lasteventsetag == response.headers()["last-modified"]) return; $scope.lasteventsetag = response.headers()["last-modified"]; var lastExercice = undefined; $scope.events = response.data; $scope.events.forEach(function(event) { if (!lastExercice && $scope.themes) { var res = event.txt.match(/(\d+)e<\/sup><\/strong> défi ([^&]+)/); if (res) { for (var tid in $scope.themes) { if ($scope.themes[tid].name == res[2]) { for (var eid in $scope.themes[tid].exercices) { lastExercice = $scope.themes[tid].exercices[parseInt(res[1])-1].id; break; } } } } } event.time = Date.parse(event.time); event.since = now - event.time; event.kind = ["border-" + event.kind, "alert-" + event.kind]; }); $rootScope.lastExercice = lastExercice; }); } $interval(refreshEvents, 2100); }) .controller("TimerController", function($scope, $rootScope, $interval, $timeout) { $scope.duration = 0; $scope.init = function(end) { $scope.initT(Date.parse(end)); } $scope.initStart = function() { $scope.$watch("settings", function(settings){ if (settings) $scope.initT(settings.start); }) } $scope.initT = function(end) { var time = angular.fromJson(sessionStorage.time); if (time) { var srv_cur = new Date(Date.now() + (time.cu - time.he)); $scope.duration = Math.floor((end - srv_cur)/1000); } else $timeout(function() { $scope.initT(end); }, 1000); } var stop = $interval(function() { $scope.duration -= 1; if ($scope.duration < -10) $interval.cancel(stop); }, 1000); }) .controller("DataController", function($scope, $http, $rootScope, $interval) { var pathname = window.location.pathname; if (pathname == "/") pathname = "/public0.html"; pathname = pathname.replace(".html", ".json"); var refreshScene = function() { $http.get(pathname).then(function(response) { if ($scope.lastpublicetag != undefined && $scope.lastpublicetag == response.headers()["last-modified"]) return; $scope.lastpublicetag = response.headers()["last-modified"]; $scope.display = response.data; }); } refreshScene(); var refreshSceneInterval = $interval(refreshScene, 900); var refreshSettings = function() { $http.get("./settings.json").then(function(response) { $rootScope.recvTime(response); response.data.start = new Date(response.data.start); response.data.end = new Date(response.data.end); response.data.generation = new Date(response.data.generation); response.data.awards = new Date(response.data.awards?response.data.awards:"2023-04-06T16:00:00Z"); $rootScope.settings = response.data; }); } refreshSettings(); var refreshSettingsInterval = $interval(refreshSettings, 4200); var refreshChallengeInfo = function() { $http.get("./challenge.json").then(function(response) { $rootScope.challenge = response.data; }); } refreshChallengeInfo(); var refreshChallengeInfoInterval = $interval(refreshChallengeInfo, 900000); $rootScope.refresh = function() { $http.get("./my.json").then(function(response) { if ($scope.lastmyetag != undefined && $scope.lastmyetag == response.headers()["last-modified"]) return; $scope.lastmyetag = response.headers()["last-modified"]; $scope.my = response.data; }); $http.get("./settings.json").then(function(response) { $rootScope.recvTime(response); response.data.start = new Date(response.data.start); response.data.end = new Date(response.data.end); response.data.generation = new Date(response.data.generation); response.data.awards = new Date(response.data.awards?response.data.awards:"2023-04-06T16:00:00Z"); $rootScope.settings = response.data; }); $http.get("./themes.json").then(function(response) { if ($scope.lastthemeetag != undefined && $scope.lastthemeetag == response.headers()["last-modified"]) return; $scope.lastthemeetag = response.headers()["last-modified"]; var themes = response.data; var exercices = {}; $scope.themes = themes; $scope.max_gain = 0; angular.forEach(themes, function(theme, key) { if (theme.exercices) this[key].exercice_count = Object.keys(theme.exercices).length; else this[key].exercice_count = 0; this[key].gain = 0; angular.forEach(theme.exercices, function(ex, k) { exercices[ex.id] = ex; this.gain += ex.gain; }, theme); $scope.max_gain += theme.gain; }, themes); $scope.exercices = exercices; }); $http.get("./teams.json").then(function(response) { if ($scope.lastteametag != undefined && $scope.lastteametag == response.headers()["last-modified"]) return; $scope.lastteametag = response.headers()["last-modified"]; var teams = response.data; $scope.teams_count = Object.keys(teams).length $scope.teams = teams; $scope.rank = []; angular.forEach($scope.teams, function(team, tid) { team.id = tid; if (team.rank) { this.push(team); } }, $scope.rank); $scope.rank.sort(function(a,b) { return a.rank > b.rank ? 1 : -1 }) $scope.pagesrank = Array(Math.ceil($scope.rank.length / 7)).fill(0).map(function(v, i){ return i; }); }); } $rootScope.refresh(); $interval($rootScope.refresh, 4200); }) .controller("TeamController", function($scope, $http, $interval) { $scope.mystats = null; $http.get("./api/teams/" + $scope.team.id + "/stats.json").then(function(response) { $scope.mystats = response.data; }); }) .controller("RankGraphController", function($scope, $q) { var margin = {left: 50, right: 20, top: 20, bottom: 50 }; var width = $("#rank_graph").width() - margin.left - margin.right; var height = $scope.s.params.height - margin.top - margin.bottom; var xNudge = 50; var yNudge = 20; var max = 0; var minDate = new Date(); var maxDate = new Date("2017-12-01"); if ($scope.settings && $scope.settings.end) maxDate = $scope.settings.end; var teams = {} var loopPromises = []; $scope.s.params.teams.forEach(function (teamid) { var deferred = $q.defer(); loopPromises.push(deferred.promise); d3.json("./api/teams/" + teamid + "/score-grid.json", function (rows) { if (rows == null) return; rows.sort(function (a,b) { return a.time > b.time ? 1 : -1 }) var nrows = {}; var sum = 0; rows.forEach(function (row) { if (!nrows[row.time]) nrows[row.time] = 0; var pts = row.points * row.coeff; sum += pts; nrows[row.time] = sum; if (sum > max) max = sum }) teams[teamid] = [] Object.keys(nrows).forEach(function (t) { var d = new Date(t) if (d < minDate) minDate = d; if (d > maxDate) maxDate = d; teams[teamid].push({time: d, points: nrows[t]}) }) deferred.resolve(); }); }) $q.all(loopPromises).then(function(){ var y = d3.scale.linear() .domain([0,max]) .range([height,0]); var x = d3.time.scale() .domain([minDate,maxDate]) .range([0,width]); var yAxis = d3.svg.axis() .orient("left") .scale(y); var xAxis = d3.svg.axis() .orient("bottom") .tickFormat(d3.time.format("%H:%M")) .scale(x); var line = d3.svg.line() .x(function(d){ return x(d.time); }) .y(function(d){ return y(d.points); }) .interpolate("cardinal"); var svg = d3.select("#rank_graph").append("svg").attr("id","svg").attr("height",$scope.s.params.height).attr("width","100%"); var chartGroup = svg.append("g").attr("class","chartGroup").attr("transform","translate("+xNudge+","+yNudge+")"); chartGroup.append("g") .attr("class","axis x") .attr("transform","translate(0,"+height+")") .call(xAxis); chartGroup.append("g") .attr("class","axis y") .call(yAxis); angular.forEach(teams, function(rows, tid) { rows.unshift({time: minDate, points: 0}) var team = $scope.teams[tid] chartGroup.append("path") .attr("style","fill: none; stroke: " + team.color + "; stroke-width: 2px;") .attr("d",function(d){ return line(rows); }) }) if ($scope.s.params.legend) { var legend = svg.append("g") .attr("style", "fill: white;") .attr("height", 100) .attr("width", 100) .attr('transform', 'translate(70,20)') legend.selectAll('rect') .data(Object.keys(teams)) .enter() .append("rect") .attr("x", 0) .attr("y", function(d, i){ return i * 23;}) .attr("width", 15) .attr("height", 15) .style("fill", function(d) { return $scope.teams[d].color; }) legend.selectAll('text') .data(Object.keys(teams)) .enter() .append("text") .attr("font-size", "23px") .attr("x", 20) .attr("y", function(d, i){ return i * 23 + 14;}) .text(function(d) { return $scope.teams[d].name + " (" + $scope.teams[d].rank + "e : " + Math.ceil($scope.teams[d].score) + " pts)"; }); } }); })