]> git.sesse.net Git - ultimatescore/blobdiff - carousel.js
Reindent carousel.
[ultimatescore] / carousel.js
index 931d2a5418376dba94a31e0ff1322458a6c36d78..4a71ce6834c39fa2e7bcfe7d9bc4d78e15f4f40d 100644 (file)
 
 addtd = function(tr, className, content) {
-  var td = document.createElement("td");
-  td.appendChild(document.createTextNode(content));
-  td.className = className;
-  tr.appendChild(td);
+       var td = document.createElement("td");
+       td.appendChild(document.createTextNode(content));
+       td.className = className;
+       tr.appendChild(td);
 };
 addth = function(tr, className, content) {
-  var th = document.createElement("th");
-  th.appendChild(document.createTextNode(content));
-  th.className = className;
-  tr.appendChild(th);
+       var th = document.createElement("th");
+       th.appendChild(document.createTextNode(content));
+       th.className = className;
+       tr.appendChild(th);
 };
 
 subrank_partitions = function(games, parts, start_rank, tiebreakers) {
-  var result = [];
-  for (var i = 0; i < parts.length; ++i) {
-    var part = rank(games, parts[i], start_rank, tiebreakers);
-    for (var j = 0; j < part.length; ++j) {
-      result.push(part[j]);
-    }
-    start_rank += part.length;
-  }
-  return result;
+       var result = [];
+       for (var i = 0; i < parts.length; ++i) {
+               var part = rank(games, parts[i], start_rank, tiebreakers);
+               for (var j = 0; j < part.length; ++j) {
+                       result.push(part[j]);
+               }
+               start_rank += part.length;
+       }
+       return result;
 };
 
 partition = function(teams, compare)
 {
-  teams.sort(compare);
+       teams.sort(compare);
 
-  var parts = [];
-  var curr_part = [teams[0]];
-  for (var i = 1; i < teams.length; ++i) {
-    if (compare(teams[i], curr_part[0]) != 0) {
-      parts.push(curr_part);
-      curr_part = [];
-    }
-    curr_part.push(teams[i]);
-  }
-  if (curr_part.length != 0) {
-    parts.push(curr_part);
-  }
-  return parts;
+       var parts = [];
+       var curr_part = [teams[0]];
+       for (var i = 1; i < teams.length; ++i) {
+               if (compare(teams[i], curr_part[0]) != 0) {
+                       parts.push(curr_part);
+                       curr_part = [];
+               }
+               curr_part.push(teams[i]);
+       }
+       if (curr_part.length != 0) {
+               parts.push(curr_part);
+       }
+       return parts;
 };
 
 explain_tiebreaker = function(parts, rule_name)
 {
-  var result = [];
-  for (var i = 0; i < parts.length; ++i) {
-    result.push(parts[i].map(function(x) { return x.shortname; }).join("/"));
-  }
-  return result.join(" > ") + " (" + rule_name + ")";
+       var result = [];
+       for (var i = 0; i < parts.length; ++i) {
+               result.push(parts[i].map(function(x) { return x.shortname; }).join("/"));
+       }
+       return result.join(" > ") + " (" + rule_name + ")";
 }
 
 make_teams_to_idx = function(teams)
 {
-  var teams_to_idx = [];
-  for (var i = 0; i < teams.length; i++) {
-    teams_to_idx[teams[i].name] = i;
-  }
-  return teams_to_idx;
+       var teams_to_idx = [];
+       for (var i = 0; i < teams.length; i++) {
+               teams_to_idx[teams[i].name] = i;
+       }
+       return teams_to_idx;
 }
 
 partition_by_beat = function(games, teams)
 {
-  // Head-to-head score by way of components. First construct the beat matrix.
-  var n = teams.length;
-  var beat = new Array(n);
-  var teams_to_idx = make_teams_to_idx(teams);
-  for (var i = 0; i < n; i++) {
-    beat[i] = new Array(n);
-    for (var j = 0; j < n; j++) {
-      beat[i][j] = 0;
-    }
-  }
-  for (i = 0; i < games.length; ++i) {
-    var idx1 = teams_to_idx[games[i].name1];
-    var idx2 = teams_to_idx[games[i].name2];
-    if (idx1 !== undefined && idx2 !== undefined) {
-      if (games[i].score1 > games[i].score2) {
-        beat[idx1][idx2] = 1;
-      }
-      if (games[i].score1 < games[i].score2) {
-        beat[idx2][idx1] = 1;
-      }
-    }
-  }
-  // Floyd-Warshall for transitive closure.
-  for (var k = 0; k < n; ++k) {
-    for (var i = 0; i < n; ++i) {
-      for (var j = 0; j < n; ++j) {
-        if (beat[i][k] && beat[k][j]) {
-          beat[i][j] = 1;
-        }
-      }
-    }
-  }
+       // Head-to-head score by way of components. First construct the beat matrix.
+       var n = teams.length;
+       var beat = new Array(n);
+       var teams_to_idx = make_teams_to_idx(teams);
+       for (var i = 0; i < n; i++) {
+               beat[i] = new Array(n);
+               for (var j = 0; j < n; j++) {
+                       beat[i][j] = 0;
+               }
+       }
+       for (i = 0; i < games.length; ++i) {
+               var idx1 = teams_to_idx[games[i].name1];
+               var idx2 = teams_to_idx[games[i].name2];
+               if (idx1 !== undefined && idx2 !== undefined) {
+                       if (games[i].score1 > games[i].score2) {
+                               beat[idx1][idx2] = 1;
+                       }
+                       if (games[i].score1 < games[i].score2) {
+                               beat[idx2][idx1] = 1;
+                       }
+               }
+       }
+       // Floyd-Warshall for transitive closure.
+       for (var k = 0; k < n; ++k) {
+               for (var i = 0; i < n; ++i) {
+                       for (var j = 0; j < n; ++j) {
+                               if (beat[i][k] && beat[k][j]) {
+                                       beat[i][j] = 1;
+                               }
+                       }
+               }
+       }
 
-  // See if we can find any team that is comparable to all others.
-  for (var pivot_idx = 0; pivot_idx < n; pivot_idx++) {
-    var incomparable = false;
-    for (var i = 0; i < n; ++i) {
-      if (i != pivot_idx && beat[pivot_idx][i] == 0 && beat[i][pivot_idx] == 0) {
-        incomparable = true;
-        break;
-      }
-    }
-    if (!incomparable) {
-      // Split the teams into three partitions:
-      var better_than_pivot = [], equal = [], worse_than_pivot = [];
-      for (var i = 0; i < n; ++i) {
-        var we_beat = (beat[pivot_idx][i] == 1);
-        var they_beat = (beat[i][pivot_idx] == 1);
-        if ((i == pivot_idx) || (we_beat && they_beat)) {
-          equal.push(teams[i]);
-        } else if (we_beat && !they_beat) {
-          worse_than_pivot.push(teams[i]);
-        } else if (they_beat && !we_beat) {
-          better_than_pivot.push(teams[i]);
-        } else {
-          console.log("this shouldn't happen");
-        }
-      } 
-      var result = [];
-      if (better_than_pivot.length > 0) {
-        result = partition_by_beat(games, better_than_pivot);
-      }
-      result.push(equal);  // Obviously can't be partitioned further.
-      if (worse_than_pivot.length > 0) {
-        result = result.concat(partition_by_beat(games, worse_than_pivot));
-      }
-      return result;
-    }
-  }
+       // See if we can find any team that is comparable to all others.
+       for (var pivot_idx = 0; pivot_idx < n; pivot_idx++) {
+               var incomparable = false;
+               for (var i = 0; i < n; ++i) {
+                       if (i != pivot_idx && beat[pivot_idx][i] == 0 && beat[i][pivot_idx] == 0) {
+                               incomparable = true;
+                               break;
+                       }
+               }
+               if (!incomparable) {
+                       // Split the teams into three partitions:
+                       var better_than_pivot = [], equal = [], worse_than_pivot = [];
+                       for (var i = 0; i < n; ++i) {
+                               var we_beat = (beat[pivot_idx][i] == 1);
+                               var they_beat = (beat[i][pivot_idx] == 1);
+                               if ((i == pivot_idx) || (we_beat && they_beat)) {
+                                       equal.push(teams[i]);
+                               } else if (we_beat && !they_beat) {
+                                       worse_than_pivot.push(teams[i]);
+                               } else if (they_beat && !we_beat) {
+                                       better_than_pivot.push(teams[i]);
+                               } else {
+                                       console.log("this shouldn't happen");
+                               }
+                       
+                       var result = [];
+                       if (better_than_pivot.length > 0) {
+                               result = partition_by_beat(games, better_than_pivot);
+                       }
+                       result.push(equal);  // Obviously can't be partitioned further.
+                       if (worse_than_pivot.length > 0) {
+                               result = result.concat(partition_by_beat(games, worse_than_pivot));
+                       }
+                       return result;
+               }
+       }
 
-  // No usable pivot was found, so the graph is inherently
-  // disconnected, and we cannot partition it.
-  return [teams];
+       // No usable pivot was found, so the graph is inherently
+       // disconnected, and we cannot partition it.
+       return [teams];
 }
 
 // Takes in an array, gives every element a rank starting with 1, and returns.
 rank = function(games, teams, start_rank, tiebreakers) {
-  if (teams.length <= 1) {
-    // Only one team, so trivial.
-    teams[0].rank = start_rank;
-    return teams;
-  }
+       if (teams.length <= 1) {
+               // Only one team, so trivial.
+               teams[0].rank = start_rank;
+               return teams;
+       }
 
-  // Rule #0: Partition the teams by score.
-  var score_parts = partition(teams, function(a, b) { return b.pts - a.pts });
-  if (score_parts.length > 1) {
-    return subrank_partitions(games, score_parts, start_rank, tiebreakers);
-  }
+       // Rule #0: Partition the teams by score.
+       var score_parts = partition(teams, function(a, b) { return b.pts - a.pts });
+       if (score_parts.length > 1) {
+               return subrank_partitions(games, score_parts, start_rank, tiebreakers);
+       }
 
-  // Rule #1: Head-to-head wins.
-  var beat_parts = partition_by_beat(games, teams);
-  if (beat_parts.length > 1) {
-    tiebreakers.push(explain_tiebreaker(beat_parts, 'head-to-head'));
-    return subrank_partitions(games, beat_parts, start_rank, tiebreakers);
-  }
+       // Rule #1: Head-to-head wins.
+       var beat_parts = partition_by_beat(games, teams);
+       if (beat_parts.length > 1) {
+               tiebreakers.push(explain_tiebreaker(beat_parts, 'head-to-head'));
+               return subrank_partitions(games, beat_parts, start_rank, tiebreakers);
+       }
 
-  // Rule #2: Number of games played (fewer is better).
-  // Actually the rule says “fewest losses”, but fewer games is equivalent
-  // as long as teams have the same amount of points and ties don't exist.
-  var nplayed_parts = partition(teams, function(a, b) { return a.nplayed - b.nplayed });
-  if (nplayed_parts.length > 1) {
-    tiebreakers.push(explain_tiebreaker(nplayed_parts, 'fewer losses'));
-    return subrank_partitions(games, nplayed_parts, start_rank, tiebreakers);
-  }
+       // Rule #2: Number of games played (fewer is better).
+       // Actually the rule says “fewest losses”, but fewer games is equivalent
+       // as long as teams have the same amount of points and ties don't exist.
+       var nplayed_parts = partition(teams, function(a, b) { return a.nplayed - b.nplayed });
+       if (nplayed_parts.length > 1) {
+               tiebreakers.push(explain_tiebreaker(nplayed_parts, 'fewer losses'));
+               return subrank_partitions(games, nplayed_parts, start_rank, tiebreakers);
+       }
 
-  // Rule #3: Head-to-head goal difference. 
-  var teams_to_idx = make_teams_to_idx(teams);
-  for (var i = 0; i < teams.length; i++) {
-    teams[i].h2h_gd = 0;
-    teams[i].h2h_goals = 0;
-    teams[i].goals = 0;
-  }
-  for (i = 0; i < games.length; ++i) {
-    var idx1 = teams_to_idx[games[i].name1];
-    var idx2 = teams_to_idx[games[i].name2];
-    if (idx1 !== undefined && idx2 !== undefined) {
-      teams[idx1].h2h_gd += games[i].score1;
-      teams[idx1].h2h_gd -= games[i].score2;
-      teams[idx2].h2h_gd += games[i].score2;
-      teams[idx2].h2h_gd -= games[i].score1;
+       // Rule #3: Head-to-head goal difference. 
+       var teams_to_idx = make_teams_to_idx(teams);
+       for (var i = 0; i < teams.length; i++) {
+               teams[i].h2h_gd = 0;
+               teams[i].h2h_goals = 0;
+               teams[i].goals = 0;
+       }
+       for (i = 0; i < games.length; ++i) {
+               var idx1 = teams_to_idx[games[i].name1];
+               var idx2 = teams_to_idx[games[i].name2];
+               if (idx1 !== undefined && idx2 !== undefined) {
+                       teams[idx1].h2h_gd += games[i].score1;
+                       teams[idx1].h2h_gd -= games[i].score2;
+                       teams[idx2].h2h_gd += games[i].score2;
+                       teams[idx2].h2h_gd -= games[i].score1;
 
-      teams[idx1].h2h_goals += games[i].score1;
-      teams[idx2].h2h_goals += games[i].score2;
-    }
-    if (idx1 !== undefined) {
-      teams[idx1].goals += games[i].score1;
-    }
-    if (idx2 !== undefined) {
-      teams[idx2].goals += games[i].score2;
-    }
-  }
-  var h2h_gd_parts = partition(teams, function(a, b) { return b.h2h_gd - a.h2h_gd });
-  if (h2h_gd_parts.length > 1) {
-    tiebreakers.push(explain_tiebreaker(h2h_gd_parts, 'head-to-head goal difference'));
-    return subrank_partitions(games, h2h_gd_parts, start_rank, tiebreakers);
-  }
+                       teams[idx1].h2h_goals += games[i].score1;
+                       teams[idx2].h2h_goals += games[i].score2;
+               }
+               if (idx1 !== undefined) {
+                       teams[idx1].goals += games[i].score1;
+               }
+               if (idx2 !== undefined) {
+                       teams[idx2].goals += games[i].score2;
+               }
+       }
+       var h2h_gd_parts = partition(teams, function(a, b) { return b.h2h_gd - a.h2h_gd });
+       if (h2h_gd_parts.length > 1) {
+               tiebreakers.push(explain_tiebreaker(h2h_gd_parts, 'head-to-head goal difference'));
+               return subrank_partitions(games, h2h_gd_parts, start_rank, tiebreakers);
+       }
 
-  // Rule #4: Global goal difference. (Well, not strictly, but good enough.)
-  var gd_parts = partition(teams, function(a, b) { return b.gd - a.gd });
-  if (gd_parts.length > 1) {
-    tiebreakers.push(explain_tiebreaker(gd_parts, 'overall goal difference'));
-    return subrank_partitions(games, gd_parts, start_rank, tiebreakers);
-  }
+       // Rule #4: Global goal difference. (Well, not strictly, but good enough.)
+       var gd_parts = partition(teams, function(a, b) { return b.gd - a.gd });
+       if (gd_parts.length > 1) {
+               tiebreakers.push(explain_tiebreaker(gd_parts, 'overall goal difference'));
+               return subrank_partitions(games, gd_parts, start_rank, tiebreakers);
+       }
 
-  // Rule #5: Head-to-head scored goals.
-  var h2h_goals_parts = partition(teams, function(a, b) { return b.h2h_goals - a.h2h_goals });
-  if (h2h_goals_parts.length > 1) {
-    tiebreakers.push(explain_tiebreaker(h2h_goals_parts, 'head-to-head scored goals'));
-    return subrank_partitions(games, h2h_goals_parts, start_rank, tiebreakers);
-  }
+       // Rule #5: Head-to-head scored goals.
+       var h2h_goals_parts = partition(teams, function(a, b) { return b.h2h_goals - a.h2h_goals });
+       if (h2h_goals_parts.length > 1) {
+               tiebreakers.push(explain_tiebreaker(h2h_goals_parts, 'head-to-head scored goals'));
+               return subrank_partitions(games, h2h_goals_parts, start_rank, tiebreakers);
+       }
 
-  // Rule #6: Overall scored goals. (Same caveat as #4.)
-  var goals_parts = partition(teams, function(a, b) { return b.goals - a.goals });
-  if (goals_parts.length > 1) {
-    tiebreakers.push(explain_tiebreaker(goals_parts, 'scored goals'));
-    return subrank_partitions(games, goals_parts, start_rank, tiebreakers);
-  }
+       // Rule #6: Overall scored goals. (Same caveat as #4.)
+       var goals_parts = partition(teams, function(a, b) { return b.goals - a.goals });
+       if (goals_parts.length > 1) {
+               tiebreakers.push(explain_tiebreaker(goals_parts, 'scored goals'));
+               return subrank_partitions(games, goals_parts, start_rank, tiebreakers);
+       }
 
-  // OK, it's a tie. Give them all the same rank.
-  var result = [];
-  for (var i = 0; i < teams.length; ++i) {
-    result.push(teams[i]);
-    result[i].rank = start_rank;
-  }
-  return result; 
+       // OK, it's a tie. Give them all the same rank.
+       var result = [];
+       for (var i = 0; i < teams.length; ++i) {
+               result.push(teams[i]);
+               result[i].rank = start_rank;
+       }
+       return result; 
 }; 
 
 var req = new XMLHttpRequest();
 req.onload = function(e) {
-  var response = JSON.parse(req.responseText);
-  console.log(response.values);
-  var carousel = document.getElementById('carousel');
-  var teams = [];
-  for (var i = 2; response.values[i].length >= 1; ++i) {
-    teams.push({
-      "name": response.values[i][0],
-      "shortname": response.values[i][1],
-      "nplayed": parseInt(response.values[i][2]),
-      "gd": parseInt(response.values[i][3].replace(/−/, '-')),
-      "pts": parseInt(response.values[i][4])
-    });
-  }
-  var games = [];
-  for (var i = 12; response.values[i] !== undefined && response.values[i].length >= 1; ++i) {
-    if (response.values[i][2] && response.values[i][3]) {
-      games.push({
-        "name1": response.values[i][0],
-        "name2": response.values[i][1],
-        "score1": parseInt(response.values[i][2]),
-        "score2": parseInt(response.values[i][3])
-      });
-    }
-  }
-  console.log(games);
+       var response = JSON.parse(req.responseText);
+       console.log(response.values);
+       var carousel = document.getElementById('carousel');
+       var teams = [];
+       for (var i = 2; response.values[i].length >= 1; ++i) {
+               teams.push({
+                               "name": response.values[i][0],
+                               "shortname": response.values[i][1],
+                               "nplayed": parseInt(response.values[i][2]),
+                               "gd": parseInt(response.values[i][3].replace(/−/, '-')),
+                               "pts": parseInt(response.values[i][4])
+                               });
+       }
+       var games = [];
+       for (var i = 12; response.values[i] !== undefined && response.values[i].length >= 1; ++i) {
+               if (response.values[i][2] && response.values[i][3]) {
+                       games.push({
+                                       "name1": response.values[i][0],
+                                       "name2": response.values[i][1],
+                                       "score1": parseInt(response.values[i][2]),
+                                       "score2": parseInt(response.values[i][3])
+                                       });
+               }
+       }
+       console.log(games);
 
-  tiebreakers = [];
-  teams = rank(games, teams, 1, tiebreakers);
-  console.log(tiebreakers. join(", "));
+       tiebreakers = [];
+       teams = rank(games, teams, 1, tiebreakers);
+       console.log(tiebreakers. join(", "));
 
-  var row_num = 2;
-  for (i = 0; i < teams.length; ++i) {
-    var tr = document.createElement("tr");
+       var row_num = 2;
+       for (i = 0; i < teams.length; ++i) {
+               var tr = document.createElement("tr");
 
-    addth(tr, "rank", teams[i].rank);
-    addtd(tr, "team", teams[i].name);
-    addtd(tr, "nplayed", teams[i].nplayed);
-    addtd(tr, "gd", teams[i].gd.toString().replace(/-/, '−'));
-    addtd(tr, "pts", teams[i].pts);
+               addth(tr, "rank", teams[i].rank);
+               addtd(tr, "team", teams[i].name);
+               addtd(tr, "nplayed", teams[i].nplayed);
+               addtd(tr, "gd", teams[i].gd.toString().replace(/-/, '−'));
+               addtd(tr, "pts", teams[i].pts);
 
-    tr.style = "-webkit-animation: fade-in 1.0s ease; -webkit-animation-delay: " + 0.25 * (row_num++) + "s; -webkit-animation-fill-mode: both;";
-    carousel.appendChild(tr);
-  }
+               tr.style = "-webkit-animation: fade-in 1.0s ease; -webkit-animation-delay: " + 0.25 * (row_num++) + "s; -webkit-animation-fill-mode: both;";
+               carousel.appendChild(tr);
+       }
 
-  if (tiebreakers.length > 0) {
-    var tie_tr = document.createElement("tr");
-    tie_tr.className = "footer";
-    tie_tr.style = "-webkit-animation: fade-in 2.0s ease; -webkit-animation-delay: " + 0.25 * (row_num++) + "s; -webkit-animation-fill-mode: both;";
-    var td = document.createElement("td");
-    td.appendChild(document.createTextNode("Tiebreaks applied: " + tiebreakers.join(', ')));
-    td.setAttribute("colspan", "5");
-    tie_tr.appendChild(td);
-    carousel.appendChild(tie_tr);
-  }
-  
-  var footer_tr = document.createElement("tr");
-  footer_tr.className = "footer";
-  footer_tr.style = "-webkit-animation: fade-in 2.0s ease; -webkit-animation-delay: " + 0.25 * (row_num++) + "s; -webkit-animation-fill-mode: both;";
-  var td = document.createElement("td");
-  td.appendChild(document.createTextNode("www.trondheimfrisbeeklubb.no | #trøndisk"));
-  td.setAttribute("colspan", "5");
-  footer_tr.appendChild(td);
-  carousel.appendChild(footer_tr);
-  console.log(footer_tr);
+       if (tiebreakers.length > 0) {
+               var tie_tr = document.createElement("tr");
+               tie_tr.className = "footer";
+               tie_tr.style = "-webkit-animation: fade-in 2.0s ease; -webkit-animation-delay: " + 0.25 * (row_num++) + "s; -webkit-animation-fill-mode: both;";
+               var td = document.createElement("td");
+               td.appendChild(document.createTextNode("Tiebreaks applied: " + tiebreakers.join(', ')));
+               td.setAttribute("colspan", "5");
+               tie_tr.appendChild(td);
+               carousel.appendChild(tie_tr);
+       }
 
-  carousel.style.display = 'table';
+       var footer_tr = document.createElement("tr");
+       footer_tr.className = "footer";
+       footer_tr.style = "-webkit-animation: fade-in 2.0s ease; -webkit-animation-delay: " + 0.25 * (row_num++) + "s; -webkit-animation-fill-mode: both;";
+       var td = document.createElement("td");
+       td.appendChild(document.createTextNode("www.trondheimfrisbeeklubb.no | #trøndisk"));
+       td.setAttribute("colspan", "5");
+       footer_tr.appendChild(td);
+       carousel.appendChild(footer_tr);
+       console.log(footer_tr);
+
+       carousel.style.display = 'table';
 }
 req.open('GET', 'https://sheets.googleapis.com/v4/spreadsheets/1CwRHQtpokVMGTPJu2FYYG-6rnG7OfISIcEHwBfXh-Y4/values/A1:E22?key=AIzaSyAuP9yQn8g0bSay6r_RpGtpFeIbwprH1TU');
 if (false) {