Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constituency Map Styling #16

Merged
merged 9 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,126 changes: 2,063 additions & 2,063 deletions backend/app/data/geojson/competitivenessColors.json

Large diffs are not rendered by default.

102 changes: 45 additions & 57 deletions frontend/components/CompetitivenessMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import * as PropTypes from "prop-types";
import MapBase from "../components/global/MapBase";
import Loading from "../components/global/Loading";
import {GeoJSON} from "react-leaflet";
import DiscreteSlider from "./global/DiscreteSlider";
export const DEFAULT_MAP_CENTER_LAT = 20.5937;
export const DEFAULT_MAP_CENTER_LNG = 78.9629;
export const DEFAULT_MAP_CENTER_LNG = 50.9629;

const CompetitivenessMap = () => {
const [features, setFeatures] = useState(null);
Expand All @@ -15,13 +14,19 @@ const CompetitivenessMap = () => {

const [electionYear, setElectionYear] = useState(2004);
const [displayData, setDisplayData] = useState(null);
const [displayId, setDisplayId] = useState(null);
const [previewData, setPreviewData] = useState(null);
const [previewId, setPreviewId] = useState(null);
const [mapChanged, setMapChanged] = useState(false);

const constituencyDataRef = useRef(constituencyData);

useEffect(() => {
constituencyDataRef.current = constituencyData;
if (displayData) {
setDisplayData(constituencyData[displayId]);
setPreviewData(constituencyData[previewId]);
}
}, [constituencyData]);

const handleSliderChange = (newValue) => {
Expand All @@ -37,6 +42,7 @@ const CompetitivenessMap = () => {

if (constituencyData[e.target.feature.id].length > 0) {
setDisplayData(constituencyDataRef.current[e.target.feature["id"]]);
setDisplayId(e.target.feature["id"]);
} else {
setDisplayData(null);
}
Expand All @@ -49,6 +55,7 @@ const CompetitivenessMap = () => {

if (constituencyData[e.target.feature.id].length > 0) {
setPreviewData(constituencyDataRef.current[e.target.feature["id"]]);
setPreviewId(e.target.feature["id"]);
} else {
setPreviewData(null);
}
Expand Down Expand Up @@ -92,25 +99,6 @@ const CompetitivenessMap = () => {
getMapColors();
}, [mapData, electionYear]);

const yearMarks = [
{
value: 2004,
label: 2004
},
{
value: 2009,
label: 2009
},
{
value: 2014,
label: 2014
},
{
value: 2019,
label: 2019
}
];

return (
<div>
<div className="map-title">Competitiveness Distribution in {electionYear}</div>
Expand All @@ -136,60 +124,60 @@ const CompetitivenessMap = () => {
defaultVisibleLayers={["LS_2019_Competitiveness"]}
mapChanged={mapChanged}
dataToDisplay={previewData}
handleSliderChange={handleSliderChange}
/>
) : (
<Loading />
)}

<div className="slider">
<div style={{fontSize: "x-large", fontWeight: "bold", textAlign: "left"}}>
<div style={{fontSize: "x-large", fontWeight: "bold", textAlign: "center"}}>
Election Year:&nbsp; {electionYear}
</div>
<DiscreteSlider handleSliderChange={handleSliderChange} marks={yearMarks} />
</div>

<div className="data-display">
{displayData && (
<div>
<div className="map-subtitle">
<div>State:</div>
<div style={{fontWeight: "normal"}}>
{displayData[0].state_name.replace("_", " ")}
<div className="data-display">
{displayData && (
<div>
<div className="map-subtitle">
<div>State:</div>
<div style={{fontWeight: "normal"}}>
{displayData[0].state_name.replace("_", " ")}
</div>
</div>
</div>

<div className="map-subtitle">
<div>Constituency:</div>
<div style={{fontWeight: "normal"}}>
{displayData[0].constituency_name.charAt(0).toUpperCase() +
displayData[0].constituency_name.slice(1).toLowerCase()}
<div className="map-subtitle">
<div>Constituency:</div>
<div style={{fontWeight: "normal"}}>
{displayData[0].constituency_name.charAt(0).toUpperCase() +
displayData[0].constituency_name.slice(1).toLowerCase()}
</div>
</div>
</div>

<div>
<div className="map-subtitle">Winning Party:</div>
<div>{displayData[0].party_name}</div>
</div>
<div>
<div className="map-subtitle">Winning Party:</div>
<div>{displayData[0].party_name}</div>
</div>

<div>
<div className="map-subtitle">Margin:</div>
<div>{displayData[0].margin_percentage}%</div>
</div>
<div>
<div className="map-subtitle">Margin:</div>
<div>{displayData[0].margin_percentage}%</div>
</div>

<div>
<div className="bold text-left-align">Winning Candidate:</div>
<div>{displayData[0].candidate}</div>
</div>
<div>
<div className="bold text-left-align">Winning Candidate:</div>
<div>{displayData[0].candidate}</div>
</div>

<div>
<div className="bold text-left-align">Runner-Up Party:</div>
<div>{displayData[1].party_name}</div>
<div>
<div className="bold text-left-align">Runner-Up Party:</div>
<div>{displayData[1].party_name}</div>

<div className="bold text-left-align">Runner-Up Candidate:</div>
<div>{displayData[1].candidate}</div>
<div className="bold text-left-align">Runner-Up Candidate:</div>
<div>{displayData[1].candidate}</div>
</div>
</div>
</div>
)}
)}
</div>
</div>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions frontend/components/global/DiscreteSlider.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ export default function DiscreteSlider({handleSliderChange, marks}) {
return (
<Box
style={{
width: 320,
width: "90%",
right: 0,
display: "flex",
justifyContent: "right",
marginTop: "5%"
justifyContent: "center",
marginTop: "2%"
}}
>
<Slider
Expand Down
70 changes: 70 additions & 0 deletions frontend/components/global/DiscreteSliderOnMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as React from "react";
import Box from "@mui/material/Box";
import Slider from "@mui/material/Slider";
import * as PropTypes from "prop-types";
import "../../scss/mapLegends.scss";

function valuetext(value) {
return `${value}°C`;
}

export default function DiscreteSlider({handleSliderChange, marks}) {
function handleChange(event, newValue) {
handleSliderChange(newValue);
}

return (
<Box
class="timeline"
style={{
width: "100%",
right: 0,
display: "flex",
justifyContent: "center",
marginTop: "2%"
}}
>
<Slider
sx={{
"& .MuiSlider-markLabel": {
fontSize: "larger",
fontWeight: "bold",
opacity: "100%",
color: "black",
textShadow: "2px 0 0 #fff, 0 2px 0 #fff, -2px 0 0 #fff, 0 -2px 0 #fff"
},
"& .MuiSlider-rail": {
height: 12, // Increase the height of the track
borderRadius: 6,
backgroundColor: "black",
opacity: "40%"
},
"& .MuiSlider-thumb": {
width: 24, // Increase the width of the thumb
height: 24, // Increase the height of the thumb
backgroundColor: "darkRed"
},
"& .MuiSlider-track": {
color: "transparent" // Make the active part (track) transparent
}
}}
aria-label="Year"
size="large"
defaultValue={30}
getAriaValueText={valuetext}
valueLabelDisplay="auto"
shiftStep={5}
onChange={handleChange}
step={5}
marks={marks}
min={2004}
max={2019}
/>
</Box>
);
}

DiscreteSlider.propTypes = {
handleSliderChange: PropTypes.func,
marks: PropTypes.array
};
20 changes: 10 additions & 10 deletions frontend/components/global/GradientLegend.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,30 @@ import React from "react";
import "../../scss/mapLegends.scss";

const GradientLegend = () => {
// TO DO: make this a prop
// TO-DO: make these variables props
function getColor(value) {
if (value > 70) {
if (value > 30) {
return "#E9EAE0";
} else if (value > 50) {
} else if (value > 20) {
return "#F7BEC0";
} else if (value > 40) {
} else if (value > 10) {
return "#FF8A8A";
} else if (value > 30) {
} else if (value > 7) {
return "#FF5C5C";
} else if (value > 20) {
} else if (value > 5) {
return "#FF2E2E";
} else if (value > 10) {
} else if (value > 3) {
return "#FF0000";
} else if (value > 5) {
} else if (value > 2) {
return "#D10000";
} else if (value > 3) {
} else if (value > 1) {
return "#A30000";
} else {
return "#750000";
}
}

const grades = [0, 3, 5, 10, 20, 30, 40, 50, 70];
const grades = [0, 1, 2, 3, 5, 7, 10, 20, 30];
const title = "Percent Margin";
return (
<div className="gradientLegend">
Expand Down
Loading