You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
269 lines
8.2 KiB
269 lines
8.2 KiB
import Matrices from './matrices';
|
|
import Diagram from './diagram';
|
|
import UI from './ui';
|
|
import Hotfixes from './hotfixes';
|
|
|
|
require('../css/reset.scss');
|
|
require('../css/index.scss');
|
|
require('../css/events.scss');
|
|
require('../css/tourney.scss');
|
|
require('../css/diagram.scss');
|
|
require('../css/sort.scss');
|
|
require('../css/schemes.scss');
|
|
require('../css/rounds.scss');
|
|
|
|
const main = {
|
|
changeEvent: (e) => {
|
|
const target = UI.findRoot(e.target);
|
|
main.setState({ eventKey: target.getAttribute(UI.DATA.EVENT) });
|
|
main.updateUI();
|
|
},
|
|
|
|
changeSort: (e) => {
|
|
const target = UI.findRoot(e.target);
|
|
main.setState({ sort: target.getAttribute(UI.DATA.SORT) });
|
|
main.updateUI();
|
|
},
|
|
|
|
changeScheme: (e) => {
|
|
const target = UI.findRoot(e.target);
|
|
main.setState({ scheme: target.getAttribute(UI.DATA.SCHEME) });
|
|
main.updateUI();
|
|
},
|
|
|
|
changeRound: (e) => {
|
|
const target = UI.findRoot(e.target);
|
|
const r = target.getAttribute(UI.DATA.ROUND)
|
|
|
|
const state = main.getState();
|
|
const roundsToShow = state.rounds ? state.rounds.split(',') : [];
|
|
const i = roundsToShow.indexOf(r);
|
|
(i === -1) ? roundsToShow.push(r) : roundsToShow.splice(i, 1);
|
|
|
|
main.setState({ rounds: roundsToShow });
|
|
main.updateUI();
|
|
},
|
|
|
|
// DEPRECATED? 161120
|
|
// getRounds: (eventKey) => {
|
|
// const rounds = {};
|
|
//
|
|
// main.json.tourneys[eventKey].games.forEach(game => {
|
|
// const name = UI.getRoundName(main.json.rounds[game.rId]);
|
|
// if (rounds[name] === undefined) {
|
|
// rounds[name] = [];
|
|
// }
|
|
//
|
|
// rounds[name].push({
|
|
// id: game.rId,
|
|
// name: name,
|
|
// });
|
|
// });
|
|
//
|
|
// return rounds;
|
|
// },
|
|
|
|
getDuplicates: (eventKey) => {
|
|
const games = {};
|
|
|
|
main.json.tourneys[eventKey].games.forEach(game => {
|
|
const teams = [game.t1, game.t2].sort();
|
|
const addr = `${teams[0]}-${teams[1]}`;
|
|
|
|
if (games[addr] === undefined) {
|
|
games[addr] = [];
|
|
}
|
|
|
|
games[addr].push(game);
|
|
});
|
|
|
|
return Object.keys(games).reduce((acc, k) => {
|
|
if (games[k].length > 1) {
|
|
acc.push(games[k]);
|
|
}
|
|
|
|
return acc;
|
|
}, []);
|
|
},
|
|
|
|
generateUI: () => {
|
|
const state = main.getState();
|
|
|
|
UI.buildTourneyPane();
|
|
UI.buildEventsPane(main.changeEvent);
|
|
UI.buildSortPane(main.changeSort);
|
|
UI.buildSchemePane(main.changeScheme);
|
|
UI.buildRoundsPane(main.changeRound);
|
|
},
|
|
|
|
updateUI: () => {
|
|
const state = main.getState();
|
|
const eventKey = state.eventKey;
|
|
|
|
const matrix = Matrices.buildMatrix(main.json, eventKey);
|
|
|
|
const duplicates = main.getDuplicates(eventKey);
|
|
|
|
const tmp = Diagram.buildChords({
|
|
data: main.json,
|
|
sort: state.sort,
|
|
eventKey,
|
|
matrix,
|
|
SORT_TYPES: UI.SORT_TYPES,
|
|
});
|
|
|
|
const getScore = (game) => {
|
|
let s1 = game.s1;
|
|
let s2 = game.s2;
|
|
|
|
if (game.sp1 !== null) {
|
|
s1 = game.sp1;
|
|
} else if (game.se1 !== null) {
|
|
s1 = game.se1;
|
|
}
|
|
|
|
if (game.sp2 !== null) {
|
|
s2 = game.sp2;
|
|
} else if (game.se2 !== null) {
|
|
s2 = game.se2;
|
|
}
|
|
|
|
return { s1, s2 }
|
|
};
|
|
|
|
const chords = tmp.reduce((acc, d) => {
|
|
const tSrc = main.json.tourneys[eventKey].teams[d.source.index].tId;
|
|
const tTgt = main.json.tourneys[eventKey].teams[d.target.index].tId;
|
|
|
|
d.game = main.json.tourneys[eventKey].games
|
|
.find(g => {
|
|
return (g.t1 === tSrc && g.t2 === tTgt) ||
|
|
(g.t1 === tTgt && g.t2 === tSrc)
|
|
});
|
|
|
|
duplicates.forEach(games => {
|
|
if (games[0] === d.game || games[1] === d.game) {
|
|
const gameNew = (games[0] === d.game ? games[1] : games[0]);
|
|
const sourceNew = Object.assign({}, d.source);
|
|
const targetNew = Object.assign({}, d.target);
|
|
|
|
const sourceAngle = d.source.endAngle - d.source.startAngle;
|
|
const targetAngle = d.target.endAngle - d.target.startAngle;
|
|
|
|
const { s1: s1g0, s2: s2g0 } = getScore(games[0]);
|
|
const { s1: s1g1, s2: s2g1 } = getScore(games[1]);
|
|
const totals = { src: 0, tgt: 0 };
|
|
const offset = { src: 0, tgt: 0 }
|
|
|
|
totals.src += (games[0].t1 === tSrc ? s1g0 : s2g0);
|
|
totals.tgt += (games[0].t1 === tTgt ? s1g0 : s2g0);
|
|
|
|
totals.src += (games[1].t1 === tSrc ? s1g1 : s2g1);
|
|
totals.tgt += (games[1].t1 === tTgt ? s1g1 : s2g1);
|
|
|
|
offset.src = (games[0].t1 === tSrc ? s1g0 : s2g0);
|
|
offset.tgt = (games[0].t1 === tTgt ? (totals.tgt - s1g0) : (totals.tgt - s2g0));
|
|
|
|
sourceNew.startAngle = d.source.startAngle + sourceAngle * (offset.src / totals.src);
|
|
d.source.endAngle = d.source.startAngle + sourceAngle * (offset.src / totals.src);
|
|
|
|
targetNew.endAngle = d.target.startAngle + targetAngle * (offset.tgt / totals.tgt);
|
|
d.target.startAngle = d.target.startAngle + targetAngle * (offset.tgt / totals.tgt);
|
|
|
|
acc.push({ source: sourceNew, target: targetNew, game: gameNew });
|
|
}
|
|
});
|
|
|
|
acc.push(d);
|
|
|
|
return acc;
|
|
}, []);
|
|
|
|
chords.groups = tmp.groups;
|
|
|
|
Diagram.clear();
|
|
|
|
const color = Diagram.buildColorScheme({
|
|
scheme: parseInt(state.scheme),
|
|
len: main.json.tourneys[state.eventKey].teams.length,
|
|
});
|
|
|
|
const container = Diagram.buildContainer(chords);
|
|
Diagram.buildArcs({ container, color, eventKey, data: main.json });
|
|
Diagram.buildRibbons({ container, color, chords, eventKey, data: main.json });
|
|
|
|
UI.updateTourneyPane(state.eventKey);
|
|
UI.updateEventsPane(state.eventKey);
|
|
UI.updateSortPane(state.sort);
|
|
UI.updateSchemePane(state.scheme);
|
|
UI.updateRoundsPane(state.rounds.split(','), main.json.rounds);
|
|
},
|
|
|
|
fetch: (url) => new Promise((resolve, reject) => {
|
|
const listener = ({ target: req }) => {
|
|
req.status === 200 ? resolve(req.responseText) : reject("busted");
|
|
};
|
|
|
|
const req = new XMLHttpRequest();
|
|
req.addEventListener('load', listener);
|
|
req.open('GET', url);
|
|
req.send();
|
|
}),
|
|
|
|
initJSON: (strData) => {
|
|
main.json = JSON.parse(strData);
|
|
},
|
|
|
|
patchErrors: () => {
|
|
main.json.tourneys['1934'] = Hotfixes.patch1934(main.json.tourneys['1934']);
|
|
},
|
|
|
|
getState: () => {
|
|
const params = window.location.href.split('?')[1];
|
|
|
|
if (!params) {
|
|
return {};
|
|
}
|
|
|
|
return params.split('&').reduce((acc, v) => {
|
|
const tmp = v.split('=');
|
|
acc[tmp[0]] = tmp[1];
|
|
return acc;
|
|
}, {});
|
|
},
|
|
|
|
initState: () => {
|
|
const state = main.getState();
|
|
|
|
state.eventKey = state.eventKey || "2014";
|
|
state.sort = state.sort || null;
|
|
state.scheme = state.scheme || Math.ceil(Math.random() * 4);
|
|
state.rounds = state.rounds || Object.values(UI.ROUND_TYPES);
|
|
|
|
main.setState(state);
|
|
},
|
|
|
|
setState: (next) => {
|
|
const state = main.getState();
|
|
const url = window.location.href.split('?')[0];
|
|
|
|
state.eventKey = next.eventKey || state.eventKey;
|
|
state.rounds = next.rounds || state.rounds;
|
|
state.scheme = next.scheme || state.scheme;
|
|
state.sort = next.sort || state.sort || null;
|
|
|
|
const params = [];
|
|
for (let key in state) {
|
|
params.push(`${key}=${state[key]}`);
|
|
}
|
|
|
|
history.pushState(null, null, `${url}?${params.join('&')}`);
|
|
},
|
|
}
|
|
|
|
main.fetch('worldcup.json')
|
|
.then(main.initJSON)
|
|
.then(main.patchErrors)
|
|
.then(main.initState)
|
|
.then(main.generateUI)
|
|
.then(main.updateUI);
|
|
|