diff --git a/hw6/.idea/workspace.xml b/hw6/.idea/workspace.xml
index 194178a..108f9c7 100644
--- a/hw6/.idea/workspace.xml
+++ b/hw6/.idea/workspace.xml
@@ -5,14 +5,6 @@
-
-
-
-
-
-
-
-
@@ -39,28 +31,28 @@
-
+
-
+
-
+
-
+
@@ -89,8 +81,8 @@
-
-
+
+
@@ -98,17 +90,35 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -116,17 +126,17 @@
-
-
+
+
-
+
-
-
+
+
@@ -142,8 +152,11 @@
electionResultgSvg'r'
- selectedi
+ selected
+ democrat
+ text
+ (d
@@ -154,10 +167,10 @@
+
-
@@ -190,6 +203,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -220,6 +244,11 @@
+
+
+
+
+
-
+
@@ -262,13 +291,9 @@
-
-
-
-
-
+
@@ -276,6 +301,10 @@
+
+
+
+
@@ -287,6 +316,18 @@
+
+
+
+
+ file://$PROJECT_DIR$/public/js/electoralVoteChart.js
+ 124
+
+
+
+
+
+
@@ -301,38 +342,52 @@
-
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hw6/public/js/electoralVoteChart.js b/hw6/public/js/electoralVoteChart.js
index 2262435..d7e9db3 100644
--- a/hw6/public/js/electoralVoteChart.js
+++ b/hw6/public/js/electoralVoteChart.js
@@ -1,303 +1,186 @@
class ElectoralVoteChart {
- /**
- * Constructor for the ElectoralVoteChart
- *
- * @param shiftChart an instance of the ShiftChart class
- */
- constructor (shiftChart){
- this.shiftChart = shiftChart;
-
- this.margin = {top: 30, right: 20, bottom: 30, left: 50};
- let divelectoralVotes = d3.select("#electoral-vote").classed("content", true);
+ /**
+ * Constructor for the ElectoralVoteChart
+ *
+ * @param shiftChart an instance of the ShiftChart class
+ */
+ constructor (shiftChart){
+ this.shiftChart = shiftChart;
- //Gets access to the div element created for this chart from HTML
- this.svgBounds = divelectoralVotes.node().getBoundingClientRect();
- this.svgWidth = this.svgBounds.width - this.margin.left - this.margin.right;
- this.svgHeight = 150;
+ this.margin = {top: 30, right: 20, bottom: 30, left: 50};
+ let divelectoralVotes = d3.select("#electoral-vote").classed("content", true);
- //creates svg element within the div
- this.svg = divelectoralVotes.append("svg")
- .attr("width",this.svgWidth)
- .attr("height",this.svgHeight)
- ;
+ //Gets access to the div element created for this chart from HTML
+ this.svgBounds = divelectoralVotes.node().getBoundingClientRect();
+ this.svgWidth = this.svgBounds.width - this.margin.left - this.margin.right;
+ this.svgHeight = 150;
- };
+ //creates svg element within the div
+ this.svg = divelectoralVotes.append("svg")
+ .attr("width",this.svgWidth)
+ .attr("height",this.svgHeight)
+ ;
- /**
- * Returns the class that needs to be assigned to an element.
- *
- * @param party an ID for the party that is being referred to.
- */
- chooseClass (party) {
- if (party == "R"){
- return "republican";
+ };
+
+ /**
+ * Returns the class that needs to be assigned to an element.
+ *
+ * @param party an ID for the party that is being referred to.
+ */
+ chooseClass (party) {
+ if (party == "R"){
+ return "republican";
+ }
+ else if (party == "D"){
+ return "democrat";
+ }
+ else if (party == "I"){
+ return "independent";
+ }
}
- else if (party == "D"){
- return "democrat";
- }
- else if (party == "I"){
- return "independent";
- }
- }
- /**
- * Creates the stacked bar chart, text content and tool tips for electoral vote chart
- *
- * @param electionResult election data for the year selected
- * @param colorScale global quantile scale based on the winning margin between republicans and democrats
- */
+ /**
+ * Creates the stacked bar chart, text content and tool tips for electoral vote chart
+ *
+ * @param electionResult election data for the year selected
+ * @param colorScale global quantile scale based on the winning margin between republicans and democrats
+ */
- update (electionResult, colorScale){
+ update (electionResult, colorScale){
- // ******* TODO: PART II *******
+ // ******* TODO: PART II *******
- //Group the states based on the winning party for the state;
- //then sort them based on the margin of victory
+ //Group the states based on the winning party for the state;
+ //then sort them based on the margin of victory
- //Create the stacked bar chart.
- //Use the global color scale to color code the rectangles.
- //HINT: Use .electoralVotes class to style your bars.
+ //Create the stacked bar chart.
+ //Use the global color scale to color code the rectangles.
+ //HINT: Use .electoralVotes class to style your bars.
- //Display total count of electoral votes won by the Democrat and Republican party
- //on top of the corresponding groups of bars.
- //HINT: Use the .electoralVoteText class to style your text elements; Use this in combination with
- // chooseClass to get a color based on the party wherever necessary
+ //Display total count of electoral votes won by the Democrat and Republican party
+ //on top of the corresponding groups of bars.
+ //HINT: Use the .electoralVoteText class to style your text elements; Use this in combination with
+ // chooseClass to get a color based on the party wherever necessary
- //Display a bar with minimal width in the center of the bar chart to indicate the 50% mark
- //HINT: Use .middlePoint class to style this bar.
+ //Display a bar with minimal width in the center of the bar chart to indicate the 50% mark
+ //HINT: Use .middlePoint class to style this bar.
- //Just above this, display the text mentioning the total number of electoral votes required
- // to win the elections throughout the country
- //HINT: Use .electoralVotesNote class to style this text element
+ //Just above this, display the text mentioning the total number of electoral votes required
+ // to win the elections throughout the country
+ //HINT: Use .electoralVotesNote class to style this text element
- //HINT: Use the chooseClass method to style your elements based on party wherever necessary.
- let electionArray = d3.nest()
- .key(function(d) {return d["State_Winner"]} )
- .sortValues(function(a,b) {
- return parseFloat(a.RD_Difference) - parseFloat(b.RD_Difference)
- })
- .entries(electionResult)
+ //HINT: Use the chooseClass method to style your elements based on party wherever necessary.
- let statesIArray = [];
- let statesRArray = [];
- let statesDArray = [];
+ this.svg.selectAll("*").remove();
- for(let i=0; i {
+ if(d.RD_Difference < 0) democratParty.push(d);
+ else if (d.RD_Difference > 0) republicanParty.push(d);
+ else independentParty.push(d);
+ })
- if(electionArray[i].key == 'D')
- statesDArray = electionArray[i].values
+ //Sorts group of states based on the margin of victory
+ independentParty.sort((a, b) => b.Total_EV - a.Total_EV);
+ democratParty.sort((a, b) => a.RD_Difference - b.RD_Difference);
+ republicanParty.sort((a, b) => a.RD_Difference - b.RD_Difference);
- }
+ let sortedData = [];
+ sortedData = sortedData.concat(independentParty);
+ sortedData = sortedData.concat(democratParty);
+ sortedData = sortedData.concat(republicanParty);
- let statesArray = []
- statesArray = statesArray.concat(statesIArray)
- statesArray = statesArray.concat(statesDArray)
- statesArray = statesArray.concat(statesRArray)
+ let xCoordinates = [];
+ sortedData.forEach(d => {
+ xCoordinates.push(allVotes);
+ allVotes += parseInt(d.Total_EV);
+ });
- //Create the stacked bar chart.
- //Use the global color scale to color code the rectangles.
- //HINT: Use .electoralVotes class to style your bars.
- var self = this;
+ let electoralVoteScale = d3.scaleLinear()
+ .domain([0, allVotes])
+ .range([0, this.svgWidth]);
- this.xScale = d3.scaleLinear()
- .domain([0, d3.sum(statesArray, d => parseInt(d['Total_EV']))])
- .range([0, self.svgWidth]);
+ //Create the stacked bar chart.
+ let electoralVoteChart = this.svg
+ .selectAll("rect")
+ .data(sortedData)
+ .enter();
- let rectG = this.svg.select('g');
+ electoralVoteChart
+ .append("rect")
+ .attr("width", d => this.svgWidth * d.Total_EV / allVotes)
+ .attr("height", 20)
+ .attr("x", (_, i) => electoralVoteScale(xCoordinates[i]))
+ .attr("y", 50)
+ //Uses the global color scale to color code the rectangles.
+ .attr("fill", d => d.RD_Difference === "0" ? "green" : colorScale(d.RD_Difference))
+ .attr("class", "electoralVotes")
- if(rectG.empty())
- {
- rectG = this.svg.append('g')
- }
+ //Displays the total count of electoral votes won by the Democrat and Republican party
+ //on top of the corresponding groups of bars.
+ electoralVoteChart
+ .append("text")
+ .text(d => d.I_EV_Total)
+ .attr("y", 50)
+ .attr("class", "electoralVoteText independent")
- let statesRect = rectG.selectAll('rect')
- .data(statesArray);
+ electoralVoteChart
+ .append("text")
+ .text(d => d.D_EV_Total)
+ .attr("y", 50)
+ .attr("dx", d => d.I_EV_Total === "" ? 0 : 120)
+ .attr("class", "electoralVoteText democrat")
- statesRect.exit().remove();
- statesRect = statesRect.enter().append('rect').merge(statesRect);
+ electoralVoteChart
+ .append("text")
+ .text(d => d.R_EV_Total)
+ .attr("y", 50)
+ .attr("dx", this.svgWidth)
+ .attr("class", "electoralVoteText republican");
- let votesSeen = 0;
+ //Display a bar with minimal width in the center of the bar chart to indicate the 50% mark
+ electoralVoteChart
+ .append("line")
+ .attr("x1", this.svgWidth/2)
+ .attr("y1", 50)
+ .attr("x2", this.svgWidth/2)
+ .attr("y2", 50)
+ .style("stroke", "black")
+ .style("stroke-width", 2)
+ .attr("class", "middlePoint")
- statesRect
- .attr('x', function(d){
- let x = self.xScale(votesSeen);
- votesSeen = votesSeen + parseInt(d['Total_EV']);
- return x;
- })
- .attr('y', 5*this.svgHeight/8)
- .attr('width', function(d){
- return self.xScale(d['Total_EV'])
- })
- .attr('height', this.svgHeight/4)
- .attr('class', '')
- .attr('fill', function(d){
+ //Displays the text mentioning the total number of electoral votes required
+ // to win the elections throughout the country
+ let votesToWin
+ if (electionResult[0].Year == 1960)
+ votesToWin = 269
+ else if(electionResult[0].Year > 1960)
+ votesToWin = 270
+ else
+ votesToWin = 266
- if(d['State_Winner'] == 'I')
- {
- d3.select(this).attr('class', function(d){
- return self.chooseClass(d["State_Winner"])
- });
- return;
- }
+ electoralVoteChart
+ .append("text")
+ .text(`Electoral Vote (${votesToWin} needed to win)`)
+ .attr('y', 45)
+ .attr("dx", this.svgWidth/2 - 140)
+ .attr("font-size", 16)
- return colorScale(d["RD_Difference"])
- })
- .attr('rd_diff', function(d){
- return d["RD_Difference"];
- })
- .attr('state_winner', function(d){
- return d["State_Winner"];
- })
- .attr('abbr', function(d){
- return d["Abbreviation"];
- })
- .attr('stroke', '#ffffff')
- .attr('stroke-width', 1)
+ //******* TODO: PART V *******
+ //Implement brush on the bar chart created above.
+ //Implement a call back method to handle the brush end event.
+ //Call the update method of shiftChart and pass the data corresponding to brush selection.
+ //HINT: Use the .brush class to style the brush.
- //Display total count of electoral votes won by the Democrat and Republican party
- //on top of the corresponding groups of bars.
- //HINT: Use the .electoralVoteText class to style your text elements; Use this in combination with
- // chooseClass to get a color based on the party wherever necessary
-
- let textDEV = this.svg.selectAll('.electoralVoteText').filter('.democrat')
- .data([d3.sum(statesDArray, d => parseInt(d['D_EV']))])
-
- textDEV = textDEV.enter().append('text').merge(textDEV)
-
- textDEV.classed('electoralVoteText', true)
- .classed('democrat', true)
- .attr('x', 0)
- .attr('y', 5*this.svgHeight/8 - 10)
- .attr('text-anchor', 'start')
- .text(function(d){
- return d;
- })
-
- let textIEV = this.svg.selectAll('.electoralVoteText').filter('.independent')
- .data([d3.sum(statesIArray, d => parseInt(d['I_EV']))])
-
- if(statesIArray.length != 0)
- {
- textDEV.attr('x', this.svgWidth/5).attr('text-anchor', 'end')
-
- textIEV = textIEV.enter().append('text').merge(textIEV)
-
- textIEV.classed('electoralVoteText', true)
- .classed('independent', true)
- .attr('x', 0)
- .attr('y', 5*this.svgHeight/8 - 10)
- .attr('text-anchor', 'start')
- .text(function(d){
- return d;
- })
- }
- else
- {
- textIEV = textIEV.data([]);
- textIEV.exit().remove();
- textIEV.enter().merge(textIEV)
- }
-
- let textREV = this.svg.selectAll('.electoralVoteText').filter('.republican')
- .data([d3.sum(statesRArray, d => parseInt(d['R_EV']))])
-
- textREV = textREV.enter().append('text').merge(textREV)
-
- textREV.classed('electoralVoteText', true)
- .classed('republican', true)
- .attr('x', this.svgWidth)
- .attr('y', 5*this.svgHeight/8 - 10)
- .attr('text-anchor', 'end')
- .text(function(d){
- return d;
- })
-
- //Display a bar with minimal width in the center of the bar chart to indicate the 50% mark
- //HINT: Use .middlePoint class to style this bar.
-
- let evLine = this.svg.selectAll('path');
- if(evLine.empty())
- {
- var data = [[this.svgWidth/2, 5*this.svgHeight/8 - 5], [this.svgWidth/2, 5*this.svgHeight/8 + this.svgHeight/4 + 5]];
-
- var lineGenerator = d3.line();
- var pathString = lineGenerator(data);
-
- this.svg.append('path')
- .attr('d', pathString)
- .attr('stroke-width', '2')
- .attr('stroke', '#000')
- }
-
- //Just above this, display the text mentioning the total number of electoral votes required
- // to win the elections throughout the country
- //HINT: Use .electoralVotesNote class to style this text element
-
- let evText = this.svg.selectAll('.electoralVotesNote')
- .data([d3.sum(statesArray, d => parseInt(d['Total_EV']))])
-
- evText = evText.enter().append('text').merge(evText)
-
- evText.classed('electoralVotesNote', true)
- .attr('x', this.svgWidth/2)
- .attr('y', 5*this.svgHeight/8 - 15)
- .text(function(d){
- let ev = d/2;
- return 'Electoral Vote (' + ev + ' needed to win)';
- })
+ };
- //HINT: Use the chooseClass method to style your elements based on party wherever necessary.
-
- //******* TODO: PART V *******
- //Implement brush on the bar chart created above.
- //Implement a call back method to handle the brush end event.
- //Call the update method of shiftChart and pass the data corresponding to brush selection.
- //HINT: Use the .brush class to style the brush.
-
- let brushed = function() {
- var selection = d3.event.selection;
-
- if(selection == null)
- return;
-
- let selectedStatesArray = new Array();
-
- let selectedStates = statesRect.filter(function(d){
- let currentRect = d3.select(this);
- let x1 = parseInt(currentRect.attr('x'));
- let x2 = x1 + parseInt(currentRect.attr('width'));
- if(x1 > selection[0] && x2 < selection[1])
- {
- selectedStatesArray.push(d);
- return true;
- }
- return false;
- })
-
- console.log(selection)
- console.log(selectedStatesArray)
-
- self.shiftChart.update(selectedStatesArray)
-
- };
-
- var brush = d3.brushX()
- .extent([[0, 5*this.svgHeight/8 - 5], [this.svgWidth, 5*this.svgHeight/8 + this.svgHeight/4 + 5]])
- .on("end", brushed);
-
- rectG.append("g")
- .attr("class", "brush")
- .call(brush)
- };
-
-
}
diff --git a/hw6/public/js/tileChart.js b/hw6/public/js/tileChart.js
index beb10aa..1f60088 100644
--- a/hw6/public/js/tileChart.js
+++ b/hw6/public/js/tileChart.js
@@ -2,172 +2,83 @@
/** Class implementing the tileChart. */
class TileChart {
- /**
- * Initializes the svg elements required to lay the tiles
- * and to populate the legend.
- */
- constructor(tooltip){
+ /**
+ * Initializes the svg elements required to lay the tiles
+ * and to populate the legend.
+ */
+ constructor(tooltip){
- let divTiles = d3.select("#tiles").classed("content", true);
- this.margin = {top: 30, right: 20, bottom: 30, left: 50};
- //Gets access to the div element created for this chart and legend element from HTML
- let svgBounds = divTiles.node().getBoundingClientRect();
- this.svgWidth = svgBounds.width - this.margin.left - this.margin.right;
- this.svgHeight = this.svgWidth/2;
- let legendHeight = 150;
- //add the svg to the div
- let legend = d3.select("#legend").classed("content",true);
+ let divTiles = d3.select("#tiles").classed("content", true);
+ this.margin = {top: 30, right: 20, bottom: 30, left: 50};
+ //Gets access to the div element created for this chart and legend element from HTML
+ let svgBounds = divTiles.node().getBoundingClientRect();
+ this.svgWidth = svgBounds.width - this.margin.left - this.margin.right;
+ this.svgHeight = this.svgWidth/2;
+ let legendHeight = 150;
+ //add the svg to the div
+ let legend = d3.select("#legend").classed("content",true);
- //creates svg elements within the div
- this.legendSvg = legend.append("svg")
- .attr("width",this.svgWidth)
- .attr("height",legendHeight)
- .attr("transform", "translate(" + this.margin.left + ",0)")
- this.svg = divTiles.append("svg")
- .attr("width",this.svgWidth)
- .attr("height",this.svgHeight)
- .attr("transform", "translate(" + this.margin.left + ",0)")
+ //creates svg elements within the div
+ this.legendSvg = legend.append("svg")
+ .attr("width",this.svgWidth)
+ .attr("height",legendHeight)
+ .attr("transform", "translate(" + this.margin.left + ",0)")
+ this.svg = divTiles.append("svg")
+ .attr("width",this.svgWidth)
+ .attr("height",this.svgHeight)
+ .attr("transform", "translate(" + this.margin.left + ",0)")
- this.tooltip = tooltip;
- };
+ this.tooltip = tooltip;
+ };
- /**
- * Returns the class that needs to be assigned to an element.
- *
- * @param party an ID for the party that is being referred to.
- */
- chooseClass (party) {
- if (party == "R"){
- return "republican";
+ /**
+ * Returns the class that needs to be assigned to an element.
+ *
+ * @param party an ID for the party that is being referred to.
+ */
+ chooseClass (party) {
+ if (party == "R"){
+ return "republican";
+ }
+ else if (party== "D"){
+ return "democrat";
+ }
+ else if (party == "I"){
+ return "independent";
+ }
}
- else if (party== "D"){
- return "democrat";
- }
- else if (party == "I"){
- return "independent";
- }
- }
- /**
- * Creates tiles and tool tip for each state, legend for encoding the
- * color scale information.
- *
- * @param electionResult election data for the year selected
- * @param colorScale global quantile scale based on the winning
- * margin between republicans and democrats
- */
- update (electionResult, colorScale){
+ /**
+ * Creates tiles and tool tip for each state, legend for encoding the
+ * color scale information.
+ *
+ * @param electionResult election data for the year selected
+ * @param colorScale global quantile scale based on the winning
+ * margin between republicans and democrats
+ */
+ update (electionResult, colorScale){
- //Calculates the maximum number of rows and columns
- this.maxColumns = d3.max(electionResult, d => +d.Space) + 1;
- this.maxRows = d3.max(electionResult, d => +d.Row) + 1;
+ //Calculates the maximum number of rows and columns
+ this.maxColumns = d3.max(electionResult, d => +d.Space) + 1;
+ this.maxRows = d3.max(electionResult, d => +d.Row) + 1;
- // ******* TODO: PART IV *******
- //Tansform the legend element to appear in the center and make a call to this element for it to display.
+ // ******* TODO: PART IV *******
+ //Tansform the legend element to appear in the center and make a call to this element for it to display.
- //Lay rectangles corresponding to each state according to the 'row' and 'column' information in the data.
+ //Lay rectangles corresponding to each state according to the 'row' and 'column' information in the data.
- //Display the state abbreviation and number of electoral votes on each of these rectangles
+ //Display the state abbreviation and number of electoral votes on each of these rectangles
- //Use global color scale to color code the tiles.
+ //Use global color scale to color code the tiles.
- //HINT: Use .tile class to style your tiles;
- // .tilestext to style the text corresponding to tiles
+ //HINT: Use .tile class to style your tiles;
+ // .tilestext to style the text corresponding to tiles
- //Call the tool tip on hover over the tiles to display stateName, count of electoral votes
- //then, vote percentage and number of votes won by each party.
- //HINT: Use the .republican, .democrat and .independent classes to style your elements.
+ //Call the tool tip on hover over the tiles to display stateName, count of electoral votes
+ //then, vote percentage and number of votes won by each party.
+ //HINT: Use the .republican, .democrat and .independent classes to style your elements.
- var self = this;
-
- let statesG = this.svg.selectAll('g')
- .data(electionResult);
-
- statesG.exit().remove();
- statesG = statesG.enter().append('g').merge(statesG);
-
- let statesRect = statesG.selectAll('rect')
- .data(function(d){
- return d3.select(this).data()
- });
-
- //statesRect.exit().remove();
- statesRect = statesRect.enter().append('rect').merge(statesRect);
-
- statesRect
- .attr('width', this.svgWidth/this.maxColumns)
- .attr('height', this.svgHeight/this.maxRows)
- .attr('x', function(d){
- return (self.svgWidth/self.maxColumns)*(parseInt(d["Space"]))
- })
- .attr('y', function(d){
- return (self.svgHeight/self.maxRows)*(parseInt(d["Row"]))
- })
- .attr('fill', function(d){
- return colorScale(d["RD_Difference"])
- })
- .attr('space-row', function(d){
- return d["Space"] + '-' + d["Row"];
- })
- .attr('stroke', '#ffffff')
- .attr('stroke-width', 1)
- .call(tip)
- .on('mouseover', tip.show)
- .on('mouseout', tip.hide)
-
- let statesNameText = statesG.selectAll('text').filter('.stateName')
- .data(function(d){
- return d3.select(this).data()
- });
-
- //statesNameText.exit().remove();
- statesNameText = statesNameText.enter().append('text').merge(statesNameText);
-
- statesNameText
- .attr('x', function(d){
- let startX = (self.svgWidth/self.maxColumns)*(parseInt(d["Space"]))
- return startX + (self.svgWidth/self.maxColumns)/2
- })
- .attr('y', function(d){
- let startY = (self.svgHeight/self.maxRows)*(parseInt(d["Row"]))
- return startY + (self.svgHeight/self.maxRows)/2
-
- })
- .attr('class', 'tilestext stateName')
- .text(function(d){
- return d["Abbreviation"]
- })
- .call(tip)
- .on('mouseover', tip.show)
- .on('mouseout', tip.hide)
-
- let statesEVText = statesG.selectAll('text').filter('.stateEV')
- .data(function(d){
- return d3.select(this).data()
- });
-
- statesEVText.exit().remove();
- statesEVText = statesEVText.enter().append('text').merge(statesEVText);
-
- statesEVText
- .attr('x', function(d){
- let startX = (self.svgWidth/self.maxColumns)*(parseInt(d["Space"]))
- return startX + (self.svgWidth/self.maxColumns)/2
- })
- .attr('y', function(d){
- let startY = (self.svgHeight/self.maxRows)*(parseInt(d["Row"]))
- return startY + (self.svgHeight/self.maxRows)/2 + 15;
- })
- .attr('class', 'tilestext stateEV')
- .text(function(d){
- return d["Total_EV"]
- })
- .call(tip)
- .on('mouseover', tip.show)
- .on('mouseout', tip.hide)
-
-
- };
+ };
}
diff --git a/hw6/public/js/votePercentageChart.js b/hw6/public/js/votePercentageChart.js
index 5aec8c4..995f9c7 100644
--- a/hw6/public/js/votePercentageChart.js
+++ b/hw6/public/js/votePercentageChart.js
@@ -65,156 +65,23 @@ class VotePercentageChart {
//Create the stacked bar chart.
//Use the global color scale to color code the rectangles.
//HINT: Use .votesPercentage class to style your bars.
- let self = this;
- electionResult[0].
- let iPercent = parseFloat(electionResult[0].I_PopularPercentage === "" ? 0: electionResult[0].I_PopularPercentage);
- let dPercent = parseFloat(electionResult[0].D_PopularPercentage);
- let rPercent = parseFloat(electionResult[0].R_PopularPercentage);
- let percentArray = [];
- percentArray.push({party: "I", percent:iPercent, nominee: electionResult[0].I_Nominee_prop});
- percentArray.push({party: "D", percent:dPercent, nominee: electionResult[0].D_Nominee_prop});
- percentArray.push({party: "R", percent:rPercent, nominee: electionResult[0].R_Nominee_prop});
- percentArray.forEach(function(d){
- d.D_Nominee_prop= electionResult[0].D_Nominee_prop;
- d.R_Nominee_prop= electionResult[0].R_Nominee_prop;
- d.I_Nominee_prop= electionResult[0].I_Nominee_prop;
- d.D_Votes = electionResult[0].D_Votes;
- d.R_Votes = electionResult[0].R_Votes;
- d.I_Votes = electionResult[0].I_Votes;
+ //Display the total percentage of votes won by each party
+ //on top of the corresponding groups of bars.
+ //HINT: Use the .votesPercentageText class to style your text elements; Use this in combination with
+ // chooseClass to get a color based on the party wherever necessary
- })
- //for reference:https://github.com/Caged/d3-tip
- //Use this tool tip element to handle any hover over the chart
- let tip = d3.tip().attr('class', 'd3-tip')
- .direction('s')
- .offset(function() {
- return [0,0];
- })
- .html((d)=> {
- let tooltip_data = {
- "result":[
- {"nominee": d.D_Nominee_prop,"votecount": d.D_Votes,"percentage": dPercent,"party":"D"} ,
- {"nominee": d.R_Nominee_prop,"votecount": d.R_Votes,"percentage": rPercent,"party":"R"} ,
- {"nominee": d.I_Nominee_prop,"votecount": d.I_Votes,"percentage": iPercent,"party":"I"}
- ]
- };
- return self.tooltip_render(tooltip_data);
- });
+ //Display a bar with minimal width in the center of the bar chart to indicate the 50% mark
+ //HINT: Use .middlePoint class to style this bar.
+ //Just above this, display the text mentioning details about this mark on top of this bar
+ //HINT: Use .votesPercentageNote class to style this text element
- // ******* TODO: PART III *******
+ //Call the tool tip on hover over the bars to display stateName, count of electoral votes.
+ //then, vote percentage and number of votes won by each party.
- //Create the stacked bar chart.
- //Use the global color scale to color code the rectangles.
- //HINT: Use .votesPercentage class to style your bars.
- let xScale = d3.scaleLinear()
- .domain([0, 100])
- .range([0, this.svgWidth]);
- let xPosition = [0];
- percentArray.forEach(function(data){
- if(xPosition.length!==0){
- xPosition.push(xPosition[xPosition.length-1]+data.percent);
- }
- });
- let rect = this.svg.selectAll(".votesPercentage").data(percentArray);
- let newRect = rect.enter().append("rect");
- rect.exit().remove();
- rect = newRect.merge(rect);
- rect.attr("x", function(d,i){
- return xScale(xPosition[i]);
- })
- .attr("y", 150)
- .attr("height", 20)
- .attr("width", function(d, i){
- return xScale(d.percent);
- })
- .attr("class", function(d, i){
- return self.chooseClass(d.party);
- })
- .classed("votesPercentage", true);
+ //HINT: Use the chooseClass method to style your elements based on party wherever necessary.
- //Display the total percentage of votes won by each party
- //on top of the corresponding groups of bars.
- //HINT: Use the .votesPercentageText class to style your text elements; Use this in combination with
- // chooseClass to get a color based on the party wherever necessary
- let text = this.svg.selectAll(".votesPercentageText").data(percentArray);
- let newText = text.enter().append("text");
- text.exit().remove();
- text = newText.merge(text);
- text.attr("x", function(d, i){
- if(i===percentArray.length-1){
- return xScale(xPosition[xPosition.length-1]);
- } else {
- return xScale(xPosition[i]);
- }
- })
- .attr("y", 120)
- .text(function(d, i){
- return d.percent===0? "": d.percent+"%";
- })
- .attr("class", function(d,i){
- return self.chooseClass(d.party);
- })
- .classed("votesPercentageText", true);
-
- let nominees = this.svg.selectAll(".nomineeNames").data(percentArray);
- let newNominees = nominees.enter().append("text");
- nominees.exit().remove();
- nominees = newNominees.merge(nominees);
- nominees.attr("x", function(d, i){
- if(i===percentArray.length-1){
- return xScale(xPosition[xPosition.length-1]);
- } else {
- return xScale(xPosition[i]);
- }
- })
- .attr("y", 80)
- .text(function(d, i){
- return d.nominee;
- })
- .attr("class", function(d,i){
- return self.chooseClass(d.party);
- })
- .classed("votesPercentageText", true);
-
- if(percentArray[0].percent!==0){
- let dText = text.filter(function(d){
- return d.party=== 'D';
- });
- dText.attr("transform", "translate(50, 0)");
-
- let dNominee = nominees.filter(function(d){
- return d.party=== 'D';
- });
- dNominee.attr("transform", "translate(180, 0)");
- }
-
- //Display a bar with minimal width in the center of the bar chart to indicate the 50% mark
- //HINT: Use .middlePoint class to style this bar.
- let midPosition = xScale(xPosition[xPosition.length-1]/2);
- this.svg.selectAll(".middlePoint").remove();
- this.svg.append("rect")
- .attr("x", xScale(50))
- .attr("y", 145)
- .attr("height", 30)
- .attr("width", 3)
- .classed("middlePoint", true);
-
- //Just above this, display the text mentioning details about this mark on top of this bar
- //HINT: Use .votesPercentageNote class to style this text element
- this.svg.selectAll(".votesPercentageNote").remove();
- this.svg.append("text")
- .attr("x", xScale(50))
- .attr("y", 120)
- .classed("votesPercentageNote", true)
- .text("Popular Vote(50%)");
-
- //Call the tool tip on hover over the bars to display stateName, count of electoral votes.
- //then, vote percentage and number of votes won by each party.
- this.svg.call(tip);
- rect.on("mouseover", tip.show);
- rect.on("mouseout", tip.hide);
};
diff --git a/hw6/public/js/yearChart.js b/hw6/public/js/yearChart.js
index 2bbd45c..00e622d 100644
--- a/hw6/public/js/yearChart.js
+++ b/hw6/public/js/yearChart.js
@@ -69,7 +69,7 @@ class YearChart {
.domain(domain)
.range(range);
- // ******* DONE: PART I *******
+ // ******* TODO: PART I *******
// Create the chart by adding circle elements representing each election year
@@ -91,6 +91,7 @@ class YearChart {
//Election information corresponding to that year should be loaded and passed to
// the update methods of other visualizations
+ let domainOfYears = [];
let yChart = this;
var data = [[0, (this.svgHeight - 40)/2], [this.svgWidth, (this.svgHeight - 40)/2]];
@@ -133,32 +134,20 @@ class YearChart {
.attr('text-anchor', 'middle')
.text((d) => {return d.YEAR});
- //Style the chart by adding a dashed line that connects all these years.
- //HINT: Use .lineChart to style this dashed line
- //Done. Before adding circles
-
- //Clicking on any specific year should highlight that circle and update the rest of the visualizations
- //HINT: Use .highlighted class to style the highlighted circle
- years.selectAll('circle')
- .on('mouseover', function (d) {
- d3.select(this).classed('highlighted', true);
- })
- .on('mouseout', function (d) {
- years.selectAll('circle').classed('highlighted', false);
- })
- .on('click', function (d) {
+ years
+ .on("click", d => {
years.selectAll('circle').classed('selected', false);
- d3.select(this).classed('selected', true);
+ d3.select(d3.event.target).classed("selected", true);
- let file = 'data/Year_Timeline_' + d.YEAR + '.csv';
-
- d3.csv(file, function (error, electionResult) {
- yChart.electoralVoteChart.update(electionResult, self.colorScale);
- yChart.votePercentageChart.update(electionResult);
- yChart.tileChart.update(electionResult, self.colorScale);
+ // Election information corresponding to the year selected is loaded and passed to the update methods of the other visualizations.
+ d3.csv(`data/Year_Timeline_${d.YEAR}.csv`).then(electionResult => {
+ this.electoralVoteChart.update(electionResult, this.colorScale);
+ this.votePercentageChart.update(electionResult, this.colorScale);
+ this.tileChart.update(electionResult, this.colorScale)
});
-
})
+ .on("mouseenter", () => d3.select(d3.event.target).classed("highlighted", true))
+ .on("mouseleave", () => d3.select(d3.event.target).classed("highlighted", false));
//******* TODO: EXTRA CREDIT *******