diff options
-rw-r--r-- | jfr_playoff/dto.py | 4 | ||||
-rw-r--r-- | jfr_playoff/generator.py | 63 | ||||
-rw-r--r-- | jfr_playoff/matchinfo.py | 4 | ||||
-rw-r--r-- | jfr_playoff/template.py | 16 | ||||
-rw-r--r-- | playoff.js | 221 |
5 files changed, 222 insertions, 86 deletions
diff --git a/jfr_playoff/dto.py b/jfr_playoff/dto.py index a88cd2b..fa22265 100644 --- a/jfr_playoff/dto.py +++ b/jfr_playoff/dto.py @@ -10,6 +10,10 @@ def coalesce(*arg): class Team(object): name = '' score = 0.0 + place = None + + def __init__(self): + self.place = [] def __unicode__(self): return u'%s (%.1f)' % (coalesce(self.name, '<None>'), self.score) diff --git a/jfr_playoff/generator.py b/jfr_playoff/generator.py index 2206520..6a184fb 100644 --- a/jfr_playoff/generator.py +++ b/jfr_playoff/generator.py @@ -106,33 +106,70 @@ class PlayoffGenerator(object): def get_match_box(self, match, position): if match is not None: + winner_link = [ + str(m) for m in match.winner_matches + ] if match.winner_matches is not None else [] + loser_link = [ + str(m) for m in match.loser_matches + ] if match.loser_matches is not None else [] + place_loser_link = [] + place_winner_link = [] + if 'starting_position_indicators' in self.page \ + and self.page['starting_position_indicators']: + for team in match.teams: + if len(team.place) > 0: + place_link = ['place-' + str(pl) for pl in team.place] + if len(team.place) > 1: + place_loser_link += place_link + else: + place_winner_link += place_link return self.p_temp.get( 'MATCH_BOX', position[0], position[1], match.id, - ' '.join([ - str(m) for m in match.winner_matches - ]) if match.winner_matches is not None else '', - ' '.join([ - str(m) for m in match.loser_matches - ]) if match.loser_matches is not None else '', + ' '.join(winner_link), + ' '.join(loser_link), + ' '.join(place_winner_link), + ' '.join(place_loser_link), self.get_match_table(match)) return '' + def get_starting_position_box(self, positions, dimensions): + if 'starting_position_indicators' not in self.page \ + or not self.page['starting_position_indicators']: + return '' + boxes = '' + order = 0 + for place in sorted(positions): + boxes += self.p_temp.get( + 'STARTING_POSITION_BOX', + 0, + int(float(order) / float(len(positions)) * dimensions[1]), + place, place) + order += 1 + return boxes + + def get_match_grid(self, dimensions, grid, matches): - canvas_size = ( + canvas_size = [ dimensions[0] * ( self.page['width'] + self.page['margin'] - ) - self.page['margin'], + ), dimensions[1] * ( self.page['height'] + self.page['margin'] - ) - self.page['margin']) + ) - self.page['margin']] + if 'starting_position_indicators' not in self.page \ + or not self.page['starting_position_indicators']: + canvas_size[0] -= self.page['margin'] PlayoffLogger.get('generator').info( 'canvas size: %s', canvas_size) grid_boxes = '' col_no = 0 + starting_positions = set() for phase in grid: - grid_x = col_no * (self.page['width'] + self.page['margin']) + grid_x = col_no * self.page['width'] + (col_no + 1) * self.page['margin'] \ + if self.page['starting_position_indicators'] \ + else col_no * (self.page['width'] + self.page['margin']) grid_boxes += self.get_phase_header(phase, grid_x) match_height = canvas_size[1] / len(phase.matches) row_no = 0 @@ -146,8 +183,13 @@ class PlayoffGenerator(object): grid_boxes += self.get_match_box( matches[match] if match is not None else None, (grid_x, grid_y)) + if match is not None: + for team in matches[match].teams: + starting_positions.update(team.place) row_no += 1 col_no += 1 + starting_positions_boxes = self.get_starting_position_box( + starting_positions, canvas_size) return self.p_temp.get( 'MATCH_GRID', canvas_size[0], canvas_size[1], @@ -155,6 +197,7 @@ class PlayoffGenerator(object): ' '.join(['data-%s="%s"' % ( setting.replace('_', '-'), str(value) ) for setting, value in self.canvas.iteritems()]), + starting_positions_boxes, grid_boxes ) diff --git a/jfr_playoff/matchinfo.py b/jfr_playoff/matchinfo.py index 93b997a..5a31577 100644 --- a/jfr_playoff/matchinfo.py +++ b/jfr_playoff/matchinfo.py @@ -187,6 +187,10 @@ class MatchInfo: 'fetching HTML scores for match #%d failed: %s(%s)', self.info.id, type(e).__name__, str(e)) self.info.teams = self.__get_config_teams(self.info.teams) + for team in range(0, len(self.info.teams)): + if 'place' in self.config['teams'][team]: + self.info.teams[team].place = self.config['teams'][team]['place'] + def __get_db_board_count(self): towels = self.database.fetch( diff --git a/jfr_playoff/template.py b/jfr_playoff/template.py index 70c179b..7b91b3b 100644 --- a/jfr_playoff/template.py +++ b/jfr_playoff/template.py @@ -51,6 +51,7 @@ class PlayoffTemplateStrings(object): <div style="position: relative; width: %dpx; height: %dpx; margin: 10px"> <canvas width="%d" height="%d" id="playoff_canvas" %s></canvas> %s + %s <script src="sklady/playoff.js" type="text/javascript"></script> </div> ''' @@ -77,8 +78,21 @@ class PlayoffTemplateStrings(object): <img src="images/A.gif" /> ''' + STARTING_POSITION_BOX = ''' + <div style="position: absolute; left: %dpx; top: %dpx" class="playoff_matchbox" data-id="place-%d"> + <table border="0" cellspacing="0"> + <tr> + <td class="bdcc1" style="opacity: 0"> </td> + </tr> + <tr> + <td class="bdc12" width="20">%d</td> + </tr> + </table> + </div> + ''' + MATCH_BOX = ''' - <div style="text-align: center; position: absolute; left: %dpx; top: %dpx" data-id="%d" data-winner="%s" data-loser="%s" class="playoff_matchbox"> + <div style="text-align: center; position: absolute; left: %dpx; top: %dpx" data-id="%d" data-winner="%s" data-loser="%s" data-place-winner="%s" data-place-loser="%s" class="playoff_matchbox"> %s </div> ''' @@ -1,12 +1,18 @@ var playoff = { settings: { - 'winner_h_offset': 8, - 'loser_h_offset': 14, - 'winner_v_offset': -6, - 'loser_v_offset': 6, + 'winner_h_offset': 5, + 'loser_h_offset': 20, + 'winner_v_offset': -10, + 'loser_v_offset': 10, 'loser_colour': '#ff0000', - 'winner_colour': '#00ff00' + 'winner_colour': '#00ff00', + 'place_winner_h_offset': 10, + 'place_loser_h_offset': 15, + 'place_winner_v_offset': 8, + 'place_loser_v_offset': 14, + 'place_loser_colour': '#dddd00', + 'place_winner_colour': '#00dddd' }, drawLine: function(ctx, line) { @@ -31,7 +37,9 @@ var playoff = { var boxes = document.getElementsByClassName('playoff_matchbox'); var lines = { 'winner': {}, - 'loser': {} + 'loser': {}, + 'place-winner': {}, + 'place-loser': {} }; var boxes_idx = {}; for (var b = 0; b < boxes.length; b++) { @@ -49,99 +57,162 @@ var playoff = { } 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]; + var lineMethods = { + 'place-winner': 'to', + 'place-loser': 'to', + 'winner': 'midpoint', + 'loser': 'midpoint' + }; + var lineCalculator = { + correctLines: function(hLines, vLine, comparator) { + for (var l1 in hLines) { + for (var l2 in hLines) { + hLines[l1][2] = comparator(hLines[l1][2], hLines[l2][2]); + hLines[l2][2] = hLines[l1][2]; + } + } + for (var l1 in hLines) { + vLine[0] = vLine[2] = comparator(hLines[l1][2], vLine[2]); + vLine[1] = Math.min(vLine[1], hLines[l1][3]); + vLine[3] = Math.max(vLine[3], hLines[l1][3]); + } + }, + template: function() { + return { + hFrom: [], + vFrom: [0, canvas.height, 0, 0], + hTo: [], + vTo: [canvas.width, canvas.height, canvas.width, 0], + midpoints: [] + } + }, + from: function(from, to, hOffset, vOffset) { + var lines = this.template(); 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'])) + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset), + Math.floor(parseInt(box.style.left) + parseInt(box.clientWidth) + hOffset), + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset) ]; - 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]; - } - } + lines.hFrom.push(line); } - var horizontal_to = []; - var vertical_to = [canvas.width, canvas.height, canvas.width, 0]; + this.correctLines(lines.hFrom, lines.vFrom, Math.max); + for (var t = 0; t < to.length; t++) { + var box = boxes_idx[to[t]]; + var line = [ + lines.vFrom[0], + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset), + Math.floor(parseInt(box.style.left) - hOffset), + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset) + ]; + lines.hTo.push(line); + } + this.correctLines(lines.hTo, lines.vTo, Math.min); + lines.midpoints = [ + [lines.vFrom[0], lines.vFrom[1]], + [lines.vTo[0], lines.vTo[1]] + ]; + return lines; + }, + to: function(from, to, hOffset, vOffset) { + var lines = this.template(); 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'])) + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset), + Math.floor(parseInt(box.style.left) - hOffset), + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset) ]; - 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]; - } - } + lines.hTo.push(line); + } + this.correctLines(lines.hTo, lines.vTo, Math.min); + 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) + vOffset), + lines.vTo[0], + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset) + ]; + lines.hFrom.push(line); } - var midpoints = [ + this.correctLines(lines.hFrom, lines.vFrom, Math.max); + lines.midpoints = [ + [lines.vFrom[0], lines.vFrom[1]], + [lines.vTo[0], lines.vTo[1]] + ]; + return lines; + }, + midpoint: function(from, to, hOffset, vOffset) { + var lines = this.template(); + 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) + vOffset), + Math.floor(parseInt(box.style.left) + parseInt(box.clientWidth) + hOffset), + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset) + ]; + lines.hFrom.push(line); + } + this.correctLines(lines.hFrom, lines.vFrom, Math.max); + 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) + vOffset), + Math.floor(parseInt(box.style.left) - hOffset), + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + vOffset) + ]; + lines.hTo.push(line); + } + this.correctLines(lines.hTo, lines.vTo, Math.min); + lines.midpoints = [ [ - (vertical_from[0] + vertical_from[2]) / 2, - (vertical_from[1] + vertical_from[3]) / 2 + (lines.vFrom[0] + lines.vFrom[2]) / 2, + (lines.vFrom[1] + lines.vFrom[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 + hOffset / 2 + (lines.vFrom[0] + lines.vFrom[2] + lines.vTo[0] + lines.vTo[2]) / 4, + (lines.vFrom[1] + lines.vFrom[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 + hOffset / 2 + (lines.vFrom[0] + lines.vFrom[2] + lines.vTo[0] + lines.vTo[2]) / 4, + (lines.vTo[1] + lines.vTo[3]) / 2 ], [ - (vertical_to[0] + vertical_to[2]) / 2, - (vertical_to[1] + vertical_to[3]) / 2 + (lines.vTo[0] + lines.vTo[2]) / 2, + (lines.vTo[1] + lines.vTo[3]) / 2 ] ] - for (var l in horizontal_from) { - this.drawLine(ctx, horizontal_from[l]); + return lines; + } + }; + var ctx = canvas.getContext('2d'); + for (var type in lines) { + styleType = type.replace('-', '_'); + ctx.strokeStyle = this.settings[styleType + '_colour']; + for (var from in lines[type]) { + var to = lines[type][from]; + from = from.split(' '); + var linesToDraw = lineCalculator[lineMethods[type]]( + from, to, + this.settings[styleType + '_h_offset'], this.settings[styleType + '_v_offset']); + for (var l in linesToDraw.hFrom) { + this.drawLine(ctx, linesToDraw.hFrom[l]); } - this.drawLine(ctx, vertical_from); - for (var l in horizontal_to) { - this.drawLine(ctx, horizontal_to[l]); + this.drawLine(ctx, linesToDraw.vFrom); + for (var l in linesToDraw.hTo) { + this.drawLine(ctx, linesToDraw.hTo[l]); } - this.drawLine(ctx, vertical_to); - for (var m = 0; m < midpoints.length-1; m++) { + this.drawLine(ctx, linesToDraw.vTo); + for (var m = 0; m < linesToDraw.midpoints.length-1; m++) { this.drawLine(ctx, [ - midpoints[m][0], midpoints[m][1], midpoints[m+1][0], midpoints[m+1][1] + linesToDraw.midpoints[m][0], linesToDraw.midpoints[m][1], + linesToDraw.midpoints[m+1][0], linesToDraw.midpoints[m+1][1] ]); } } |