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