Skip to content

Instantly share code, notes, and snippets.

@owain68
Created June 26, 2018 09:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save owain68/813fd9c445d34e79e83b182dbcd0ff3f to your computer and use it in GitHub Desktop.
Save owain68/813fd9c445d34e79e83b182dbcd0ff3f to your computer and use it in GitHub Desktop.
Generate tournament brackets
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://sheets.googleapis.com/$discovery/rest?version=v4"];
var SCOPES = "https://www.googleapis.com/auth/spreadsheets.readonly";
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message);
pre.appendChild(textContent);
}
/*
* Print the names and majors of students in a sample spreadsheet:
*/
function listMajors() {
gapi.client.sheets.spreadsheets.values.get({
spreadsheetId: '1YgToE7KCx4BpGt08pGQkExVcqBHqvTPPWHcH5v1-sz8',
/* range: 'Class Data!A2:E', */
range: 'Sheet1!A1:X',
}).then(function(response) {
/* Global variables for <<ROUND>> and <<RESULT>> */
var range = response.result;
var ROUND = [];
var RESULT = [];
var PLAYER = [];
if (range.values.length > 0) {
for (i = 0; i < 2; i++) {
ROUND[i] = [];
var row = range.values[i];
for (col = 0; col < 8; col++){
ROUND[i][col] = row[2+3*col]; /* Col C, F, I etc */
}
}
for (i = 3; i < range.values.length; i++) {
RESULT[i-3] = [];
PLAYER[i-3] = [];
var row = range.values[i];
for (col = 0; col < 8; col++){
PLAYER[i-3][col] = row[2+3*col];
RESULT[i-3][col] = row[3+3*col];
}
/* Fix for full player name in first round */
PLAYER[i-3][0] = row[1] + ' ' + row[2];
}
/* Print out Values */
for (i = 0; i < PLAYER.length ; i++){
row = '';
for (col = 0 ; col < 8 ; col++){
var str = String(PLAYER[i][col]);
if (str.indexOf("undefined") != -1 ){
PLAYER[i][col] = '';
}
if (RESULT[i][col] === undefined || RESULT[i][col] === null || 0 == RESULT[i][col].length ){
RESULT[i][col] = '';
}
else{
RESULT[i][col] = '[' + RESULT[i][col] + ']';
}
appendPre( PLAYER[i][col] + ' ' + RESULT[i][col] + ', ');
}
appendPre('\n');
}
printBrackets(ROUND, PLAYER, RESULT);
printMobile(ROUND, PLAYER, RESULT);
} else {
appendPre('No data found.');
}
}, function(response) {
appendPre('Error: ' + response.result.error.message);
});
}
function printBrackets(ROUND, PLAYER, RESULT){
/* groupCount is the number of rounds of matches
* excluding the winner on their own. Have to calculate
* as a power of two
*/
groupCount = (Math.log2(PLAYER.length));
topMargin = 10;
bottomMargin = 10;
bracketSize = 33;
var group = $('<div class="group'+(groupCount+1)+'" id="b0"></div>');
/* Build divs round by round */
gameoffset = 0;
for(rnd = 0; rnd < groupCount; rnd++) {
/* Number of games depends on the round */
numgames = PLAYER.length / Math.pow(2,1+rnd) ;
jump = Math.pow(2,1+rnd);
/* Calculate the width dynamically
* First column has 20% for the full name
* remainder divide it out
*/
leftwid = Math.max(23, 76 / groupCount);
remwid = (97 - leftwid) / groupCount;
if (rnd == 0){
wid = 'style="width: ' + leftwid + '%;"';
}
else{
wid = 'style="width:' + remwid + '%;"';
}
var round = $('<div class="r' + (rnd+1) + '" ' + wid + '></div>');
/* Dynamically calculate the margin of the divs */
style = 'style="margin:' + topMargin +'px 0px ' + bottomMargin + 'px 0px; height:' + bracketSize + 'px;"'
styleBottom = 'style="margin:' + topMargin +'px 0px 0px 0px; height:' + bracketSize + 'px;"'
/* Set line-height to equal the box size to center the text */
style2 = 'style="line-height: ' + bracketSize + 'px;"'
/* Add heading */
round.append('<div style="margin: 0px; height: 35px;"><b>' + ROUND[0][rnd] + '</br>' + ROUND[1][rnd] + '</b></div>')
for(game = 0; game < numgames; game++){
if (game < (numgames-1)){ /* Need bottom margin if not last element */
round.append('<div ' + style + '><div class="bracketbox"><span class="info"' + style2 +'>'+(1 + gameoffset + game)+'</span><span class="teama">'+PLAYER[jump*game][rnd]+' '+RESULT[jump*game][rnd]+'</span><span class="teamb">'+PLAYER[jump*(game+0.5)][rnd]+' '+RESULT[jump*(game+0.5)][rnd]+'</span></div></div>');
}
else{
round.append('<div ' + styleBottom + '><div class="bracketbox"><span class="info"' + style2 +'>'+(1 + gameoffset + game)+'</span><span class="teama">'+PLAYER[jump*game][rnd]+' '+RESULT[jump*game][rnd]+'</span><span class="teamb">'+PLAYER[jump*(game+0.5)][rnd]+' '+RESULT[jump*(game+0.5)][rnd]+'</span></div></div>');
}
group.append(round);
}
gameoffset += numgames;
/* and adjust for next iteration values*/
topMargin += 0.5 * bracketSize;
bracketSize += bottomMargin ;
bottomMargin = bracketSize ;
}
/* Winner */
style = 'style="margin:' + topMargin +'px 0px 0px 0px; height: 0px; width: ' + remwid + '%;"'
/* Add heading */
group.append('<div style="margin: 0px; height: 35px;"><b>' + ROUND[0][rnd] + '</br>' + ROUND[1][rnd] + '</b></div>')
group.append('<div class="r'+(groupCount+1)+'" ' + style + '><div class="final"><div class="bracketbox"><span class="teamc">'+PLAYER[0][groupCount]+'</span></div></div></div>');
$('.brackets').append(group);
}
function printMobile(ROUND, PLAYER, RESULT) {
/* groupCount is the number of rounds of matches
* excluding the winner on their own. Have to calculate
* as a power of two
*/
groupCount = (Math.log2(PLAYER.length));
var mobileview = $('<div></div>');
/* Build divs round by round */
gameoffset = 0;
var round = $('<div></div>');
for(rnd = 0; rnd < groupCount; rnd++) {
/* Number of games depends on the round */
numgames = PLAYER.length / Math.pow(2,1+rnd) ;
jump = Math.pow(2,1+rnd);
/* Calculate the width dynamically
* First column has 20% for the full name
* remainder divide it out
*/
/* Add heading */
stg = ('<h3>' + ROUND[0][rnd] + ' - ' + ROUND[1][rnd] + '</h3>')
/* Start table */
stg += ('<table>');
stg += '<thead><tr><th>Match</th><th>Player 1</th><th>Player 2</th></tr>';
stg += '</thead><tbody>';
for( game = 0; game < numgames; game++){
stg += '<tr><td>' + (1 + gameoffset + game) + '</td>';
for( pl = 0; pl < 2; pl++){
if ((rnd == 0) && (0 == PLAYER[jump*((pl * 0.5) + game)][rnd].length)){ /* Bye */
stg += '<td>Bye</td>';
}
else if (0 == PLAYER[jump*((pl * 0.5)+game)][rnd].length){
stg += '<td>Winner ' + (1 + pl + gameoffset + (2 * game )- (2*numgames)) + '</td>';
}
else {
stg += '<td>' + PLAYER[jump*((pl * 0.5) + game)][rnd] + ' ' + RESULT[jump*((pl * 0.5) +game)][rnd] + '</td>';
}
}
stg += '</tr>';
}
stg += '</tbody></table>';
round.append(stg);
gameoffset += numgames;
}
$('.mobileview').append(round);
}
@owain68
Copy link
Author

owain68 commented Jun 26, 2018

@derekjw314159 https://gist.github.com/owain68/813fd9c445d34e79e83b182dbcd0ff3f#file-dgc_brackets-js-L18 for multiple tournaments that should be a parameter or a named range in the sheet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment