X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=carousel.js;h=2336e5545d7a091259150e24a0a49b6f2e73baaa;hb=a33d84fea4047585ea797e9081862475c5d87fcd;hp=fc8a4ecdb0231eaf68a07d2aaa4d7b7a96ebda5d;hpb=a9dba5b7562983e9c71e9ccd275c1b9a9156fc3a;p=ultimatescore diff --git a/carousel.js b/carousel.js index fc8a4ec..2336e55 100644 --- a/carousel.js +++ b/carousel.js @@ -1,18 +1,28 @@ - -addtd = function(tr, className, content) { +function addheading(carousel, colspan, content) +{ + var thead = document.createElement("thead"); + var tr = document.createElement("tr"); + var th = document.createElement("th"); + th.innerHTML = content; + th.setAttribute("colspan", colspan); + tr.appendChild(th); + thead.appendChild(tr); + carousel.appendChild(thead); +}; +function addtd(tr, className, content) { var td = document.createElement("td"); td.appendChild(document.createTextNode(content)); td.className = className; tr.appendChild(td); }; -addth = function(tr, className, content) { +function addth(tr, className, content) { var th = document.createElement("th"); th.appendChild(document.createTextNode(content)); th.className = className; tr.appendChild(th); }; -subrank_partitions = function(games, parts, start_rank, tiebreakers) { +function subrank_partitions(games, parts, start_rank, tiebreakers) { var result = []; for (var i = 0; i < parts.length; ++i) { var part = rank(games, parts[i], start_rank, tiebreakers); @@ -24,7 +34,7 @@ subrank_partitions = function(games, parts, start_rank, tiebreakers) { return result; }; -partition = function(teams, compare) +function partition(teams, compare) { teams.sort(compare); @@ -43,7 +53,7 @@ partition = function(teams, compare) return parts; }; -explain_tiebreaker = function(parts, rule_name) +function explain_tiebreaker(parts, rule_name) { var result = []; for (var i = 0; i < parts.length; ++i) { @@ -52,7 +62,7 @@ explain_tiebreaker = function(parts, rule_name) return result.join(" > ") + " (" + rule_name + ")"; } -make_teams_to_idx = function(teams) +function make_teams_to_idx(teams) { var teams_to_idx = []; for (var i = 0; i < teams.length; i++) { @@ -61,7 +71,7 @@ make_teams_to_idx = function(teams) return teams_to_idx; } -partition_by_beat = function(games, teams) +function partition_by_beat(games, teams) { // Head-to-head score by way of components. First construct the beat matrix. var n = teams.length; @@ -139,7 +149,7 @@ partition_by_beat = function(games, teams) } // Takes in an array, gives every element a rank starting with 1, and returns. -rank = function(games, teams, start_rank, tiebreakers) { +function rank(games, teams, start_rank, tiebreakers) { if (teams.length <= 1) { // Only one team, so trivial. teams[0].rank = start_rank; @@ -177,7 +187,8 @@ rank = function(games, teams, start_rank, tiebreakers) { 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 (idx1 !== undefined && idx2 !== undefined && + !isNaN(games[i].score1) && isNaN(games[i].score2)) { teams[idx1].h2h_gd += games[i].score1; teams[idx1].h2h_gd -= games[i].score2; teams[idx2].h2h_gd += games[i].score2; @@ -223,39 +234,70 @@ rank = function(games, teams, start_rank, tiebreakers) { 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'); +function parse_teams_from_spreadsheet(response) { var teams = []; for (var i = 2; response.values[i].length >= 1; ++i) { teams.push({ "name": response.values[i][0], - "shortname": response.values[i][1], + "mediumname": response.values[i][1], + "shortname": response.values[i][2], + "tags": response.values[i][3], "nplayed": 0, "gd": 0, "pts": 0, "goals": 0 }); } + return teams; +}; + +function parse_games_from_spreadsheet(response, group_name, include_unplayed) { 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]) { + var i; + for (i = 0; i < response.values.length; ++i) { + if (response.values[i][0] === 'Results') { + i += 2; + break; + } + } + + for ( ; response.values[i] !== undefined && response.values[i].length >= 1; ++i) { + if ((response.values[i][2] && response.values[i][3]) || include_unplayed) { + var real_group_name = response.values[i][9]; + if (real_group_name === undefined) { + real_group_name = group_name; + } games.push({ "name1": response.values[i][0], "name2": response.values[i][1], "score1": parseInt(response.values[i][2]), - "score2": parseInt(response.values[i][3]) + "score2": parseInt(response.values[i][3]), + "streamday": response.values[i][7], + "streamtime": response.values[i][8], + "group_name": real_group_name }); } } + return games; +}; + +function display_group(response, group_name) +{ + var teams = parse_teams_from_spreadsheet(response); + var games = parse_games_from_spreadsheet(response, group_name, false); + display_group_parsed(teams, games, group_name); +}; + +function display_group_parsed(teams, games, group_name) +{ + document.getElementById('entire-bug').style.display = 'none'; var teams_to_idx = make_teams_to_idx(teams); - for (i = 0; i < games.length; ++i) { + for (var i = 0; i < games.length; ++i) { var idx1 = teams_to_idx[games[i].name1]; var idx2 = teams_to_idx[games[i].name2]; if (games[i].score1 === undefined || games[i].score2 === undefined || + isNaN(games[i].score1) || isNaN(games[i].score2) || idx1 === undefined || idx2 === undefined || games[i].score1 == games[i].score2) { continue; @@ -275,9 +317,22 @@ req.onload = function(e) { } } - tiebreakers = []; + var tiebreakers = []; teams = rank(games, teams, 1, tiebreakers); + var carousel = document.getElementById('carousel'); + clear_carousel(carousel); + + addheading(carousel, 5, "Current standings, Trøndisk 2017
" + group_name); + var tr = document.createElement("tr"); + tr.className = "subfooter"; + addth(tr, "rank", ""); + addth(tr, "team", ""); + addth(tr, "nplayed", "P"); + addth(tr, "gd", "GD"); + addth(tr, "pts", "Pts"); + carousel.appendChild(tr); + var row_num = 2; for (i = 0; i < teams.length; ++i) { var tr = document.createElement("tr"); @@ -288,14 +343,12 @@ req.onload = function(e) { 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); } 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"); @@ -305,16 +358,268 @@ req.onload = function(e) { 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); + fade_in_rows(carousel); + carousel.style.display = 'table'; +}; + +function fade_in_rows(table) +{ + var trs = table.getElementsByTagName("tr"); + for (var i = 1; i < trs.length; ++i) { // The header already has its own fade-in. + if (trs[i].className === "footer") { + trs[i].style = "-webkit-animation: fade-in 1.0s ease; -webkit-animation-delay: " + (0.25 * i) + "s; -webkit-animation-fill-mode: both;"; + } else { + trs[i].style = "-webkit-animation: fade-in 2.0s ease; -webkit-animation-delay: " + (0.25 * i) + "s; -webkit-animation-fill-mode: both;"; + } + } +}; + +function fade_out_rows(table) +{ + var trs = table.getElementsByTagName("tr"); + for (var i = 0; i < trs.length; ++i) { + if (trs[i].className === "footer") { + trs[i].style = "-webkit-animation: fade-out 1.0s ease; -webkit-animation-delay: " + (0.125 * i) + "s; -webkit-animation-fill-mode: both;"; + } else { + trs[i].style = "-webkit-animation: fade-out 1.0s ease; -webkit-animation-delay: " + (0.125 * i) + "s; -webkit-animation-fill-mode: both;"; + } + } +}; + +function clear_carousel(table) +{ + while (table.childNodes.length > 0) { + table.removeChild(table.firstChild); + } +}; + +// Stream schedule +var max_list_len = 8; + +function display_stream_schedule(response, group_name) { + var teams = parse_teams_from_spreadsheet(response); + var games = parse_games_from_spreadsheet(response, group_name, true); + display_stream_schedule_parsed(teams, games, 0); +}; + +function sort_game_list(games) { + games = games.filter(function(game) { return game.streamtime !== undefined && game.streamtime.match(/[0-9]+:[0-9]+/) != null; }); + games.sort(function(a, b) { + if (a.streamday !== b.streamday) { + return a.streamday - b.streamday; + } + + var m1 = a.streamtime.match(/([0-9]+):([0-9]+)/); + var m2 = b.streamtime.match(/([0-9]+):([0-9]+)/); + return (m1[1] * 60 + m1[2]) - (m2[1] * 60 + m2[2]); + }); + return games; } -req.open('GET', 'https://sheets.googleapis.com/v4/spreadsheets/1CwRHQtpokVMGTPJu2FYYG-6rnG7OfISIcEHwBfXh-Y4/values/A1:E22?key=AIzaSyAuP9yQn8g0bSay6r_RpGtpFeIbwprH1TU'); -if (false) { + +function find_game_start_idx(games) { + // Pick out a reasonable place to start the list. We'll show the last + // completed match and start from there. + var start_idx = games.length - 1; + for (var i = 0; i < games.length; ++i) { + if (isNaN(games[i].score1) || isNaN(games[i].score2) && + games[i].score1 === games[i].score2) { + start_idx = i; + break; + } + } + if (start_idx > 0) start_idx--; + if (games.length >= max_list_len) { + start_idx = Math.min(start_idx, games.length - max_list_len); + } + return start_idx; +} + +function find_num_pages(games) { + games = sort_game_list(games); + var start_idx = find_game_start_idx(games); + return Math.ceil((games.length - start_idx) / max_list_len); +} + +function display_stream_schedule_parsed(teams, games, page) { + document.getElementById('entire-bug').style.display = 'none'; + + games = sort_game_list(games); + var start_idx = find_game_start_idx(games); + + start_idx += page * max_list_len; + if (start_idx >= games.length) { + // Error. + return; + } + + var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; + var shortdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; + var today = days[(new Date).getDay()]; + + var covered_days = []; + var row_num = 0; + for (var i = start_idx; i < games.length && row_num++ < max_list_len; ++i) { + if (i == start_idx || games[i].streamday != games[i - 1].streamday) { + covered_days.push(days[games[i].streamday]); + } + } + + var carousel = document.getElementById('carousel'); + clear_carousel(carousel); + addheading(carousel, 3, "Stream schedule, Trøndisk 2017
" + covered_days.join('/') + " (all times CET)"); + + var teams_to_idx = make_teams_to_idx(teams); + row_num = 0; + for (i = start_idx; i < games.length && row_num < max_list_len; ++i) { + var tr = document.createElement("tr"); + + var name1 = teams[teams_to_idx[games[i].name1]].mediumname; + var name2 = teams[teams_to_idx[games[i].name2]].mediumname; + + addtd(tr, "matchup", name1 + "–" + name2); + addtd(tr, "group", games[i].group_name); + + if (!isNaN(games[i].score1) && !isNaN(games[i].score2) && + games[i].score1 !== games[i].score2) { + addtd(tr, "streamtime", games[i].score1 + "–" + games[i].score2); + } else { + var streamtime = games[i].streamtime; + var streamday = days[games[i].streamday]; + if (streamday !== today) { + streamtime = shortdays[games[i].streamday] + " " + streamtime; + } + addth(tr, "streamtime", streamtime); + } + + row_num++; + carousel.appendChild(tr); + } + + fade_in_rows(carousel); + + carousel.style.display = 'table'; +}; + +function get_group(group_name, cb) +{ + var req = new XMLHttpRequest(); + req.onload = function(e) { + cb(JSON.parse(req.responseText), group_name); + }; + req.open('GET', 'https://sheets.googleapis.com/v4/spreadsheets/1CwRHQtpokVMGTPJu2FYYG-6rnG7OfISIcEHwBfXh-Y4/values/\'' + group_name + '\'!A1:J50?key=AIzaSyAuP9yQn8g0bSay6r_RpGtpFeIbwprH1TU'); req.send(); +}; + +function showgroup(group_name) +{ + get_group(group_name, display_group); +}; + +function showgroup_from_state() +{ + showgroup(state['group_name']); +}; + +var carousel_timeout = null; + +function hidetable() +{ + fade_out_rows(document.getElementById('carousel')); +}; + +function showschedule(page) +{ + var teams = []; + var games = []; + var num_left = 3; + + var cb = function(response, group_name) { + teams = teams.concat(parse_teams_from_spreadsheet(response)); + games = games.concat(parse_games_from_spreadsheet(response, group_name, true)); + if (--num_left == 0) { + display_stream_schedule_parsed(teams, games, 0); + } + }; + + get_group('Group A', cb); + get_group('Group B', cb); + get_group('Playoffs', cb); +}; + +function do_series(series) +{ + do_series_internal(series, 0); +}; + +function do_series_internal(series, idx) +{ + (series[idx][1])(); + if (idx + 1 < series.length) { + carousel_timeout = setTimeout(function() { do_series_internal(series, idx + 1); }, series[idx][0]); + } +}; + +function showcarousel() +{ + var teams_per_group = []; + var games_per_group = []; + var combined_teams = []; + var combined_games = []; + var num_left = 3; + + var cb = function(response, group_name) { + var teams = parse_teams_from_spreadsheet(response); + var games = parse_games_from_spreadsheet(response, group_name, true); + teams_per_group[group_name] = teams; + games_per_group[group_name] = games; + + combined_teams = combined_teams.concat(teams); + combined_games = combined_games.concat(games); + if (--num_left == 0) { + var series = [ + [ 13000, function() { display_group_parsed(teams_per_group['Group A'], games_per_group['Group A'], 'Group A'); } ], + [ 2000, function() { hidetable(); } ], + [ 13000, function() { display_group_parsed(teams_per_group['Group B'], games_per_group['Group B'], 'Group B'); } ], + [ 2000, function() { hidetable(); } ] + ]; + var num_pages = find_num_pages(combined_games); + for (let page = 0; page < num_pages; ++page) { + series.push([ 13000, function() { display_stream_schedule_parsed(combined_teams, combined_games, page); } ]); + series.push([ 2000, function() { hidetable(); } ]); + } + + do_series(series); + } + }; + + get_group('Group A', cb); + get_group('Group B', cb); + get_group('Playoffs', cb); +}; + +function stopcarousel() +{ + if (carousel_timeout !== null) { + hidetable(); + clearTimeout(carousel_timeout); + carousel_timeout = null; + } +}; + +function hidescorebug() +{ + document.getElementById('entire-bug').style.display = 'none'; } + +function showscorebug() +{ + document.getElementById('entire-bug').style.display = null; +}; +