308 lines
9.5 KiB
JavaScript
308 lines
9.5 KiB
JavaScript
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(/<strong>(\d+)<sup>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)";
|
|
});
|
|
}
|
|
});
|
|
})
|