From ade10194c01dcf4a71fc92f055d5dc53ac555e0e Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Thu, 28 Dec 2017 14:53:19 +0100
Subject: [PATCH] improve / simplify ranking. Fix forgotten renaming

---
 css/index.css          |  8 -------
 index.html             |  4 ++--
 js/index.js            | 51 ++++++++++++++++++------------------------
 scripts/rw_players.php |  6 ++---
 4 files changed, 27 insertions(+), 42 deletions(-)

diff --git a/css/index.css b/css/index.css
index 54022f6..d92ca1c 100644
--- a/css/index.css
+++ b/css/index.css
@@ -148,14 +148,6 @@ table.ranking tr:not(.title):hover, table.ranking tr:not(.title):nth-child(even)
 	background-color: lightyellow;
 }
 
-table.ranking th.scoring {
-	cursor: pointer;
-}
-
-.active {
-	background-color: yellow;
-}
-
 /* pairings div */
 
 button.block {
diff --git a/index.html b/index.html
index 1392bfe..1360c13 100644
--- a/index.html
+++ b/index.html
@@ -19,8 +19,8 @@
 			</header>
 			<main>
 				<my-players v-show="display=='players'" :players="players"></my-players>
-				<my-ranking v-show="display=='ranking'" :players="players"></my-ranking>
-				<my-pairings v-show="display=='pairings'" :players="players"></my-pairings>
+				<my-ranking v-show="display=='ranking'" :players="players" :sort-by-score="sortByScore" :rank-people="rankPeople"></my-ranking>
+				<my-pairings v-show="display=='pairings'" :players="players" :sort-by-score="sortByScore"></my-pairings>
 			</main>
 		</div>
 	</body>
diff --git a/js/index.js b/js/index.js
index 77287d8..649e44c 100644
--- a/js/index.js
+++ b/js/index.js
@@ -46,22 +46,17 @@ new Vue({
 			},
 		},
 		'my-ranking': {
-			props: ['players'],
-			data: function() {
-				return {
-					sortMethod: "pdt",
-				};
-			},
+			props: ['players','sortByScore','rankPeople'],
 			template: `
 				<div id="ranking">
 					<table class="ranking">
 						<tr class="title">
 							<th>Rang</th>
 							<th>Joueur</th>
-							<th @click="sortMethod='pdt'" class="scoring" :class="{active: sortMethod=='pdt'}">Points</th>
-							<th @click="sortMethod='session'" class="scoring" :class="{active: sortMethod=='session'}">Mini-pts</th>
+							<th>Points</th>
+							<th>Mini-pts</th>
 						</tr>
-						<tr v-for="p in sortedPlayers" v-if="p.nom!=''">
+						<tr v-for="p in sortedPlayers">
 							<td>{{ p.rank }}</td>
 							<td>{{ p.prenom }} {{ p.nom }}</td>
 							<td>{{ p.pdt }}</td>
@@ -70,19 +65,14 @@ new Vue({
 					</table>
 				</div>
 			`,
-			computed: { //TODO: first sort on score, then on Pdt (and reciprocally) --> function add fraction relative Pdt / score (compute min max first, take care of 0 case)
+			computed: {
 				sortedPlayers: function() {
-					let sortFunc = this.sortMethod == "pdt"
-						? this.sortByPdt
-						: this.sortBySession;
-					let res = this.players
-						.map( p => { return Object.assign({}, p); }) //to not alter original array
-						.sort(sortFunc);
+					let res = this.rankPeople();
 					// Add rank information (taking care of ex-aequos)
 					let rank = 1;
 					for (let i=0; i<res.length; i++)
 					{
-						if (i==0 || sortFunc(res[i],res[i-1]) == 0)
+						if (i==0 || this.sortByScore(res[i],res[i-1]) == 0)
 							res[i].rank = rank;
 						else //strictly lower scoring
 							res[i].rank = ++rank;
@@ -90,17 +80,9 @@ new Vue({
 					return res;
 				},
 			},
-			methods: {
-				sortByPdt: function(a,b) {
-					return b.pdt - a.pdt;
-				},
-				sortBySession: function(a,b) {
-					return b.session - a.session;
-				},
-			},
 		},
 		'my-pairings': {
-			props: ['players'],
+			props: ['players','sortByScore'],
 			data: function() {
 				return {
 					unpaired: [],
@@ -152,7 +134,7 @@ new Vue({
 					// Simple case first: 4 by 4
 					let tables = [];
 					let currentTable = [];
-					let ordering = _.shuffle(_.range(this.players.length)); //TODO: take scores into account?
+					let ordering = _.shuffle(_.range(this.players.length));
 					for (let i=0; i<ordering.length; i++)
 					{
 						if ( ! this.players[ordering[i]].available )
@@ -228,9 +210,9 @@ new Vue({
 					xhr.open("POST", "scripts/rw_players.php");
 					xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
 					let orderedPlayers = this.players
-						.slice(1) //discard "Toto"
+						.slice(1) //discard Toto
 						.map( p => { return Object.assign({}, p); }) //deep (enough) copy
-						.sort( (a,b) => { return b.pdt - a.pdt; }); //TODO: re-use sorting function in ranking component
+						.sort(this.sortByScore);
 					xhr.send("players="+encodeURIComponent(JSON.stringify(orderedPlayers)));
 				},
 			},
@@ -261,4 +243,15 @@ new Vue({
 		xhr.open("GET", "scripts/rw_players.php", true);
 		xhr.send(null);
 	},
+	methods: {
+		rankPeople: function() {
+			return this.players
+				.slice(1) //discard Toto
+				.map( p => { return Object.assign({}, p); }) //to not alter original array
+				.sort(this.sortByScore);
+		},
+		sortByScore: function(a,b) {
+			return b.pdt - a.pdt + (Math.atan(b.session - a.session) / (Math.PI/2)) / 2;
+		},
+	},
 });
diff --git a/scripts/rw_players.php b/scripts/rw_players.php
index 3f641c2..b5bdabc 100644
--- a/scripts/rw_players.php
+++ b/scripts/rw_players.php
@@ -12,8 +12,8 @@ if (!isset($_POST["players"]))
 		$players[$row] = array(
 			"prenom" => $data[0],
 			"nom" => $data[1],
-			"score" => count($data)>=3 ? $data[2] : 0,
-			"pdt" => count($data)>=4 ? $data[3] : 0,
+			"pdt" => count($data)>=3 ? $data[2] : 0,
+			"session" => count($data)>=4 ? $data[3] : 0,
 			"available" => count($data)>=5 ? $data[4] : 1,
 		);
 		$row++;
@@ -25,7 +25,7 @@ else
 {
 	// Write header + all players
 	$handle = fopen("../joueurs.csv", "w");
-	fputcsv($handle, ["prenom","nom","score","pdt","present"]);
+	fputcsv($handle, ["prenom","nom","pdt","session","present"]);
 	$players = json_decode($_POST["players"]);
 	foreach ($players as $p)
 		fputcsv($handle, (array)$p);
-- 
2.44.0