Skip to content
Snippets Groups Projects
Commit efe8e492 authored by danielmyren's avatar danielmyren
Browse files

Add functionality and options to show votes on each party in a single election...

Add functionality and options to show votes on each party in a single election & other minor changes
parent 98549859
No related branches found
No related tags found
No related merge requests found
......@@ -45,26 +45,38 @@ const MultiLevelOptions = () => {
setSelectedOptions({'option': ""}); // Reset since no option is selected
} else if (category === 'Swedish Election Results' && subCategory === '') {
setSelectedOptions({'option': ""}); // Reset since no option is selected
setSelectedOptions({'option': ""}); // Reset since no option is selected
} else if (category === 'Swedish Election Results' && subCategory === 'partyVotes' && (!year || !party)) {
setSelectedOptions({'option': ""}); // Reset since no option is selected
setSelectedOptions({'option': ""}); // Reset since no option is selected
} else if (category === 'Swedish Demographic') {
setSelectedOptions({'option': "swedish_demographic"});
// Route -> /api/swedish_demographic (note that .option is a part of the route)
setSelectedOptions({'option': "swedish_demographic"});
} else if (category === 'Swedish Election Results' && subCategory === 'totalVotes') {
setSelectedOptions({'option': "swedish_election_total_results"});
} else if (category === 'Swedish Election Results' && subCategory === 'partyVotes' && year && party){
console.log("omg im in here");
setSelectedOptions({
// Route -> /api/swedish_election_total_results (note that .option is a part of the route)
setSelectedOptions({'option': "swedish_election_total_results"});
} else if (category === 'Swedish Election Results' && subCategory === 'allPartyVotes' && year){
// Route -> /api/swedish_election_party_votes (note that .option is a part of the route)
console.log("Set corecct options");
setSelectedOptions(
{'option': "swedish_election_party_votes",
'subOption' : "everyParty_one_year",
'year' : year
});
}else if (category === 'Swedish Election Results' && subCategory === 'partyVotes' && year && party){
// Route -> /api/swedish_election_party_votes (note that .option is a part of the route)
setSelectedOptions({
'option': "swedish_election_party_votes",
'year': [year],
'party': [party]
'subOption' : false,
'year': year,
'party': party
});
}
}, [category, subCategory, year, party]);
useEffect(() => {
......@@ -94,11 +106,25 @@ const MultiLevelOptions = () => {
<select value={subCategory} onChange={handleSubCategoryChange}>
<option value="">Select Subcategory</option>
<option value="totalVotes">Total Votes</option>
<option value="partyVotes">Party Votes</option>
<option value="partyVotes">Single Party Votes</option>
<option value="allPartyVotes">All Party Votes / Year</option>
</select>
)}
{/* Third level menus, visible only if Party Votes is selected */}
{/* Third level menus: */}
{subCategory === 'allPartyVotes' && (
<div>
<select value={year} onChange={handleYearChange}>
<option value="">Select Election Year</option>
{/* Create an 'Option' element for each year */}
{years.map((year) => (
<option key={year} value={year}>{year}</option>
))}
</select>
</div>
)}
{/* Third level menus: */}
{subCategory === 'partyVotes' && (
<div>
<select value={party} onChange={handlePartyChange}>
......
.table{
padding: 30px;
margin: 10px;
margin: 5px;
height: 800px;
margin-bottom: 16px;
}
......
......@@ -36,21 +36,23 @@ const BarChart = ({ selectedKey }) => {
* The variable `selectedOptions.option` determines what data is drawn on the chart.
* Data should be handled separately for each type of graph based on the `selectedOptions.option` value.
*
* SelectedOptions.option is one of : swedish_demographic,
* SelectedOptions.option is one of :
* swedish_election_allPartyVotes,
* swedish_election_total_results,
* swedish_election_party_votes
* swedish_election_party_votes,
* swedish_demographic,
*/
// Set up common dimensions and margins
const margin = { top: 20, right: 30, bottom: 30, left: 40 };
const width = 800 - margin.left - margin.right;
const margin = { top: 20, right: 60, bottom: 30, left: 60 };
const width = 1000 - margin.left - margin.right;
const height = 500 - margin.top - margin.bottom;
// Clear previous SVG content
svg.selectAll('*').remove();
if (selectedOptions.option == 'swedish_election_total_results'){
if (selectedOptions.option === 'swedish_election_total_results'){
/*
* If this option is selected show a number instead of a graph
*/
......@@ -69,26 +71,121 @@ const BarChart = ({ selectedKey }) => {
.attr("font-family", "source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace")
.text(formattedNumber);
}
if (selectedOptions.option === 'swedish_election_party_votes' && selectedOptions.subOption === 'everyParty_one_year'){
const partiesKeys = Object.keys(response.data.info.query_data);
const partyAbbreviations = {
"Centerpartiet": "C",
"Kristdemokraterna": "KD",
"Liberalerna": "L",
"Miljöpartiet": "MP",
"Moderaterna": "M",
"Socialdemokraterna": "S",
"Sverigedemokraterna": "SD",
"Vänsterpartiet": "V",
"Överiga partier": "Other",
"ogiltiga valsedlar": "Invalid",
"ej röstande": "No Vote"
};
const tempData = {}; // Votes for each party in a specific year
for (const partyName of partiesKeys){
const votes = response.data.info.query_data[partyName].votes_per_year[selectedOptions.year];
const partyAbbreviation = partyAbbreviations[partyName] || partyName; // Attempt to translate into abbreviations to save space
tempData[partyAbbreviation] = votes;
}
const partyKeys = Object.keys(tempData);
const values = Object.values(tempData);
if (selectedOptions.option == 'swedish_election_party_votes'){
const d3PreparedData = partyKeys.map((partyAbbrev, index) => ({
'party': partyAbbrev, // Keep year as a number for numerical operations
'value': values[index] // Get the corresponding value
}));
// Customize the colors as desired
/* Centerpartiet = #009933,
* Kristdemokraterna = #000077
* Liberalerna = #006AB3
* Miljöpartiet = #83CF39
* Moderaterna = #52BDEC
* Socialdemokraterna = #E8112d
* Sverigedemokraterna = #DDDD00
* Vänsterpartiet = #DA291C
* Överiga partier = #9E9E9E
* ogiltiga valsedlar = #8B5E3C
* ej röstande = #D3D3D3
*/
const colorScale = d3.scaleOrdinal()
.domain(Object.values(partyAbbreviations))
.range(["#009933", "#000077", "#006AB3", "#83CF39", "#52BDEC", "#E8112d", "#DDDD00", "#DA291C", "#9E9E9E", "#8B5E3C", "#D3D3D3"]);
// Create the graph:
// Set up scales
const xScale = d3.scaleBand()
.domain(partyKeys)
.range([0, width])
.padding(0.1);
const yScale = d3.scaleLinear()
.domain([0, d3.max(values)]) // Highest value in dataset
.nice()
.range([height, 0]);
// Create x-axis
svg.append('g')
.attr('transform', `translate(${margin.left}, ${height + margin.top})`)
.call(d3.axisBottom(xScale))
.selectAll('path, line, text') // Select the axis lines and text
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke-width', 0) // Set the width of the text
.attr('fill', 'white') // Set the color of the text to white
.attr('font-size', '18px');
// Create y-axis
svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.call(d3.axisLeft(yScale))
.selectAll('path, line, text') // Select the axis lines and text
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke-width', 0) // Set the width of the text
.attr('fill', 'white') // Set the color of the text to white
.attr('font-size', '14px');
// Create bars
svg.selectAll('.bar')
.data(d3PreparedData)
.enter().append('rect')
.attr('class', 'bar')
.attr('x', d => xScale(d.party) + margin.left)
.attr('y', d => yScale(d.value) + margin.top)
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('fill', d => colorScale(d.party));
}
if (selectedOptions.option === 'swedish_election_party_votes' && selectedOptions.subOption === false){
/*
* If this option is selected create a graph or show a number depending on the options
* If this option is selected create a graph or show a number depending on the options.
* Show votes for a single party over a time period
*/
const selected_party = selectedOptions.party[0];
let d3PreparedData = {};
const yearKeys = Object.keys(response.data.info.query_data[selected_party].votes_per_year);
const values = Object.values(response.data.info.query_data[selected_party].votes_per_year);
const yearKeys = Object.keys(response.data.info.query_data[selectedOptions.party].votes_per_year);
const values = Object.values(response.data.info.query_data[selectedOptions.party].votes_per_year);
if (selectedOptions.year[0] == 'All'){
if (selectedOptions.year === 'All'){
d3PreparedData = yearKeys.map((year, index) => ({
'year': year, // Keep year as a number for numerical operations
'value': values[index] // Get the corresponding value
}));
} else {
const total_votes_in_county_for_party = response.data.info.query_data[selected_party].votes_per_year[selectedOptions.year[0]];
const total_votes_in_county_for_party = response.data.info.query_data[selectedOptions.party].votes_per_year[selectedOptions.year];
const formattedNumber = d3.format(",")(total_votes_in_county_for_party);
svg.append("text")
......@@ -108,49 +205,49 @@ const BarChart = ({ selectedKey }) => {
// Create the graph:
// Set up scales
const xScale = d3.scaleBand()
.domain(yearKeys)
.range([0, width])
.padding(0.1);
.domain(yearKeys)
.range([0, width])
.padding(0.1);
const yScale = d3.scaleLinear()
.domain([0, d3.max(values)]) // Highest value in dataset
.nice()
.range([height, 0]);
// Create x-axis
svg.append('g')
.attr('transform', `translate(${margin.left}, ${height + margin.top})`)
.call(d3.axisBottom(xScale))
.selectAll('path, line, text') // Select the axis lines and text
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke-width', 0) // Set the width of the text
.attr('fill', 'white') // Set the color of the text to white
.attr('font-size', '16px');
// Create y-axis
svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.call(d3.axisLeft(yScale))
.selectAll('path, line, text') // Select the axis lines and text
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke-width', 0) // Set the width of the text
.attr('fill', 'white') // Set the color of the text to white
.attr('font-size', '10px');
// Create bars
svg.selectAll('.bar')
.data(d3PreparedData)
.enter().append('rect')
.attr('class', 'bar')
.attr('x', d => xScale(d.year) + margin.left)
.attr('y', d => yScale(d.value) + margin.top)
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('fill', '#3D96B1');
}
const yScale = d3.scaleLinear()
.domain([0, d3.max(values)]) // Highest value in dataset
.nice()
.range([height, 0]);
// Create x-axis
svg.append('g')
.attr('transform', `translate(${margin.left}, ${height + margin.top})`)
.call(d3.axisBottom(xScale))
.selectAll('path, line, text') // Select the axis lines and text
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke-width', 0) // Set the width of the text
.attr('fill', 'white') // Set the color of the text to white
.attr('font-size', '16px');
// Create y-axis
svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.call(d3.axisLeft(yScale))
.selectAll('path, line, text') // Select the axis lines and text
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke-width', 0) // Set the width of the text
.attr('fill', 'white') // Set the color of the text to white
.attr('font-size', '14px');
// Create bars
svg.selectAll('.bar')
.data(d3PreparedData)
.enter().append('rect')
.attr('class', 'bar')
.attr('x', d => xScale(d.year) + margin.left)
.attr('y', d => yScale(d.value) + margin.top)
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('fill', '#3D96B1');
}
if (selectedOptions.option == 'swedish_demographic'){
if (selectedOptions.option === 'swedish_demographic'){
/*
* If this option is selected create a graph
*/
......@@ -179,19 +276,21 @@ const BarChart = ({ selectedKey }) => {
.attr('transform', `translate(${margin.left}, ${height + margin.top})`)
.call(d3.axisBottom(xScale))
.selectAll('path, line, text') // Select the axis lines and text
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke-width', 0) // Set the width of the text
.attr('fill', 'white'); // Set the color of the text to white
.attr('fill', 'white') // Set the color of the text to white
.attr('font-size', '12px');
// Create y-axis
svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.call(d3.axisLeft(yScale))
.selectAll('path, line, text') // Select the axis lines and text
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke', 'white') // Set the color of the lines to white
.attr('stroke-width', 0) // Set the width of the text
.attr('fill', 'white'); // Set the color of the text to white
.attr('fill', 'white') // Set the color of the text to white
attr('font-size', '20px');
// Create bars
svg.selectAll('.bar')
.data(d3PreparedData)
......@@ -212,7 +311,7 @@ const BarChart = ({ selectedKey }) => {
}, [selectedKey, selectedOptions]); // Whenever these are changed invoke useEffect()
return (
<svg ref={svgRef} width={800} height={500}></svg>
<svg ref={svgRef} width={1000} height={500}></svg>
);
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment