From 7506974691eecb12e839cb27c9ba59ee4f7098d7 Mon Sep 17 00:00:00 2001 From: Ben Burlingham Date: Sat, 5 Nov 2016 07:55:19 -0700 Subject: [PATCH] Sort state and persistence complete. --- index.html | 5 ++- js/constants.js | 7 ++++ js/diagram.js | 40 +++++++++++------- js/main.js | 33 +++++++++++---- js/ui.js | 105 +++++++++++++++++++++--------------------------- res/events.css | 9 ++++- res/sort.css | 11 +++++ 7 files changed, 126 insertions(+), 84 deletions(-) create mode 100644 js/constants.js diff --git a/index.html b/index.html index 9ce52f6..81171fd 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,7 @@ body { + @@ -71,8 +72,10 @@ body { https://openfootball.github.io/questions.html
TODO
+ embiggen current event flag move styling out of index.html - add team country population below team name + move fetch into main + add sort metric below team name hide rounds round persistence sort persistence diff --git a/js/constants.js b/js/constants.js new file mode 100644 index 0000000..c0551b2 --- /dev/null +++ b/js/constants.js @@ -0,0 +1,7 @@ +const CONSTANTS = { + SORT_TYPES: { + GOALS: 'goals', + COUNTRY: 'country', + POPULATION: 'population', + }, +}; diff --git a/js/diagram.js b/js/diagram.js index a6347a8..bc7d37c 100644 --- a/js/diagram.js +++ b/js/diagram.js @@ -112,15 +112,15 @@ const Diagram = { getGoalsFor: (data, eventKey, n) => { const team = data.tourneys[eventKey].teams[n]; - return team.ga; + return team.gf; }, getGoalsAgainst: (data, eventKey, n) => { const team = data.tourneys[eventKey].teams[n]; - return team.gf; + return team.ga; }, - build: (data, eventKey, matrix) => { + build: (data, eventKey, sort, SORT_TYPES, matrix) => { const svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), @@ -132,14 +132,25 @@ const Diagram = { .padAngle(0.05) .call(null, matrix); - // const sortedChords = Sorter.sort(chords, 0, chords.groups.length - 1, - // // Diagram.getCountryName.bind(null, data, eventKey), - // // Diagram.getGoalsFor.bind(null, data, eventKey), - // Diagram.getGoalsAgainst.bind(null, data, eventKey), - // // Diagram.getPopulation.bind(null, data, eventKey), - // Diagram.swapGroups.bind(null, data, eventKey)); + let sortedChords = chords; + switch (sort) { + case SORT_TYPES.COUNTRY: + sortedChords = Sorter.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 = Sorter.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 = Sorter.sort(chords, 0, chords.groups.length - 1, + Diagram.getPopulation.bind(null, data, eventKey), + Diagram.swapGroups.bind(null, data, eventKey)); + break; + } - const sortedChords = chords; // SORTED: "null" // let sortedChords = Diagram.swapGroups(data, "1930", chords, 2, 10); // sortedChords = Diagram.swapGroups(data, "1930", chords, 2, 8); // [ Romania, Belgium, Serbia, France, US, Mexico, Paraguay, Peru, Uruguay, Chile, Bolivia, Brazil, Argentina ] @@ -155,15 +166,14 @@ const Diagram = { // const color = d3.scaleOrdinal(d3.schemeCategory20); // const color = d3.scaleOrdinal(d3.schemeCategory10); - // const color = d3.scaleOrdinal(d3.interpolateCool); - // const color = d3.scaleSequential(d3.interpolateRainbow); - const color = d3.scaleLinear().domain([0,10]).range(["red", "blue"]).interpolate(d3.interpolateRgb) + const len = data.tourneys[eventKey].teams.length; + // const color = d3.scaleLinear().domain([0, len]).range(["#edf8b1", "#081d58"]).interpolate(d3.interpolateRgb); + // const color = d3.scaleLinear().domain([0, len]).range(["#aaa", "green"]).interpolate(d3.interpolateRgb); + const color = d3.scaleLinear().domain([0, len]).range(["gainsboro", "darkgreen"]).interpolate(d3.interpolateRgb); - // const colors = ["#f1eef6","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"]; // const colors = ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"]; // const colors = ["#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"]; - // const colors = ["#1B9E77", "#D95F02", "#7570B3", "#E7298A", "#66A61E", "#E6AB02", "#A6761D", "#666666"]; // const color = i => colors[i % colors.length]; const g = svg.append("g") diff --git a/js/main.js b/js/main.js index 4f94916..66f946f 100644 --- a/js/main.js +++ b/js/main.js @@ -39,8 +39,10 @@ const main = { }, generateUI: () => { + const state = main.getState(); + UI.buildEventsPane(main.changeEvent); - UI.buildSortPane(main.changeSort); + UI.buildSortPane(main.changeSort, CONSTANTS.SORT_TYPES); UI.buildRoundsPane(main.changeRound); }, @@ -49,12 +51,12 @@ const main = { const rounds = main.getRounds(state.eventKey); UI.updateEventsPane(state.eventKey); - UI.updateRoundsPane(rounds); - // UI.updateSortPane(state.sort); + // UI.updateRoundsPane(rounds); + UI.updateSortPane(state.sort); const matrix = Matrices.buildMatrix(main.json, state.eventKey); Diagram.clear(); - Diagram.build(main.json, state.eventKey, matrix); + Diagram.build(main.json, state.eventKey, state.sort, CONSTANTS.SORT_TYPES, matrix); }, initJSON: (strData) => { @@ -75,20 +77,37 @@ const main = { }, {}); }, + initState: () => { + const state = main.getState(); + + if (state.eventKey === undefined) { + state.eventKey = "1930"; + } + + if (state.sort === undefined) { + state.sort = null; + } + + if (state.rounds === undefined) { + } + + main.setState(state); + }, + setState: (next) => { const prev = main.getState(); const url = window.location.href.split('?')[0]; const eventKey = next.eventKey || prev.eventKey; - const round = next.round || prev.round || null; + const rounds = next.rounds || prev.rounds || null; const sort = next.sort || prev.sort || null; - history.pushState(null, null, `${url}?eventKey=${eventKey}&sort=${sort}&round=${round}`); + history.pushState(null, null, `${url}?eventKey=${eventKey}&sort=${sort}&rounds=${rounds}`); }, } fetch('worldcup.json') .then(main.initJSON) - .then(main.setState.call(null, { sort: null, eventKey: "1930" })) + .then(main.initState) .then(main.generateUI) .then(main.updateUI); diff --git a/js/ui.js b/js/ui.js index e179b34..8bd1d5f 100644 --- a/js/ui.js +++ b/js/ui.js @@ -21,21 +21,24 @@ const UI = { }, findRoot: (node) => { - while (node !== document.body && node.getAttribute(UI.DATA.EVENT) === null) { + while (node !== document.body && node.getAttribute(UI.DATA.ROOT) === null) { node = node.parentNode; } return node; }, - updateEventsPane: (eventKey) => { - const events = document.querySelectorAll(`.${UI.CLASSNAMES.EVENT.ITEM}`); - - events.forEach(node => { + clearActive: (nodes) => { + nodes.forEach(node => { const classes = node.className.split(' '); classes.splice(1, classes.indexOf('active')); node.className = classes.join(' '); }); + }, + + updateEventsPane: (eventKey) => { + const eventItems = document.querySelectorAll(`.${UI.CLASSNAMES.EVENT.ITEM}`); + UI.clearActive(eventItems); const activeEventNode = document.querySelector(`[${UI.DATA.EVENT}="${eventKey}"`); activeEventNode.className += ' active'; @@ -43,29 +46,16 @@ const UI = { updateRoundsPane: (rounds) => { const roundsDiv = document.querySelector('.rounds'); + }, - while (roundsDiv.hasChildNodes()) { - roundsDiv.firstChild.remove(); - } - - console.warn(rounds) - - rounds.forEach(round => { - const item = document.createElement('div'); - item.className = 'round-item'; - item.setAttribute('data-round-id', round.roundId); - - const hide = document.createElement('div'); - hide.className = 'round-hide'; - hide.innerHTML = 'hide'; - - const text = document.createElement('div'); - text.className = 'round-text'; - text.innerHTML = round.roundName; + updateSortPane: (sort) => { + const sortItems = document.querySelectorAll('.sort-item'); + UI.clearActive(sortItems); - item.appendChild(text); - item.appendChild(hide); - roundsDiv.appendChild(item); + sortItems.forEach(node => { + if (node.getAttribute(UI.DATA.SORT) === sort) { + node.className += ' active'; + } }); }, @@ -106,15 +96,17 @@ const UI = { const flagIcon = document.createElement('div'); item.className = UI.CLASSNAMES.EVENT.ITEM; - year.className = UI.CLASSNAMES.EVENT.YEAR; - location.className = UI.CLASSNAMES.EVENT.LOCATION; - flag.className = UI.CLASSNAMES.EVENT.FLAG; - 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; + + location.className = UI.CLASSNAMES.EVENT.LOCATION; location.innerHTML = evt.location; + + flag.className = UI.CLASSNAMES.EVENT.FLAG; flagIcon.className = `flag-icon flag-icon-${evt.icon}`; flag.appendChild(flagIcon); @@ -126,12 +118,12 @@ const UI = { }); }, - buildSortPane: (onClick) => { + buildSortPane: (onClick, SORT_TYPES) => { const sortList = [ { text: 'Order by continent', value: null }, - { text: 'Order by goals scored', value: 'goals-scored' }, - { text: 'Order by country name', value: 'country-name' }, - { text: 'Order by country population', value: 'country-population' }, + { text: 'Order by goals scored', value: SORT_TYPES.GOALS }, + { text: 'Order by country name', value: SORT_TYPES.COUNTRY }, + { text: 'Order by country population', value: SORT_TYPES.POPULATION }, ]; const sortDiv = document.querySelector('.sort'); @@ -147,6 +139,8 @@ const UI = { item.className = UI.CLASSNAMES.SORT.ITEM; item.addEventListener('click', onClick); item.setAttribute(UI.DATA.SORT, sort.value); + item.setAttribute(UI.DATA.ROOT, true); + item.addEventListener('click', onClick); text.className = UI.CLASSNAMES.SORT.TEXT; text.innerHTML = sort.text; @@ -157,36 +151,29 @@ const UI = { }, buildRoundsPane: (onClick) => { - //
- //
Round Robin
- //
Hide
- //
+ // const roundsDiv = document.querySelector('.rounds'); // - //
- //
Round of 16
- //
Hide
- //
+ // while (roundsDiv.hasChildNodes()) { + // roundsDiv.firstChild.remove(); + // } // - //
- //
Quarterfinals
- //
Hide
- //
+ // rounds.forEach(round => { + // const item = document.createElement('div'); + // item.className = 'round-item'; + // item.setAttribute('data-round-id', round.roundId); // - //
- //
Semifinals
- //
Hide
- //
+ // const hide = document.createElement('div'); + // hide.className = 'round-hide'; + // hide.innerHTML = 'hide'; // - //
- //
Third Place
- //
Hide
- //
+ // const text = document.createElement('div'); + // text.className = 'round-text'; + // text.innerHTML = round.roundName; // - //
- //
Final
- //
Hide
- //
- + // item.appendChild(text); + // item.appendChild(hide); + // roundsDiv.appendChild(item); + // }); }, getRoundName: (name) => { diff --git a/res/events.css b/res/events.css index ddb26de..9621302 100644 --- a/res/events.css +++ b/res/events.css @@ -8,8 +8,11 @@ } .event-item { - background: #CBFFC0; - border-radius: 0 16px 16px 0; + /*background: #CBFFC0;*/ + border-color: #fff; + /*border-radius: 0 16px 16px 0;*/ + border-style: solid; + border-width: 1px 0; cursor: pointer; filter: grayscale(100%); height: 24px; @@ -21,6 +24,8 @@ .event-item.active, .event-item.active:hover { + background: #fdfdfd; + border-color: #aaa; filter: grayscale(0%); opacity: 1; } diff --git a/res/sort.css b/res/sort.css index 9b51453..ecbe3c6 100644 --- a/res/sort.css +++ b/res/sort.css @@ -10,6 +10,17 @@ .sort-item { border: 1px solid brickred; + cursor: pointer; + font-size: 13px; + line-height: 34px; +} + +.sort-item:hover { + background: yellow; +} + +.sort-item.active { + background: red; } .sort-text {