var playoff = { settings: { 'winner_h_offset': 8, 'loser_h_offset': 14, 'winner_v_offset': -6, 'loser_v_offset': 6, 'loser_colour': '#ff0000', 'winner_colour': '#00ff00' }, drawLine: function(ctx, line) { ctx.beginPath(); ctx.moveTo(line[0], line[1]); ctx.lineTo(line[2], line[3]); ctx.stroke(); }, loadSettings: function(canvas, defaults) { for (var setting in defaults) { var attr = 'data-' + setting.replace(/_/g, '-'); var attr_value = canvas.getAttribute(attr); if (attr_value) { defaults[setting] = attr_value; } } return defaults; }, run: function() { var boxes = document.getElementsByClassName('playoff_matchbox'); var lines = { 'winner': {}, 'loser': {} }; var boxes_idx = {}; for (var b = 0; b < boxes.length; b++) { var id = boxes[b].getAttribute('data-id'); boxes_idx[id] = boxes[b]; for (var attr in lines) { var value = boxes[b].getAttribute('data-' + attr); if (value) { if (!lines[attr][value]) { lines[attr][value] = []; } lines[attr][value].push(id); } } } var canvas = document.getElementById('playoff_canvas'); this.settings = this.loadSettings(canvas, this.settings); var ctx = canvas.getContext('2d'); for (var type in lines) { ctx.strokeStyle = this.settings[type + '_colour']; for (var from in lines[type]) { var to = lines[type][from]; from = from.split(' '); var horizontal_from = []; var vertical_from = [0, canvas.height, 0, 0]; for (var f = 0; f < from.length; f++) { var box = boxes_idx[from[f]]; var line = [ Math.floor(parseInt(box.style.left) + parseInt(box.clientWidth)), Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + parseFloat(this.settings[type + '_v_offset'])), Math.floor(parseInt(box.style.left) + parseInt(box.clientWidth) + parseFloat(this.settings[type + '_h_offset'])), Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + parseFloat(this.settings[type + '_v_offset'])) ]; horizontal_from.push(line); for (var l in horizontal_from) { if (horizontal_from[l][2] < line[2]) { horizontal_from[l][2] = line[2]; } else { line[2] = horizontal_from[l][2]; } if (vertical_from[0] < horizontal_from[l][2]) { vertical_from[0] = horizontal_from[l][2]; vertical_from[2] = horizontal_from[l][2]; } if (vertical_from[1] > horizontal_from[l][3]) { vertical_from[1] = horizontal_from[l][3]; } if (vertical_from[3] < horizontal_from[l][3]) { vertical_from[3] = horizontal_from[l][3]; } } } var horizontal_to = []; var vertical_to = [canvas.width, canvas.height, canvas.width, 0]; for (var t = 0; t < to.length; t++) { var box = boxes_idx[to[t]]; var line = [ parseInt(box.style.left), Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + parseFloat(this.settings[type + '_v_offset'])), Math.floor(parseInt(box.style.left) - parseFloat(this.settings[type + '_h_offset'])), Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + parseFloat(this.settings[type + '_v_offset'])) ]; horizontal_to.push(line); for (var l in horizontal_to) { if (horizontal_to[l][2] > line[2]) { horizontal_to[l][2] = line[2]; } else { line[2] = horizontal_to[l][2]; } if (vertical_to[0] > horizontal_to[l][2]) { vertical_to[0] = horizontal_to[l][2]; vertical_to[2] = horizontal_to[l][2]; } if (vertical_to[1] > horizontal_to[l][3]) { vertical_to[1] = horizontal_to[l][3]; } if (vertical_to[3] < horizontal_to[l][3]) { vertical_to[3] = horizontal_to[l][3]; } } } var midpoints = [ [ (vertical_from[0] + vertical_from[2]) / 2, (vertical_from[1] + vertical_from[3]) / 2 ], [ parseFloat(this.settings[type + '_h_offset']) / 2 + (vertical_from[0] + vertical_from[2] + vertical_to[0] + vertical_to[2]) / 4, (vertical_from[1] + vertical_from[3]) / 2 ], [ parseFloat(this.settings[type + '_h_offset']) / 2 + (vertical_from[0] + vertical_from[2] + vertical_to[0] + vertical_to[2]) / 4, (vertical_to[1] + vertical_to[3]) / 2 ], [ (vertical_to[0] + vertical_to[2]) / 2, (vertical_to[1] + vertical_to[3]) / 2 ] ] for (var l in horizontal_from) { this.drawLine(ctx, horizontal_from[l]); } this.drawLine(ctx, vertical_from); for (var l in horizontal_to) { this.drawLine(ctx, horizontal_to[l]); } this.drawLine(ctx, vertical_to); for (var m = 0; m < midpoints.length-1; m++) { this.drawLine(ctx, [ midpoints[m][0], midpoints[m][1], midpoints[m+1][0], midpoints[m+1][1] ]); } } } } } playoff.run();