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.
1007 lines
33 KiB
1007 lines
33 KiB
/******/ (function(modules) { // webpackBootstrap
|
|
/******/ // The module cache
|
|
/******/ var installedModules = {};
|
|
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
|
|
/******/ // Check if module is in cache
|
|
/******/ if(installedModules[moduleId])
|
|
/******/ return installedModules[moduleId].exports;
|
|
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = installedModules[moduleId] = {
|
|
/******/ exports: {},
|
|
/******/ id: moduleId,
|
|
/******/ loaded: false
|
|
/******/ };
|
|
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.loaded = true;
|
|
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
|
|
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = modules;
|
|
|
|
/******/ // expose the module cache
|
|
/******/ __webpack_require__.c = installedModules;
|
|
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "";
|
|
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(0);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
var _matrices = __webpack_require__(1);
|
|
|
|
var _matrices2 = _interopRequireDefault(_matrices);
|
|
|
|
var _diagram = __webpack_require__(2);
|
|
|
|
var _diagram2 = _interopRequireDefault(_diagram);
|
|
|
|
var _ui = __webpack_require__(4);
|
|
|
|
var _ui2 = _interopRequireDefault(_ui);
|
|
|
|
var _sorter = __webpack_require__(3);
|
|
|
|
var _sorter2 = _interopRequireDefault(_sorter);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
__webpack_require__(5);
|
|
__webpack_require__(6);
|
|
__webpack_require__(7);
|
|
__webpack_require__(8);
|
|
__webpack_require__(9);
|
|
__webpack_require__(10);
|
|
__webpack_require__(11);
|
|
__webpack_require__(12);
|
|
|
|
var main = {
|
|
changeEvent: function changeEvent(e) {
|
|
var target = _ui2.default.findRoot(e.target);
|
|
main.setState({ eventKey: target.getAttribute(_ui2.default.DATA.EVENT) });
|
|
main.updateUI();
|
|
},
|
|
|
|
changeSort: function changeSort(e) {
|
|
var target = _ui2.default.findRoot(e.target);
|
|
main.setState({ sort: target.getAttribute(_ui2.default.DATA.SORT) });
|
|
main.updateUI();
|
|
},
|
|
|
|
changeScheme: function changeScheme(e) {
|
|
var target = _ui2.default.findRoot(e.target);
|
|
main.setState({ scheme: target.getAttribute(_ui2.default.DATA.SCHEME) });
|
|
main.updateUI();
|
|
},
|
|
|
|
changeRound: function changeRound(e) {
|
|
var target = _ui2.default.findRoot(e.target);
|
|
var r = target.getAttribute(_ui2.default.DATA.ROUND);
|
|
|
|
var state = main.getState();
|
|
var roundsToShow = state.rounds ? state.rounds.split(',') : [];
|
|
var i = roundsToShow.indexOf(r);
|
|
i === -1 ? roundsToShow.push(r) : roundsToShow.splice(i, 1);
|
|
|
|
main.setState({ rounds: roundsToShow });
|
|
main.updateUI();
|
|
},
|
|
|
|
getRounds: function getRounds(eventKey) {
|
|
var rounds = {};
|
|
|
|
main.json.tourneys[eventKey].games.forEach(function (game) {
|
|
var name = _ui2.default.getRoundName(main.json.rounds[game.rId]);
|
|
if (rounds[name] === undefined) {
|
|
rounds[name] = [];
|
|
}
|
|
|
|
rounds[name].push({
|
|
id: game.rId,
|
|
name: name
|
|
});
|
|
});
|
|
|
|
return rounds;
|
|
},
|
|
|
|
generateUI: function generateUI() {
|
|
var state = main.getState();
|
|
|
|
_ui2.default.buildTourneyPane();
|
|
_ui2.default.buildEventsPane(main.changeEvent);
|
|
_ui2.default.buildSortPane(main.changeSort);
|
|
_ui2.default.buildSchemePane(main.changeScheme);
|
|
_ui2.default.buildRoundsPane(main.changeRound);
|
|
},
|
|
|
|
updateUI: function updateUI() {
|
|
var state = main.getState();
|
|
|
|
var matrix = _matrices2.default.buildMatrix(main.json, state.eventKey);
|
|
_diagram2.default.clear();
|
|
_diagram2.default.build(main.json, state.eventKey, state.sort, state.scheme, _ui2.default.SORT_TYPES, matrix);
|
|
|
|
_ui2.default.updateTourneyPane(state.eventKey);
|
|
_ui2.default.updateEventsPane(state.eventKey);
|
|
_ui2.default.updateSortPane(state.sort);
|
|
_ui2.default.updateSchemePane(state.scheme);
|
|
_ui2.default.updateRoundsPane(state.rounds.split(','), main.json.rounds);
|
|
},
|
|
|
|
fetch: function fetch(url) {
|
|
return new Promise(function (resolve, reject) {
|
|
var listener = function listener(_ref) {
|
|
var req = _ref.srcElement;
|
|
|
|
req.status === 200 ? resolve(req.responseText) : reject("busted");
|
|
};
|
|
|
|
var req = new XMLHttpRequest();
|
|
req.addEventListener('load', listener);
|
|
req.open('GET', url);
|
|
req.send();
|
|
});
|
|
},
|
|
|
|
initJSON: function initJSON(strData) {
|
|
main.json = JSON.parse(strData);
|
|
},
|
|
|
|
getState: function getState() {
|
|
var params = window.location.href.split('?')[1];
|
|
|
|
if (!params) {
|
|
return {};
|
|
}
|
|
|
|
return params.split('&').reduce(function (acc, v) {
|
|
var tmp = v.split('=');
|
|
acc[tmp[0]] = tmp[1];
|
|
return acc;
|
|
}, {});
|
|
},
|
|
|
|
initState: function initState() {
|
|
var 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(_ui2.default.ROUND_TYPES);
|
|
|
|
main.setState(state);
|
|
},
|
|
|
|
setState: function setState(next) {
|
|
var state = main.getState();
|
|
var 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;
|
|
|
|
var params = [];
|
|
for (var key in state) {
|
|
params.push(key + '=' + state[key]);
|
|
}
|
|
|
|
history.pushState(null, null, url + '?' + params.join('&'));
|
|
}
|
|
};
|
|
|
|
main.fetch('worldcup.json').then(main.initJSON).then(main.initState).then(main.generateUI).then(main.updateUI);
|
|
|
|
/***/ },
|
|
/* 1 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var Matrices = {
|
|
// A x A array of nulls; null-null relationships are omitted in chord diagram.
|
|
createEmptyMatrix: function createEmptyMatrix(len) {
|
|
var empty = Array.apply(null, Array(len));
|
|
return empty.map(function () {
|
|
return empty.map(function () {
|
|
return null;
|
|
});
|
|
});
|
|
},
|
|
|
|
// Scalar data points (sum of goals scored).
|
|
buildMatrix: function buildMatrix(json, eventKey) {
|
|
var teams = json.tourneys[eventKey].teams;
|
|
var matrix = Matrices.createEmptyMatrix(teams.length);
|
|
|
|
json.tourneys[eventKey].games.forEach(function (g) {
|
|
var i1 = teams.findIndex(function (v) {
|
|
return v.tId === g.t1;
|
|
});
|
|
var i2 = teams.findIndex(function (v) {
|
|
return v.tId === g.t2;
|
|
});
|
|
|
|
matrix[i1][i2] = g.s1 + g.se1 + g.sp1;
|
|
matrix[i2][i1] = g.s2 + g.se2 + g.sp2;
|
|
}, []);
|
|
|
|
return matrix;
|
|
},
|
|
|
|
swapIndices: function swapIndices(arr, i, j) {
|
|
var tmp = arr[i];
|
|
arr[i] = arr[j];
|
|
arr[j] = tmp;
|
|
|
|
return arr;
|
|
}
|
|
};
|
|
|
|
exports.default = Matrices;
|
|
|
|
/***/ },
|
|
/* 2 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _sorter = __webpack_require__(3);
|
|
|
|
var _sorter2 = _interopRequireDefault(_sorter);
|
|
|
|
var _matrices = __webpack_require__(1);
|
|
|
|
var _matrices2 = _interopRequireDefault(_matrices);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var Diagram = {
|
|
clear: function clear() {
|
|
return d3.select('svg').selectAll("*").remove();
|
|
},
|
|
|
|
swapGroupArcs: function swapGroupArcs(chords, i, j) {
|
|
if (i < 0 || j < 0 || i === j) {
|
|
return chords;
|
|
}
|
|
|
|
// Determine which arc is closer to 0, so earlier arc always swaps with later.
|
|
var f = chords.groups[i].endAngle < chords.groups[j].endAngle ? i : j;
|
|
var s = chords.groups[i].endAngle < chords.groups[j].endAngle ? j : i;
|
|
|
|
var fst = Object.assign({}, chords.groups[f]);
|
|
var snd = Object.assign({}, chords.groups[s]);
|
|
|
|
var fstAngle = fst.endAngle - fst.startAngle;
|
|
var sndAngle = snd.endAngle - snd.startAngle;
|
|
var offsetAngle = sndAngle - fstAngle;
|
|
|
|
// Bring first forward.
|
|
chords.groups[f].startAngle = snd.endAngle - fstAngle;
|
|
chords.groups[f].endAngle = snd.endAngle;
|
|
chords.groups[f].index = snd.index;
|
|
|
|
// Bring second back.
|
|
chords.groups[s].startAngle = fst.startAngle;
|
|
chords.groups[s].endAngle = fst.startAngle + sndAngle;
|
|
chords.groups[s].index = fst.index;
|
|
|
|
// Bump other groups forward.
|
|
for (var ii = f + 1; ii < s; ii++) {
|
|
chords.groups[ii].startAngle += offsetAngle;
|
|
chords.groups[ii].endAngle += offsetAngle;
|
|
}
|
|
|
|
chords.forEach(function (v) {
|
|
if (v.source.index === f) {
|
|
v.source.startAngle += snd.endAngle - fst.endAngle;
|
|
v.source.endAngle += snd.endAngle - fst.endAngle;
|
|
}
|
|
|
|
if (v.target.index === f) {
|
|
v.target.startAngle += snd.endAngle - fst.endAngle;
|
|
v.target.endAngle += snd.endAngle - fst.endAngle;
|
|
}
|
|
|
|
if (v.source.index === s) {
|
|
v.source.startAngle -= snd.startAngle - fst.startAngle;
|
|
v.source.endAngle -= snd.startAngle - fst.startAngle;
|
|
}
|
|
|
|
if (v.target.index === s) {
|
|
v.target.startAngle -= snd.startAngle - fst.startAngle;
|
|
v.target.endAngle -= snd.startAngle - fst.startAngle;
|
|
}
|
|
|
|
if (v.source.index > f && v.source.index < s) {
|
|
v.source.startAngle += offsetAngle;
|
|
v.source.endAngle += offsetAngle;
|
|
}
|
|
|
|
if (v.target.index > f && v.target.index < s) {
|
|
v.target.startAngle += offsetAngle;
|
|
v.target.endAngle += offsetAngle;
|
|
}
|
|
|
|
if ((v.source.index === f || v.source.index === s) && (v.target.index === f || v.target.index === s)) {
|
|
var _tmp = v.source.index;
|
|
v.source.index = v.target.index;
|
|
v.target.index = _tmp;
|
|
} else if (v.source.index === f) {
|
|
v.source.index = s;
|
|
} else if (v.target.index === f) {
|
|
v.target.index = s;
|
|
} else if (v.source.index === s) {
|
|
v.source.index = f;
|
|
} else if (v.target.index === s) {
|
|
v.target.index = f;
|
|
}
|
|
});
|
|
|
|
// Swap array positions.
|
|
var tmp = chords.groups[f];
|
|
chords.groups[f] = chords.groups[s];
|
|
chords.groups[s] = tmp;
|
|
|
|
return chords;
|
|
},
|
|
|
|
swapGroups: function swapGroups(data, eventKey, chords, i, j) {
|
|
Diagram.swapGroupArcs(chords, i, j);
|
|
_matrices2.default.swapIndices(data.tourneys[eventKey].teams, i, j);
|
|
return chords;
|
|
},
|
|
|
|
getCountryName: function getCountryName(data, eventKey, n) {
|
|
var team = data.tourneys[eventKey].teams[n];
|
|
return data.countries[team.cId];
|
|
},
|
|
|
|
getPopulation: function getPopulation(data, eventKey, n) {
|
|
var team = data.tourneys[eventKey].teams[n];
|
|
return team.p;
|
|
},
|
|
|
|
getGoalsFor: function getGoalsFor(data, eventKey, n) {
|
|
var team = data.tourneys[eventKey].teams[n];
|
|
return team.gf;
|
|
},
|
|
|
|
getGoalsAgainst: function getGoalsAgainst(data, eventKey, n) {
|
|
var team = data.tourneys[eventKey].teams[n];
|
|
return team.ga;
|
|
},
|
|
|
|
build: function build(data, eventKey, sort, scheme, SORT_TYPES, matrix) {
|
|
var svg = d3.select("svg"),
|
|
width = svg.attr("width"),
|
|
height = svg.attr("height"),
|
|
outerArcThickness = 5,
|
|
outerRadius = Math.min(width, height) * 0.5 - 130,
|
|
innerRadius = outerRadius - outerArcThickness;
|
|
|
|
var chords = d3.chord().padAngle(0.05).call(null, matrix);
|
|
|
|
var sortedChords = chords;
|
|
switch (sort) {
|
|
case SORT_TYPES.COUNTRY:
|
|
sortedChords = _sorter2.default.sort(chords, 0, chords.groups.length - 1, Diagram.getCountryName.bind(null, data, eventKey), Diagram.swapGroups.bind(null, data, eventKey));
|
|
break;
|
|
case SORT_TYPES.GOALS:
|
|
sortedChords = _sorter2.default.sort(chords, 0, chords.groups.length - 1, Diagram.getGoalsFor.bind(null, data, eventKey), Diagram.swapGroups.bind(null, data, eventKey));
|
|
break;
|
|
case SORT_TYPES.POPULATION:
|
|
sortedChords = _sorter2.default.sort(chords, 0, chords.groups.length - 1, Diagram.getPopulation.bind(null, data, eventKey), Diagram.swapGroups.bind(null, data, eventKey));
|
|
break;
|
|
}
|
|
|
|
var arc = d3.arc().innerRadius(innerRadius).outerRadius(outerRadius);
|
|
|
|
var ribbon = d3.ribbon().radius(innerRadius);
|
|
|
|
var len = data.tourneys[eventKey].teams.length;
|
|
var color = d3.scaleOrdinal(d3.schemeCategory20);
|
|
|
|
(function () {
|
|
switch (parseInt(scheme)) {
|
|
case 1:
|
|
color = d3.scaleLinear().domain([0, len]).range(["#fff", "green"]).interpolate(d3.interpolateRgb);
|
|
break;
|
|
case 2:
|
|
var colors = ["#ffffd9", "#edf8b1", "#c7e9b4", "#7fcdbb", "#41b6c4", "#1d91c0", "#225ea8", "#253494", "#081d58"];
|
|
color = function color(i) {
|
|
return colors[i % colors.length];
|
|
};
|
|
break;
|
|
case 3:
|
|
color = d3.scaleLinear().domain([0, len]).range(["red", "blue"]).interpolate(d3.interpolateRgb);
|
|
break;
|
|
case 4:
|
|
color = d3.scaleOrdinal(d3.schemeCategory10);
|
|
break;
|
|
}
|
|
})();
|
|
|
|
var g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")").datum(sortedChords);
|
|
|
|
var group = g.append("g").attr("class", "groups").selectAll("g").data(function (chords) {
|
|
return chords.groups;
|
|
}).enter().append("g");
|
|
|
|
group.append("path").style("fill", function (d) {
|
|
return color(d.index);
|
|
}).style("stroke", function (d) {
|
|
return d3.rgb(color(d.index)).darker();
|
|
}).attr("d", arc);
|
|
|
|
g.append("g").attr("class", "ribbons").selectAll("path").data(function (chords) {
|
|
return chords;
|
|
}).enter().append("path").attr("d", ribbon).attr("data-round-id", function (d) {
|
|
var t1 = data.tourneys[eventKey].teams[d.source.index];
|
|
var t2 = data.tourneys[eventKey].teams[d.target.index];
|
|
|
|
var game = data.tourneys[eventKey].games.find(function (v) {
|
|
return (v.t1 === t1.tId || v.t1 === t2.tId) && (v.t2 === t1.tId || v.t2 === t2.tId);
|
|
});
|
|
|
|
return game.rId;
|
|
}).style("fill", function (d) {
|
|
return color(d.target.index);
|
|
}).style("stroke", function (d) {
|
|
return d3.rgb(color(d.target.index)).darker();
|
|
}).classed("ribbon", true).append("title").text(function (d) {
|
|
var t1 = data.tourneys[eventKey].teams[d.source.index];
|
|
var t2 = data.tourneys[eventKey].teams[d.target.index];
|
|
|
|
var c1 = data.countries[t1.cId];
|
|
var c2 = data.countries[t2.cId];
|
|
|
|
var game = data.tourneys[eventKey].games.find(function (v) {
|
|
return (v.t1 === t1.tId || v.t1 === t2.tId) && (v.t2 === t1.tId || v.t2 === t2.tId);
|
|
});
|
|
|
|
var e1 = game.se1 ? '(+' + game.se1 + ' in extended time)' : '';
|
|
var e2 = game.se2 ? '(+' + game.se2 + ' in extended time)' : '';
|
|
|
|
var p1 = game.sp1 ? '(+' + game.sp1 + ' in penalties)' : '';
|
|
var p2 = game.sp2 ? '(+' + game.sp2 + ' in penalties)' : '';
|
|
|
|
return c1 + ': ' + game.s1 + ' ' + e1 + ' ' + p1 + '\n' + c2 + ': ' + game.s2 + ' ' + e2 + ' ' + p2;
|
|
});
|
|
|
|
group.append("text").each(function (d) {
|
|
d.angle = (d.startAngle + d.endAngle) / 2;
|
|
}).attr("dy", ".35em").attr("transform", function (d) {
|
|
return "rotate(" + (d.angle * 180 / Math.PI - 91) + ")" + "translate(" + (innerRadius + 26) + ")" + (d.angle > Math.PI ? "rotate(180)" : "");
|
|
}).style("text-anchor", function (d) {
|
|
return d.angle > Math.PI ? "end" : null;
|
|
}).text(function (d) {
|
|
var team = data.tourneys[eventKey].teams[d.index];
|
|
var metric = '';
|
|
|
|
switch (sort) {
|
|
case SORT_TYPES.GOALS:
|
|
metric = '(' + team.gf + ')';
|
|
break;
|
|
// case SORT_TYPES.POPULATION:
|
|
// metric = `(${Number(team.p).toLocaleString()})`;
|
|
// break;
|
|
}
|
|
|
|
return data.countries[team.cId] + ' ' + metric;
|
|
});
|
|
}
|
|
};
|
|
|
|
exports.default = Diagram;
|
|
|
|
/***/ },
|
|
/* 3 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var Sorter = {
|
|
sort: function sort(chords, start, end, getVal, swap) {
|
|
if (end <= start) {
|
|
return chords;
|
|
}
|
|
|
|
var left = start;
|
|
var right = end;
|
|
|
|
var pivot = Math.floor((right + left) / 2);
|
|
var pivotval = getVal(pivot);
|
|
var tmp;
|
|
var rval;
|
|
|
|
while (left <= right) {
|
|
while (getVal(left) < pivotval) {
|
|
left++;
|
|
}
|
|
|
|
while (getVal(right) > pivotval) {
|
|
right--;
|
|
}
|
|
|
|
if (left <= right) {
|
|
chords = swap(chords, left, right);
|
|
|
|
left++;
|
|
right--;
|
|
}
|
|
break;
|
|
}
|
|
|
|
Sorter.sort(chords, start, right, getVal, swap);
|
|
Sorter.sort(chords, left, end, getVal, swap);
|
|
|
|
return chords;
|
|
}
|
|
};
|
|
|
|
exports.default = Sorter;
|
|
|
|
/***/ },
|
|
/* 4 */
|
|
/***/ function(module, exports) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var UI = {
|
|
CLASSNAMES: {
|
|
TOURNEY: {
|
|
LINK: 'tourney-link',
|
|
IMAGE: 'tourney-image',
|
|
COUNTRY: 'tourney-country',
|
|
YEAR: 'tourney-year'
|
|
},
|
|
EVENT: {
|
|
ITEM: 'event-item',
|
|
YEAR: 'event-year',
|
|
FLAG: 'event-flag'
|
|
},
|
|
|
|
SCHEME: {
|
|
SCHEME1: 'scheme-item scheme1',
|
|
SCHEME2: 'scheme-item scheme2',
|
|
SCHEME3: 'scheme-item scheme3',
|
|
SCHEME4: 'scheme-item scheme4'
|
|
},
|
|
|
|
SORT: {
|
|
ICON: 'sort-icon',
|
|
ITEM: 'sort-item',
|
|
TEXT: 'sort-text',
|
|
TINY: 'sort-tiny'
|
|
},
|
|
|
|
ROUND: {
|
|
ICON: 'round-icon',
|
|
ITEM: 'round-item',
|
|
TEXT: 'round-text',
|
|
TINY: 'round-tiny'
|
|
}
|
|
},
|
|
|
|
SORT_TYPES: {
|
|
GOALS: 'goals',
|
|
COUNTRY: 'country',
|
|
POPULATION: 'population'
|
|
},
|
|
|
|
ROUND_TYPES: {
|
|
PRELIM: '1',
|
|
ROUNDOF16: '2',
|
|
QUARTERFINAL: '3',
|
|
SEMIFINAL: '4',
|
|
CONSOLATION: '5',
|
|
FINAL: '6'
|
|
},
|
|
|
|
DATA: {
|
|
ROOT: 'data-root',
|
|
EVENT: 'data-event-key',
|
|
ROUND: 'data-round-key',
|
|
SCHEME: 'data-round-scheme',
|
|
SORT: 'data-sort-key'
|
|
},
|
|
|
|
I18N: {
|
|
HIDE: 'hide',
|
|
SHOW: 'show'
|
|
},
|
|
|
|
findRoot: function findRoot(node) {
|
|
while (node !== document.body && node.getAttribute(UI.DATA.ROOT) === null) {
|
|
node = node.parentNode;
|
|
}
|
|
|
|
return node;
|
|
},
|
|
|
|
clearActive: function clearActive(nodes) {
|
|
nodes.forEach(function (node) {
|
|
var classes = node.className.split(' ');
|
|
var i = classes.indexOf('active');
|
|
|
|
if (i !== -1) {
|
|
classes.splice(i, 1);
|
|
node.className = classes.join(' ');
|
|
}
|
|
});
|
|
},
|
|
|
|
updateTourneyPane: function updateTourneyPane(eventKey) {
|
|
var tourneyList = {
|
|
'1930': "Uruguay",
|
|
'1934': "Italy",
|
|
'1938': "France",
|
|
'1950': "Brazil",
|
|
'1954': "Switzerland",
|
|
'1958': "Sweden",
|
|
'1962': "Chile",
|
|
'1966': "England",
|
|
'1970': "Mexico",
|
|
'1974': "West Germany",
|
|
'1978': "Argentina",
|
|
'1982': "Spain",
|
|
'1986': "Mexico",
|
|
'1990': "Italy",
|
|
'1994': "USA",
|
|
'1998': "France",
|
|
'2002': "Japan / South Korea",
|
|
'2006': "Germany",
|
|
'2010': "Johannesburg",
|
|
'2014': "Brazil"
|
|
};
|
|
|
|
var ek = tourneyList[eventKey] === undefined ? null : eventKey;
|
|
|
|
var tourneyPane = document.querySelector('.tourney');
|
|
|
|
tourneyPane.querySelector('.' + UI.CLASSNAMES.TOURNEY.IMAGE).src = 'res/' + ek + '.jpg';
|
|
tourneyPane.querySelector('.' + UI.CLASSNAMES.TOURNEY.LINK).href = 'https://en.wikipedia.org/wiki/' + ek + '_FIFA_World_Cup';
|
|
tourneyPane.querySelector('.' + UI.CLASSNAMES.TOURNEY.COUNTRY).innerHTML = tourneyList[ek];
|
|
tourneyPane.querySelector('.' + UI.CLASSNAMES.TOURNEY.YEAR).innerHTML = ek;
|
|
},
|
|
|
|
updateEventsPane: function updateEventsPane(eventKey) {
|
|
var eventItems = document.querySelectorAll('.' + UI.CLASSNAMES.EVENT.ITEM);
|
|
UI.clearActive(eventItems);
|
|
|
|
var activeEventNode = document.querySelector('[' + UI.DATA.EVENT + '="' + eventKey + '"');
|
|
activeEventNode.className += ' active';
|
|
},
|
|
|
|
updateRoundsPane: function updateRoundsPane(roundsToShow, allRounds) {
|
|
var roundsItems = document.querySelectorAll('.' + UI.CLASSNAMES.ROUND.ITEM);
|
|
UI.clearActive(roundsItems);
|
|
|
|
roundsItems.forEach(function (item) {
|
|
var type = item.getAttribute(UI.DATA.ROUND);
|
|
var tiny = item.querySelector('.' + UI.CLASSNAMES.ROUND.TINY);
|
|
tiny.innerHTML = UI.I18N.SHOW;
|
|
|
|
if (roundsToShow.indexOf(type) > -1) {
|
|
item.className += ' active';
|
|
tiny.innerHTML = UI.I18N.HIDE;
|
|
}
|
|
});
|
|
|
|
var ribbons = document.querySelectorAll('.ribbon');
|
|
ribbons.forEach(function (ribbon) {
|
|
var name = allRounds[ribbon.getAttribute("data-round-id")];
|
|
var type = UI.getRoundType(name);
|
|
|
|
roundsToShow.indexOf(type) === -1 ? ribbon.style.display = 'none' : ribbon.style.display = 'inline';
|
|
});
|
|
},
|
|
|
|
updateSchemePane: function updateSchemePane(scheme) {
|
|
var schemeItems = document.querySelectorAll('.scheme-item');
|
|
UI.clearActive(schemeItems);
|
|
|
|
schemeItems.forEach(function (node) {
|
|
if (node.getAttribute(UI.DATA.SCHEME) === scheme) {
|
|
node.className += ' active';
|
|
}
|
|
});
|
|
},
|
|
|
|
updateSortPane: function updateSortPane(sort) {
|
|
var sortItems = document.querySelectorAll('.sort-item');
|
|
UI.clearActive(sortItems);
|
|
|
|
sortItems.forEach(function (node) {
|
|
if (node.getAttribute(UI.DATA.SORT) === sort) {
|
|
node.className += ' active';
|
|
}
|
|
});
|
|
},
|
|
|
|
buildTourneyPane: function buildTourneyPane() {
|
|
var link = document.createElement('a');
|
|
var img = document.createElement('img');
|
|
var country = document.createElement('div');
|
|
var year = document.createElement('year');
|
|
|
|
link.className = UI.CLASSNAMES.TOURNEY.LINK;
|
|
link.target = '_blank';
|
|
|
|
img.className = UI.CLASSNAMES.TOURNEY.IMAGE;
|
|
|
|
country.className = UI.CLASSNAMES.TOURNEY.COUNTRY;
|
|
|
|
year.className = UI.CLASSNAMES.TOURNEY.YEAR;
|
|
|
|
var tourneyPane = document.querySelector('.tourney');
|
|
|
|
link.appendChild(img);
|
|
|
|
tourneyPane.appendChild(link);
|
|
tourneyPane.appendChild(year);
|
|
tourneyPane.appendChild(country);
|
|
},
|
|
|
|
buildEventsPane: function buildEventsPane(onClick) {
|
|
var eventsList = [{ year: 1930, icon: "uy" }, { year: 1934, icon: "it" }, { year: 1938, icon: "fr" }, { year: 1950, icon: "br" }, { year: 1954, icon: "ch" }, { year: 1958, icon: "se" }, { year: 1962, icon: "cl" }, { year: 1966, icon: "gb" }, { year: 1970, icon: "mx" }, { year: 1974, icon: "de" }, { year: 1978, icon: "ar" }, { year: 1982, icon: "es" }, { year: 1986, icon: "mx" }, { year: 1990, icon: "it" }, { year: 1994, icon: "us" }, { year: 1998, icon: "fr" }, { year: 2002, icon: "jp" }, { year: 2006, icon: "de" }, { year: 2010, icon: "za" }, { year: 2014, icon: "br" }];
|
|
|
|
var eventsDiv = document.querySelector('.events');
|
|
|
|
while (eventsDiv.hasChildNodes()) {
|
|
eventsDiv.firstChild.remove();
|
|
}
|
|
|
|
eventsList.forEach(function (evt) {
|
|
var item = document.createElement('div');
|
|
var year = document.createElement('div');
|
|
var flag = document.createElement('div');
|
|
|
|
item.className = UI.CLASSNAMES.EVENT.ITEM;
|
|
item.addEventListener('click', onClick);
|
|
item.setAttribute(UI.DATA.EVENT, evt.year);
|
|
item.setAttribute(UI.DATA.ROOT, true);
|
|
|
|
year.className = UI.CLASSNAMES.EVENT.YEAR;
|
|
year.innerHTML = evt.year;
|
|
|
|
flag.className = UI.CLASSNAMES.EVENT.FLAG + ' flag-icon flag-icon-' + evt.icon;
|
|
|
|
item.appendChild(year);
|
|
item.appendChild(flag);
|
|
|
|
eventsDiv.appendChild(item);
|
|
});
|
|
},
|
|
|
|
buildSortPane: function buildSortPane(onClick) {
|
|
var sortList = [{ text: 'Default', value: null }, { text: 'Goals Scored', value: UI.SORT_TYPES.GOALS }, { text: 'Country Name', value: UI.SORT_TYPES.COUNTRY }];
|
|
|
|
var sortDiv = document.querySelector('.sort');
|
|
|
|
while (sortDiv.hasChildNodes()) {
|
|
sortDiv.firstChild.remove();
|
|
}
|
|
|
|
sortList.forEach(function (sort) {
|
|
var icon = document.createElement('img');
|
|
var item = document.createElement('div');
|
|
var text = document.createElement('div');
|
|
var tiny = document.createElement('div');
|
|
|
|
item.className = UI.CLASSNAMES.SORT.ITEM;
|
|
item.addEventListener('click', onClick);
|
|
item.setAttribute(UI.DATA.SORT, sort.value);
|
|
item.setAttribute(UI.DATA.ROOT, true);
|
|
|
|
text.className = UI.CLASSNAMES.SORT.TEXT;
|
|
text.innerHTML = sort.text;
|
|
|
|
tiny.className = UI.CLASSNAMES.SORT.TINY;
|
|
tiny.innerHTML = 'sort';
|
|
|
|
icon.className = UI.CLASSNAMES.SORT.ICON;
|
|
icon.src = 'res/sort.svg';
|
|
|
|
item.appendChild(icon);
|
|
item.appendChild(text);
|
|
item.appendChild(tiny);
|
|
|
|
sortDiv.appendChild(item);
|
|
});
|
|
},
|
|
|
|
buildSchemePane: function buildSchemePane(onClick) {
|
|
var schemePane = document.querySelector('.schemes');
|
|
|
|
var scheme1 = document.createElement('div');
|
|
var scheme2 = document.createElement('div');
|
|
var scheme3 = document.createElement('div');
|
|
var scheme4 = document.createElement('div');
|
|
|
|
scheme1.className = UI.CLASSNAMES.SCHEME.SCHEME1;
|
|
scheme1.setAttribute(UI.DATA.SCHEME, 1);
|
|
scheme1.addEventListener('click', onClick);
|
|
scheme1.setAttribute(UI.DATA.ROOT, true);
|
|
|
|
scheme2.className = UI.CLASSNAMES.SCHEME.SCHEME2;
|
|
scheme2.setAttribute(UI.DATA.SCHEME, 2);
|
|
scheme2.addEventListener('click', onClick);
|
|
scheme2.setAttribute(UI.DATA.ROOT, true);
|
|
|
|
scheme3.className = UI.CLASSNAMES.SCHEME.SCHEME3;
|
|
scheme3.setAttribute(UI.DATA.SCHEME, 3);
|
|
scheme3.addEventListener('click', onClick);
|
|
scheme3.setAttribute(UI.DATA.ROOT, true);
|
|
|
|
scheme4.className = UI.CLASSNAMES.SCHEME.SCHEME4;
|
|
scheme4.setAttribute(UI.DATA.SCHEME, 4);
|
|
scheme4.addEventListener('click', onClick);
|
|
scheme4.setAttribute(UI.DATA.ROOT, true);
|
|
|
|
schemePane.appendChild(scheme1);
|
|
schemePane.appendChild(scheme2);
|
|
schemePane.appendChild(scheme3);
|
|
schemePane.appendChild(scheme4);
|
|
},
|
|
|
|
buildRoundsPane: function buildRoundsPane(onClick) {
|
|
var roundsList = [{ text: 'Preliminaries', value: UI.ROUND_TYPES.PRELIM }, { text: 'Round of 16', value: UI.ROUND_TYPES.ROUNDOF16 }, { text: 'Quarterfinals', value: UI.ROUND_TYPES.QUARTERFINAL }, { text: 'Semifinals', value: UI.ROUND_TYPES.SEMIFINAL }, { text: 'Consolation', value: UI.ROUND_TYPES.CONSOLATION }, { text: 'Final', value: UI.ROUND_TYPES.FINAL }];
|
|
|
|
var roundsDiv = document.querySelector('.rounds');
|
|
|
|
while (roundsDiv.hasChildNodes()) {
|
|
roundsDiv.firstChild.remove();
|
|
}
|
|
|
|
roundsList.forEach(function (round) {
|
|
var icon = document.createElement('img');
|
|
var item = document.createElement('div');
|
|
var text = document.createElement('div');
|
|
var tiny = document.createElement('div');
|
|
|
|
item.className = UI.CLASSNAMES.ROUND.ITEM;
|
|
item.addEventListener('click', onClick);
|
|
item.setAttribute(UI.DATA.ROUND, round.value);
|
|
item.setAttribute(UI.DATA.ROOT, true);
|
|
|
|
tiny.className = UI.CLASSNAMES.ROUND.TINY;
|
|
tiny.innerHTML = 'hide';
|
|
|
|
text.className = UI.CLASSNAMES.ROUND.TEXT;
|
|
text.innerHTML = round.text;
|
|
|
|
icon.className = UI.CLASSNAMES.ROUND.ICON;
|
|
icon.src = 'res/check.svg';
|
|
|
|
item.appendChild(icon);
|
|
item.appendChild(text);
|
|
item.appendChild(tiny);
|
|
|
|
roundsDiv.appendChild(item);
|
|
});
|
|
},
|
|
|
|
getRoundType: function getRoundType(name) {
|
|
var name2 = name.match(/^Matchday/) ? 'First round' : name;
|
|
|
|
switch (name2) {
|
|
case 'Preliminary round':
|
|
case 'First round':
|
|
case 'First round replays':
|
|
case 'Group-1 Play-off':
|
|
case 'Group-2 Play-off':
|
|
case 'Group-3 Play-off':
|
|
case 'Group-4 Play-off':
|
|
return UI.ROUND_TYPES.PRELIM;
|
|
case 'Round of 16':
|
|
return UI.ROUND_TYPES.ROUNDOF16;
|
|
case 'Third place match':
|
|
case 'Third-place match':
|
|
case 'Match for third place':
|
|
case 'Third place play-off':
|
|
case 'Third-place play-off':
|
|
return UI.ROUND_TYPES.CONSOLATION;
|
|
case 'Quarterfinals':
|
|
case 'Quarter-finals':
|
|
case 'Quarter-finals replays':
|
|
return UI.ROUND_TYPES.QUARTERFINAL;
|
|
case 'Semifinals':
|
|
case 'Semi-finals':
|
|
return UI.ROUND_TYPES.SEMIFINAL;
|
|
case 'Final':
|
|
case 'Finals':
|
|
return UI.ROUND_TYPES.FINAL;
|
|
}
|
|
|
|
console.error('Unknown round name: ' + name);
|
|
return name;
|
|
}
|
|
};
|
|
|
|
exports.default = UI;
|
|
|
|
/***/ },
|
|
/* 5 */
|
|
/***/ function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ },
|
|
/* 6 */
|
|
/***/ function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ },
|
|
/* 7 */
|
|
/***/ function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ },
|
|
/* 8 */
|
|
/***/ function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ },
|
|
/* 9 */
|
|
/***/ function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ },
|
|
/* 10 */
|
|
/***/ function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ },
|
|
/* 11 */
|
|
/***/ function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ },
|
|
/* 12 */
|
|
/***/ function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }
|
|
/******/ ]); |