summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jfr_playoff/dto.py4
-rw-r--r--jfr_playoff/generator.py63
-rw-r--r--jfr_playoff/matchinfo.py4
-rw-r--r--jfr_playoff/template.py16
-rw-r--r--playoff.js221
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">&nbsp;</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>
'''
diff --git a/playoff.js b/playoff.js
index a2cfa6a..c118f58 100644
--- a/playoff.js
+++ b/playoff.js
@@ -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]
]);
}
}