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 = ({ srcElement: 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);