From 1e2ecb4bd9794d21e954c9867834295feec12e25 Mon Sep 17 00:00:00 2001 From: Ben Burlingham Date: Sun, 23 Oct 2016 18:29:05 -0700 Subject: [PATCH] Chord swap function constructed. --- index.html | 14 ++-- js/diagram.js | 189 ++++++++++++++++++++++++++++++++++++++----------- js/matrices.js | 4 +- 3 files changed, 160 insertions(+), 47 deletions(-) diff --git a/index.html b/index.html index 2d52acd..53b98ae 100644 --- a/index.html +++ b/index.html @@ -104,18 +104,24 @@ body {
-
Sort By Country Name
+
Order By Country Name
-
Sort By Goals Scored
+
Order By Continent Name
-
Sort By Country Population
+
Order By Country Population
+
+
+
Order By Goals For
+
+
+
Order By Goals Against
- +
diff --git a/js/diagram.js b/js/diagram.js index f2b5285..75aa163 100644 --- a/js/diagram.js +++ b/js/diagram.js @@ -1,18 +1,131 @@ const Diagram = { - // clear: () => d3.select('svg').remove(), 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() + // + // sortKey = "goalsFor" + // + // switch (sortKey) { + // case 'goalsFor': + // // console.info(json.tourneys[eventKey].teams)/ + // // return json.tourneys[eventKey].teams; + // + // const teams = json.tourneys[eventKey].teams + // .slice() + // .sort((a, b) => { + // const n1 = json.countries[json.teams[a]].n; + // const n2 = json.countries[json.teams[b]].n; + // + // if (n1 < n2) { + // return -1; + // } + // else if (n1 > n2) { + // return 1; + // } + // + // return 0; + // }); + // + // console.warn(teams.map(v => { + // return json.countries[json.teams[v]].n + // })) + // + // // console.warn(teams.map(a => json.countries[json.teams[a]].n)) + // + // return teams; + // break; + // + // case 'goalsAgainst': + // break; + // + // case 'countryName': + // break; + // + // case 'countryPopulation': + // break; + // } + }, + build: (data, eventIndex, metaMatrix, chordMatrix) => { const svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), outerArcThickness = 5, - outerRadius = Math.min(width, height) * 0.5 - 100, + outerRadius = Math.min(width, height) * 0.5 - 125, innerRadius = outerRadius - outerArcThickness; const chord = d3.chord() .padAngle(0.05); + const sortedChords = Diagram.sort(chord(chordMatrix)); + const arc = d3.arc() .innerRadius(innerRadius) .outerRadius(outerRadius); @@ -35,46 +148,46 @@ const Diagram = { const g = svg.append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") - .datum(chord(chordMatrix)); + .datum(sortedChords); const group = g.append("g") .attr("class", "groups") .selectAll("g") - .data(function(chords) { return chords.groups; }) + .data(chords => 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(); }) + .style("fill", d => color(d.index)) + .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; }) @@ -92,15 +205,9 @@ const Diagram = { // COLOR BY CONTINENT // STRANGE EXTENDED TIME CHILE-BRAZIL - FIX BY HAND? IS BECAUE se1 IS SCORE __GOING INTO__ EXTENDED TIME // console.info(metaMatrix[d.index]) + const t = data.tourneys[eventIndex].teams[d.index]; - const c = data.countries[data.teams[t]]; - return data.countries[data.teams[t]].n; + return data.countries[data.teams[t]].n + ' ' + d.index; }); }, }; - -// const main = (data) => { -// const lookup = buildLookup(endpoints, data); -// const chordMatrix = buildChordMatrix(lookup.games, lookup.reducedTeams) -// const metaMatrix = buildMetaMatrix(lookup.games, lookup.reducedTeams) -// }; diff --git a/js/matrices.js b/js/matrices.js index 5ac920f..df0e146 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; + const teams = json.tourneys[eventKey].teams.sort(); 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; + const teams = json.tourneys[eventKey].teams.sort(); const matrix = Matrices.createEmptyMatrix(teams.length); json.tourneys[eventKey].games.forEach(g => {