From d21b3022f94f7c2b2956db0b27e07920bd36a2b7 Mon Sep 17 00:00:00 2001 From: Ben Burlingham Date: Wed, 26 Oct 2016 19:38:26 -0700 Subject: [PATCH] Sorting by country name complete. --- index.html | 1 + js/diagram.js | 157 ++++++++++++++++++------------------------------- js/matrices.js | 12 +++- js/sorter.js | 38 ++++++++++++ 4 files changed, 107 insertions(+), 101 deletions(-) create mode 100644 js/sorter.js diff --git a/index.html b/index.html index 53b98ae..56a4a54 100644 --- a/index.html +++ b/index.html @@ -32,6 +32,7 @@ body { + diff --git a/js/diagram.js b/js/diagram.js index 67e71a6..f0bcd7c 100644 --- a/js/diagram.js +++ b/js/diagram.js @@ -1,72 +1,10 @@ +const goalsFor = {}; +const goalsAgainst = {}; + const Diagram = { clear: () => d3.select('svg').selectAll("*").remove(), - swap: (i, j) => { - const fst = Object.assign({}, chords.groups[i]); - const snd = Object.assign({}, chords.groups[j]); - - // Calculate and apply offsets for adjacent group arcs. - deltaFst = snd.endAngle - fst.endAngle; - deltaSnd = snd.startAngle - fst.startAngle - - chords.groups[i].startAngle += deltaFst; - chords.groups[i].endAngle += deltaFst; - - chords.groups[j].startAngle -= deltaSnd; - chords.groups[j].endAngle -= deltaSnd; - - // Apply offsets to relevant chords. - chords.forEach((v,i) => { - const sourceProps = {}; - const targetProps = {} - - // Adjust source and target arcs for first index. - if (v.source.index === fst.index) { - sourceProps.index = snd.index; - sourceProps.startAngle = v.source.startAngle + deltaFst; - sourceProps.endAngle = v.source.endAngle + deltaFst; - } - - if (v.target.index === fst.index) { - targetProps.index = snd.index; - targetProps.startAngle = v.target.startAngle + deltaFst; - targetProps.endAngle = v.target.endAngle + deltaFst; - } - - if (v.source.subindex === fst.index) { - sourceProps.subindex = snd.index; - } - - if (v.target.subindex === fst.index) { - targetProps.subindex = snd.index; - } - - // Adjust source and target arcs for second index. - if (v.source.index === snd.index) { - sourceProps.index = fst.index; - sourceProps.startAngle = v.source.startAngle - deltaSnd; - sourceProps.endAngle = v.source.endAngle - deltaSnd; - } - - if (v.target.index === snd.index) { - targetProps.index = fst.index; - targetProps.startAngle = v.target.startAngle - deltaSnd; - targetProps.endAngle = v.target.endAngle - deltaSnd; - } - - if (v.source.subindex === snd.index) { - sourceProps.subindex = fst.index; - } - - if (v.target.subindex === snd.index) { - targetProps.subindex = fst.index; - } - - Object.assign(v.source, sourceProps) - Object.assign(v.target, targetProps) - }); - return chords; // // json.tourneys[eventKey].teams.sort() // @@ -112,7 +50,7 @@ const Diagram = { // break; // } - swap: (chords, i, j) => { + swapGroupArcs: (chords, i, j) => { if (i < 0 || j < 0 || i === j) { return chords; } @@ -131,12 +69,12 @@ const Diagram = { // Bring first forward. chords.groups[f].startAngle = snd.endAngle - fstAngle; chords.groups[f].endAngle = snd.endAngle; - // chords.groups[f].index = snd.index; + 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; + chords.groups[s].index = fst.index; // Bump other groups forward. for (let ii = f + 1; ii < s; ii++) { @@ -152,6 +90,23 @@ const Diagram = { return chords; }, + swapGroups: (data, eventIndex, chords, i, j) => { + Diagram.swapGroupArcs(chords, i, j); + Matrices.swapIndices(data.tourneys[eventIndex].teams, i, j); + return chords; + }, + + getCountryName: (data, eventIndex, n) => { + const countryId = data.teams[data.tourneys[eventIndex].teams[n]]; + return data.countries[countryId].n; + }, + + // getGoalsFor: (data, eventIndex, n) => { + // data.tourneys[eventIndex].games.reduce( + // + // return Math.round(100 * Math.random); + // }, + build: (data, eventIndex, metaMatrix, chordMatrix) => { const svg = d3.select("svg"), width = +svg.attr("width"), @@ -160,10 +115,14 @@ const Diagram = { outerRadius = Math.min(width, height) * 0.5 - 125, innerRadius = outerRadius - outerArcThickness; - const chord = d3.chord() - .padAngle(0.05); + const chords = d3.chord() + .padAngle(0.05) + .call(null, chordMatrix); - const sortedChords = Diagram.sort(chord(chordMatrix)); + const sortedChords = Sorter.sort(chords, 0, chords.groups.length - 1, + Diagram.getCountryName.bind(null, data, eventIndex), + // Diagram.getGoalsFor.bind(null, data, eventIndex), + Diagram.swapGroups.bind(null, data, eventIndex)); const arc = d3.arc() .innerRadius(innerRadius) @@ -200,34 +159,34 @@ const Diagram = { .style("stroke", d => 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) - .style("fill", function(d) { return color(d.target.index); }) - .style("stroke", function(d) { return d3.rgb(color(d.target.index)).darker(); }) - .attr("class", "ribbon") - // .append("title") - // .text(function(d) { - // const meta1 = metaMatrix[d.target.index][d.source.index]; - // const meta2 = metaMatrix[d.source.index][d.target.index]; - // - // const g = meta1.game; - // - // const t1 = lookup.teams[g.t1]; - // const t2 = lookup.teams[g.t2]; - // - // const e1 = g.s1e ? `(+${g.s1e} in extended time)` : ''; - // const e2 = g.s2e ? `(+${g.s2e} in extended time)` : ''; - // - // const p1 = g.s1p ? `(+${g.s1p} in penalties)` : ''; - // const p2 = g.s2p ? `(+${g.s2p} in penalties)` : ''; - // - // return `${t1}: ${g.s1} ${e1} ${p1}\n${t2}: ${g.s2} ${e2} ${p2}`; - // }); - + // g.append("g") + // .attr("class", "ribbons") + // .selectAll("path") + // .data(function(chords) { return chords; }) + // .enter().append("path") + // .attr("d", ribbon) + // .style("fill", function(d) { return color(d.target.index); }) + // .style("stroke", function(d) { return d3.rgb(color(d.target.index)).darker(); }) + // .attr("class", "ribbon") + // // .append("title") + // // .text(function(d) { + // // const meta1 = metaMatrix[d.target.index][d.source.index]; + // // const meta2 = metaMatrix[d.source.index][d.target.index]; + // // + // // const g = meta1.game; + // // + // // const t1 = lookup.teams[g.t1]; + // // const t2 = lookup.teams[g.t2]; + // // + // // const e1 = g.s1e ? `(+${g.s1e} in extended time)` : ''; + // // const e2 = g.s2e ? `(+${g.s2e} in extended time)` : ''; + // // + // // const p1 = g.s1p ? `(+${g.s1p} in penalties)` : ''; + // // const p2 = g.s2p ? `(+${g.s2p} in penalties)` : ''; + // // + // // return `${t1}: ${g.s1} ${e1} ${p1}\n${t2}: ${g.s2} ${e2} ${p2}`; + // // }); + // group.append("text") .each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; }) .attr("dy", ".35em") diff --git a/js/matrices.js b/js/matrices.js index df0e146..795f32e 100644 --- a/js/matrices.js +++ b/js/matrices.js @@ -7,7 +7,7 @@ const Matrices = { // Identical structure of chord matrix but with { game, team }. buildMetaMatrix: (json, eventKey) => { - const teams = json.tourneys[eventKey].teams.sort(); + const teams = json.tourneys[eventKey].teams; const matrix = Matrices.createEmptyMatrix(teams.length); json.tourneys[eventKey].games.forEach(g => { @@ -23,7 +23,7 @@ const Matrices = { // Scalar data points (sum of goals scored). buildChordMatrix: (json, eventKey) => { - const teams = json.tourneys[eventKey].teams.sort(); + const teams = json.tourneys[eventKey].teams; const matrix = Matrices.createEmptyMatrix(teams.length); json.tourneys[eventKey].games.forEach(g => { @@ -36,4 +36,12 @@ const Matrices = { return matrix; }, + + swapIndices: (arr, i, j) => { + const tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + + return arr; + }, }; diff --git a/js/sorter.js b/js/sorter.js new file mode 100644 index 0000000..727687c --- /dev/null +++ b/js/sorter.js @@ -0,0 +1,38 @@ +const Sorter = { + sort: function(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; + } + + this.sort(chords, start, right, getVal, swap); + this.sort(chords, left, end, getVal, swap); + + return chords; + } +};