diff --git a/index.html b/index.html
index 2b804c7..143d13d 100644
--- a/index.html
+++ b/index.html
@@ -29,6 +29,9 @@ body {
+
+
+
@@ -201,6 +204,9 @@ body {
+
+
Sort By Country Population
+
@@ -208,200 +214,6 @@ body {
-
-
-
Lessons learned
scaleOrdinal vs scaleLinear (only 2 colors!) vs interpolateCool vs d3.schemeColor20c
diff --git a/js/diagram.js b/js/diagram.js
new file mode 100644
index 0000000..94c8472
--- /dev/null
+++ b/js/diagram.js
@@ -0,0 +1,104 @@
+const Diagram = {
+ build: (eventIndex, data, 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,
+ innerRadius = outerRadius - outerArcThickness;
+
+ const chord = d3.chord()
+ .padAngle(0.05);
+
+ const arc = d3.arc()
+ .innerRadius(innerRadius)
+ .outerRadius(outerRadius);
+
+ const ribbon = d3.ribbon()
+ .radius(innerRadius);
+
+ // 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 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")
+ .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
+ .datum(chord(chordMatrix));
+
+ const 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)
+ .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")
+ .attr("transform", function(d) {
+ return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ + "translate(" + (innerRadius + 26) + ")"
+ + (d.angle > Math.PI ? "rotate(180)" : "");
+ })
+ .style("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
+ .text(function(d) {
+ // SORT BY GOALS SCORED
+ // SORT BY ALPHABETICAL
+ // SORT BY COUNTRY SIZE
+ // SORT BY COUNTRY POPULATION
+ // 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;
+ });
+ },
+};
+
+// 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/main.js b/js/main.js
new file mode 100644
index 0000000..b33e913
--- /dev/null
+++ b/js/main.js
@@ -0,0 +1,19 @@
+const 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();
+});
+
+const main = function(strData) {
+ const json = JSON.parse(strData);
+ const metaMatrix = Matrices.buildMetaMatrix(json, "1930");
+ const chordMatrix = Matrices.buildChordMatrix(json, "1930");
+ Diagram.build("1930", json, metaMatrix, chordMatrix);
+}
+
+fetch('worldcup.json').then(main);
diff --git a/js/matrices.js b/js/matrices.js
new file mode 100644
index 0000000..5ac920f
--- /dev/null
+++ b/js/matrices.js
@@ -0,0 +1,39 @@
+const Matrices = {
+ // A x A array of nulls; null-null relationships are omitted in chord diagram.
+ createEmptyMatrix: (len) => {
+ const empty = Array.apply(null, Array(len));
+ return empty.map(() => empty.map(() => null));
+ },
+
+ // Identical structure of chord matrix but with { game, team }.
+ buildMetaMatrix: (json, eventKey) => {
+ const teams = json.tourneys[eventKey].teams;
+ const matrix = Matrices.createEmptyMatrix(teams.length);
+
+ json.tourneys[eventKey].games.forEach(g => {
+ const i1 = teams.indexOf(g.t1);
+ const i2 = teams.indexOf(g.t2);
+
+ matrix[i1][i2] = { game: g, team: g.t1 };
+ matrix[i2][i1] = { game: g, team: g.t2 };
+ }, []);
+
+ return matrix;
+ },
+
+ // Scalar data points (sum of goals scored).
+ buildChordMatrix: (json, eventKey) => {
+ const teams = json.tourneys[eventKey].teams;
+ const matrix = Matrices.createEmptyMatrix(teams.length);
+
+ json.tourneys[eventKey].games.forEach(g => {
+ const i1 = teams.indexOf(g.t1);
+ const i2 = teams.indexOf(g.t2);
+
+ matrix[i1][i2] = g.s1 + g.se1 + g.sp1;
+ matrix[i2][i1] = g.s2 + g.se2 + g.sp2;
+ }, []);
+
+ return matrix;
+ },
+};
diff --git a/js/ui.js b/js/ui.js
new file mode 100644
index 0000000..88fb315
--- /dev/null
+++ b/js/ui.js
@@ -0,0 +1,2 @@
+const UI = {
+};