diff --git a/hw2/.idea/workspace.xml b/hw2/.idea/workspace.xml index 604152d..504645f 100644 --- a/hw2/.idea/workspace.xml +++ b/hw2/.idea/workspace.xml @@ -1,9 +1,7 @@ - - - + @@ -17,12 +15,12 @@ - - + + - + @@ -79,7 +77,7 @@ - + @@ -210,11 +208,12 @@ + - @@ -228,7 +227,7 @@ - + @@ -240,7 +239,7 @@ - + @@ -311,7 +310,7 @@ - + diff --git a/hw3.zip b/hw3.zip new file mode 100644 index 0000000..c268d42 Binary files /dev/null and b/hw3.zip differ diff --git a/hw3/.idea/workspace.xml b/hw3/.idea/workspace.xml index ba29064..04c2d2a 100644 --- a/hw3/.idea/workspace.xml +++ b/hw3/.idea/workspace.xml @@ -2,13 +2,15 @@ - - + + + - - + + - - - - - - - - - - - + + + @@ -91,7 +85,6 @@ @@ -108,11 +101,24 @@ - + + + + + + + + + + + + + + @@ -124,8 +130,6 @@ + + + + + + + + + + + + + + +
+

World Map

+ + + + Host + + Participant + + Winner + + Runner-Up + + + + + + +
+ + + + diff --git a/hw4/js/barChart.js b/hw4/js/barChart.js new file mode 100644 index 0000000..ac6a905 --- /dev/null +++ b/hw4/js/barChart.js @@ -0,0 +1,55 @@ +/** Class implementing the bar chart view. */ +class BarChart { + + /** + * Create a bar chart instance and pass the other views in. + * @param worldMap + * @param infoPanel + * @param allData + */ + constructor(worldMap, infoPanel, allData) { + this.worldMap = worldMap; + this.infoPanel = infoPanel; + this.allData = allData; + } + + /** + * Render and update the bar chart based on the selection of the data type in the drop-down box + */ + updateBarChart(selectedDimension) { + // ******* TODO: PART I ******* + + // Create the x and y scales; make + // sure to leave room for the axes + + + // Create colorScale + + // Create the axes (hint: use #xAxis and #yAxis) + + // Create the bars (hint: use #bars) + + + // ******* TODO: PART II ******* + + // Implement how the bars respond to click events + // Color the selected bar to indicate is has been selected. + // Make sure only the selected bar has this new color. + + // Call the necessary update functions for when a user clicks on a bar. + // Note: think about what you want to update when a different bar is selected. + + } + + /** + * Check the drop-down box for the currently selected data type and update the bar chart accordingly. + * + * There are 4 attributes that can be selected: + * goals, matches, attendance and teams. + */ + chooseData() { + // ******* TODO: PART I ******* + //Changed the selected data when a user selects a different + // menu item from the drop down. + } +} diff --git a/hw4/js/infoPanel.js b/hw4/js/infoPanel.js new file mode 100644 index 0000000..b7bbb1b --- /dev/null +++ b/hw4/js/infoPanel.js @@ -0,0 +1,27 @@ +/** Class implementing the infoPanel view. */ +class InfoPanel { + /** + * Creates a infoPanel Object + */ + constructor() { + } + + /** + * Update the info panel to show info about the currently selected world cup + * @param oneWorldCup the currently selected world cup + */ + updateInfo(oneWorldCup) { + + // ******* TODO: PART III ******* + + // Update the text elements in the infoBox to reflect: + // World Cup Title, host, winner, runner_up, and all participating teams that year + + // Hint: For the list of teams, you can create an list element for each team. + // Hint: Select the appropriate ids to update the text content. + + //Set Labels + + } + +} diff --git a/hw4/js/map.js b/hw4/js/map.js new file mode 100644 index 0000000..bcca145 --- /dev/null +++ b/hw4/js/map.js @@ -0,0 +1,78 @@ +/** Class implementing the map view. */ +class Map { + /** + * Creates a Map Object + */ + constructor() { + this.projection = d3.geoConicConformal().scale(150).translate([400, 350]); + + } + + /** + * Function that clears the map + */ + clearMap() { + + // ******* TODO: PART V******* + // Clear the map of any colors/markers; You can do this with inline styling or by + // defining a class style in styles.css + + // Hint: If you followed our suggestion of using classes to style + // the colors and markers for hosts/teams/winners, you can use + // d3 selection and .classed to set these classes on and off here. + + } + + /** + * Update Map with info for a specific FIFA World Cup + * @param wordcupData the data for one specific world cup + */ + updateMap(worldcupData) { + + //Clear any previous selections; + this.clearMap(); + + // ******* TODO: PART V ******* + + // Add a marker for the winner and runner up to the map. + + // Hint: remember we have a conveniently labeled class called .winner + // as well as a .silver. These have styling attributes for the two + // markers. + + + // Select the host country and change it's color accordingly. + + // Iterate through all participating teams and change their color as well. + + // We strongly suggest using CSS classes to style the selected countries. + + + // Add a marker for gold/silver medalists + } + + /** + * Renders the actual map + * @param the json data with the shape of all countries + */ + drawMap(world) { + + //(note that projection is a class member + // updateMap() will need it to add the winner/runner_up markers.) + + // ******* TODO: PART IV ******* + + // Draw the background (country outlines; hint: use #map). + // You will need to convert the topoJSON file to geoJSON. + // Make sure and add gridlines to the map. + + // Hint: assign an id to each country path to make it easier to select afterwards + // we suggest you use the variable in the data element's .id field to set the id + + // Make sure and give your paths the appropriate class (see the .css selectors at + // the top of the provided html file) + + } + + +} diff --git a/hw4/js/script.js b/hw4/js/script.js new file mode 100644 index 0000000..a0d9145 --- /dev/null +++ b/hw4/js/script.js @@ -0,0 +1,50 @@ + +// Load CSV file +d3.csv("data/fifa-world-cup.csv", function (d) { + // Convert numeric values to 'numbers' + d.year = +d.YEAR; + d.teams = +d.TEAMS; + d.matches = +d.MATCHES; + d.goals = +d.GOALS; + d.avg_goals = +d.AVERAGE_GOALS; + d.attendance = +d.AVERAGE_ATTENDANCE; + // Lat and Lons of gold and silver medals teams + d.win_pos = [+d.WIN_LON, +d.WIN_LAT]; + d.ru_pos = [+d.RUP_LON, +d.RUP_LAT]; + + //Break up lists into javascript arrays + d.teams_iso = d3.csvParse(d.TEAM_LIST).columns; + d.teams_names = d3.csvParse(d.TEAM_NAMES).columns; + return d; +}).then(function(allData) { + + /* Create infoPanel, barChart and Map objects */ + let infoPanel = new InfoPanel(); + let worldMap = new Map(); + + /* DATA LOADING */ + //Load in json data to make map + d3.json("data/world.json") + .then(function(world) { + worldMap.drawMap(world); + }); + + // Define this as a global variable + window.barChart = new BarChart(worldMap, infoPanel, allData); + + // Draw the Bar chart for the first time + barChart.updateBarChart('attendance'); +}); + +/** + * Check the drop-down box for the currently selected data type and update the bar chart accordingly. + * + * There are 4 attributes that can be selected: + * goals, matches, attendance and teams. + */ +function chooseData() { + // ******* TODO: PART I ******* + // Changed the selected data when a user selects a different + // menu item from the drop down. + +} diff --git a/hw4/styles.css b/hw4/styles.css new file mode 100644 index 0000000..7a4e325 --- /dev/null +++ b/hw4/styles.css @@ -0,0 +1,146 @@ + +.countries { + stroke: #f7f7f7; + fill: #d9d9d9; +} + +.legend-element { + width: 15px; + height: 15px; +} + +.team { + fill: #fee8c8; +} + +.team-html { + background-color: #fee8c8; +} + +.host { + fill: #2b8cbe; +} + +.gold { + fill: #FFD700; + opacity: .8; + stroke: #252525; + stroke-width: 2px; +} + +.silver { + fill: #d9d9d9; + opacity: .8; + stroke: #252525; +} + +.selected { + fill: #d20a11; +} + +/*Map grid style*/ +.grat { + stroke: grey; + stroke-width: 1px; + opacity: .2; +} + +@font-face { + font-family: 'font2'; + src: url('assets/font2.ttf'); +} + +@font-face { + font-family: 'font1'; + src: url('assets/font1.ttf'); +} + +h1 { + margin-top: 0; + font-family: 'font2'; + color: #d20a11; +} + +h2 { + font-family: 'font2'; + color: #d20a11; + padding-bottom: 0; + margin-top: 3px; + margin-bottom: 0; +} + +h3 { + padding-bottom: 0px; + margin-bottom: 0px; +} + +* { + font-family: 'font1'; +} + +header { + padding: 0.5em; + clear: left; + text-align: left; + height: 100px; +} + +#logo { + float: right; + height: 100px; +} + + +#plot-selector { + float: right; + margin-bottom: 5px; + +} + +.view { + padding: 0.5em; + +} + + +#details { + width: 200px; + padding: 0.5em; + float: left; + + border-width: 1px; + border-color: #d9d9d9; + border-right-style: solid; +} + +#bar-chart { + width: 500px; + margin-right: 20px; + float: left; + +} + +#map-view { + margin-left: 750px; + width: 910px; + border-width: 1px; + border-color: #d9d9d9; + border-left-style: solid; +} + + +#links > line { + stroke: rgb(216, 216, 216); +} + +#xAxis path, +#yAxis path { + fill: none; + stroke: black; +} + +#xAxis text, +#yAxis text { + font-size: 14px; + +} \ No newline at end of file diff --git a/hw4/topojson.min.js b/hw4/topojson.min.js new file mode 100644 index 0000000..b5ae0b3 --- /dev/null +++ b/hw4/topojson.min.js @@ -0,0 +1 @@ +!function(){var m={version:"1.6.19",mesh:function(t){return q(t,l.apply(this,arguments))},meshArcs:l,merge:function(t){return q(t,o.apply(this,arguments))},mergeArcs:o,feature:s,neighbors:k,presimplify:d};function a(A,t){var u={},v={},w={},x=[],B=-1;t.forEach(function(F,C){var E=A.arcs[F<0?~F:F],D;if(E.length<3&&!E[1][0]&&!E[1][1]){D=t[++B],t[B]=F,t[C]=D}});t.forEach(function(F){var I=y(F),J=I[0],D=I[1],H,G;if(H=w[J]){delete w[H.end];H.push(F);H.end=D;if(G=v[D]){delete v[G.start];var C=G===H?H:H.concat(G);v[C.start=H.start]=w[C.end=G.end]=C}else{v[H.start]=w[H.end]=H}}else{if(H=v[D]){delete v[H.start];H.unshift(F);H.start=J;if(G=w[J]){delete w[G.end];var E=G===H?H:G.concat(H);v[E.start=G.start]=w[E.end=H.end]=E}else{v[H.start]=w[H.end]=H}}else{H=[F];v[H.start=J]=w[H.end=D]=H}}});function y(D){var C=A.arcs[D<0?~D:D],F=C[0],E;if(A.transform){E=[0,0],C.forEach(function(G){E[0]+=G[0],E[1]+=G[1]})}else{E=C[C.length-1]}return D<0?[E,F]:[F,E]}function z(D,F){for(var C in D){var E=D[C];delete F[E.start];delete E.start;delete E.end;E.forEach(function(G){u[G<0?~G:G]=1});x.push(E)}}z(w,v);z(v,w);t.forEach(function(C){if(!u[C<0?~C:C]){x.push([C])}});return x}function l(E,w,u){var t=[];if(arguments.length>1){var z=[],B;function v(H){var G=H<0?~H:H;(z[G]||(z[G]=[])).push({i:H,g:B})}function F(G){G.forEach(v)}function C(G){G.forEach(F)}function A(G){if(G.type==="GeometryCollection"){G.geometries.forEach(A)}else{if(G.type in D){B=G,D[G.type](G.arcs)}}}var D={LineString:F,MultiLineString:C,Polygon:C,MultiPolygon:function(G){G.forEach(C)}};A(w);z.forEach(arguments.length<3?function(G){t.push(G[0].i)}:function(G){if(u(G[0].g,G[G.length-1].g)){t.push(G[0].i)}})}else{for(var y=0,x=E.arcs.length;y0}t.forEach(function(C){if(!C._){var A=[],B=[C];C._=1;v.push(A);while(C=B.pop()){A.push(C);C.forEach(function(D){D.forEach(function(E){w[E<0?~E:E].forEach(function(F){if(!F._){F._=1;B.push(F)}})})})}}});t.forEach(function(A){delete A._});return{type:"MultiPolygon",arcs:v.map(function(A){var D=[];A.forEach(function(F){F.forEach(function(G){G.forEach(function(H){if(w[H<0?~H:H].length<2){D.push(H)}})})});D=a(z,D);if((n=D.length)>1){var E=x(A[0][0]);for(var C=0,B;C>>1;if(u[v]0){y=x[v],w(x[y._=0]=y,0)}return z};u.remove=function(A){var z=A._,y;if(x[z]!==A){return}if(z!==--v){y=x[v],(r(y,A)<0?t:w)(x[y._=z]=y,z)}return z};function t(z,A){while(A>0){var y=((A+1)>>1)-1,B=x[y];if(r(z,B)>=0){break}x[B._=A]=B;x[z._=A=y]=z}}function w(A,B){while(true){var C=(B+1)<<1,y=C-1,z=B,D=x[z];if(y