From 61cffe5a08b89c6d0fdcc257aaede7fda1960ac6 Mon Sep 17 00:00:00 2001 From: YONG WOOK KIM Date: Wed, 19 Jul 2023 10:29:57 -0500 Subject: [PATCH 01/16] saving purpose --- src/components/LandingPageMap.tsx | 682 +++++++++++++-------------- src/components/LandingPageMapTab.tsx | 132 ++++-- src/pages/LandingPage.tsx | 156 +++--- 3 files changed, 524 insertions(+), 446 deletions(-) diff --git a/src/components/LandingPageMap.tsx b/src/components/LandingPageMap.tsx index dc806dbe..6a2d5c40 100644 --- a/src/components/LandingPageMap.tsx +++ b/src/components/LandingPageMap.tsx @@ -8,9 +8,6 @@ import PropTypes from "prop-types"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; import "../styles/map.css"; -import { CircularProgress } from "@mui/material"; -import { config } from "../app.config"; -import { getJsonDataFromUrl, convertAllState } from "../utils/apiutil"; import DrawLegend from "./shared/DrawLegend"; import legendConfig from "../utils/legendConfig.json"; @@ -29,13 +26,15 @@ const offsets = { }; const MapChart = (props) => { - const { setTooltipContent, title, stateCodes, allPrograms, allStates, summary } = props; + const { setTooltipContent, title, stateCodes, allPrograms, allStates, summary, screenWidth } = props; let searchKey = ""; let color1 = ""; let color2 = ""; let color3 = ""; let color4 = ""; let color5 = ""; + let minValue = 0; + let maxValue = 0; let legendTitle =
; let customScale: number[] = []; const hashmap = new Map([]); @@ -48,6 +47,7 @@ const MapChart = (props) => { hashmap.set(state, hashmap.get(state) + item.Amount); } }); + maxValue = Math.max(...hashmap.values()); switch (title) { case "All Programs": searchKey = "18-22 All Programs Total"; @@ -61,6 +61,7 @@ const MapChart = (props) => { Total Farm Bill Benefits from 2018 - 2022 ); + minValue = Math.min(...hashmap.values()); break; case "Title I: Commodities": searchKey = "Title I Total"; @@ -74,6 +75,7 @@ const MapChart = (props) => { Total Commodities Programs (Title I) from 2018 - 2022 ); + minValue = Math.min(...hashmap.values()); break; case "Title II: Conservation": searchKey = "Title II Total"; @@ -133,6 +135,11 @@ const MapChart = (props) => { allPrograms.forEach((d) => { if (d[searchKey] === 0) zeroPoints.push(d.State); }); + const label1 = ((maxValue - minValue) / 5) * 0 + minValue; + const label2 = ((maxValue - minValue) / 5) * 1 + minValue; + const label3 = ((maxValue - minValue) / 5) * 2 + minValue; + const label4 = ((maxValue - minValue) / 5) * 3 + minValue; + const label5 = ((maxValue - minValue) / 5) * 4 + minValue; return (
@@ -145,347 +152,324 @@ const MapChart = (props) => { initWidth={window.innerWidth > 1679 ? window.innerWidth * 0.75 : window.innerWidth * 0.8} /> - {summary.length === 0 ? null : ( - - - {({ geographies }) => ( - <> - {geographies.map((geo) => { - let records = []; - let total = 0; - let totalAverageMonthlyParticipation = 0; - const cur = allStates.find((s) => s.val === geo.id); - if (cur !== undefined) { - if (title === "All Programs") { - records = allPrograms.filter((s) => s.State === cur.id); - records.forEach((record) => { - total += record["18-22 All Programs Total"]; - }); - } else { - records = summary.filter((s) => s.State === cur.id && s.Title === title); - records.forEach((record) => { - total += record.Amount; - }); - } - if (title === "Supplemental Nutrition Assistance Program (SNAP)") { - records.forEach((record) => { - totalAverageMonthlyParticipation += - record["Average Monthly Participation"]; - }); - } + + + {({ geographies }) => ( + <> + {geographies.map((geo) => { + let records = []; + let total = 0; + let totalAverageMonthlyParticipation = 0; + const cur = allStates.find((s) => s.val === geo.id); + if (cur !== undefined) { + if (title === "All Programs") { + records = allPrograms.filter((s) => s.State === cur.id); + records.forEach((record) => { + total += record["18-22 All Programs Total"]; + }); + } else { + records = summary.filter((s) => s.State === cur.id && s.Title === title); + records.forEach((record) => { + total += record.Amount; + }); + } + if (title === "Supplemental Nutrition Assistance Program (SNAP)") { + records.forEach((record) => { + totalAverageMonthlyParticipation += record["Average Monthly Participation"]; + }); + } - const hoverContent = - title !== "All Programs" ? ( - - + const hoverContent = + title !== "All Programs" ? ( + + + + {stateCodes[cur.id]} + + {title === "Supplemental Nutrition Assistance Program (SNAP)" ? ( + Total Cost + ) : ( + Total Benefit + )} + + {Math.round(Number(total / 1000000.0)) >= 0 + ? `$${Number(undefined).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M` + : `-$${Number(undefined).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M`} + +
+ {/* Show additional data on hover for SNAP */} + {title === "Supplemental Nutrition Assistance Program (SNAP)" && ( - {stateCodes[cur.id]} + Avg. Monthly Participation - {title === - "Supplemental Nutrition Assistance Program (SNAP)" ? ( - - Total Cost - - ) : ( - - Total Benefit - - )} + )} + {/* Average SNAP monthly participation for the current years */} + {title === "Supplemental Nutrition Assistance Program (SNAP)" && ( - {Math.round(Number(total / 1000000.0)) >= 0 - ? `$${Number( - Math.abs(total) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M` - : `-$${Number( - Math.abs(total) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M`} + {Number( + totalAverageMonthlyParticipation / yearList.length + ).toLocaleString(undefined, { + maximumFractionDigits: 0 + })} -
- {/* Show additional data on hover for SNAP */} - {title === - "Supplemental Nutrition Assistance Program (SNAP)" && ( - - Avg. Monthly Participation - - )} - {/* Average SNAP monthly participation for the current years */} - {title === - "Supplemental Nutrition Assistance Program (SNAP)" && ( - - {Number( - totalAverageMonthlyParticipation / yearList.length - ).toLocaleString(undefined, { - maximumFractionDigits: 0 - })} - - )} -
- - - {title === - "Supplemental Nutrition Assistance Program (SNAP)" ? ( - - Costs: -
- {records.map((record) => ( -
- {record["Fiscal Year"]}:{" "} - {Number(record.Amount / 1000000.0) >= 0 - ? `$${Number( - Math.abs(record.Amount) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M` - : `-$${Number( - Math.abs(record.Amount) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M`} -
- ))} -
- ) : ( - - {title === "Crop Insurance" ? "Benefits:" : "Payments:"} -
- {records.map((record) => ( -
- {record["Fiscal Year"]}:{" "} - {Number(record.Amount / 1000000.0) >= 0 - ? `$${Number( - Math.abs(record.Amount) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M` - : `-$${Number( - Math.abs(record.Amount) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M`} -
- ))} -
- )} -
+ )}
- ) : ( - - - - {cur ? stateCodes[cur.id] : ""} - - Total Benefit - - {Math.round(Number(total / 1000000.0)) >= 0 - ? `$${Number( - Math.abs(total) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M` - : `-$${Number( - Math.abs(total) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M`} - - - - + + + {title === "Supplemental Nutrition Assistance Program (SNAP)" ? ( - Payments: + Costs:
{records.map((record) => ( -
- 2018:{" "} - {record["2018 All Programs Total"] / 1000000.0 >= 0 - ? `$${Number( - Math.abs( - record["2018 All Programs Total"] - ) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M` - : `-$${Number( - Math.abs( - record["2018 All Programs Total"] - ) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M`} -
- 2019:{" "} - {record["2019 All Programs Total"] / 1000000.0 >= 0 - ? `$${Number( - Math.abs( - record["2019 All Programs Total"] - ) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M` - : `-$${Number( - Math.abs( - record["2019 All Programs Total"] - ) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M`} -
- 2020:{" "} - {record["2020 All Programs Total"] / 1000000.0 >= 0 - ? `$${Number( - Math.abs( - record["2020 All Programs Total"] - ) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M` - : `-$${Number( - Math.abs( - record["2020 All Programs Total"] - ) / 1000000.0 - ).toLocaleString(undefined, { - maximumFractionDigits: 2 - })}M`} -
- 2021:{" "} - {record["2021 All Programs Total"] / 1000000.0 >= 0 +
+ {record["Fiscal Year"]}:{" "} + {Number(record.Amount / 1000000.0) >= 0 ? `$${Number( - Math.abs( - record["2021 All Programs Total"] - ) / 1000000.0 + Math.abs(record.Amount) / 1000000.0 ).toLocaleString(undefined, { maximumFractionDigits: 2 })}M` : `-$${Number( - Math.abs( - record["2021 All Programs Total"] - ) / 1000000.0 + Math.abs(record.Amount) / 1000000.0 ).toLocaleString(undefined, { maximumFractionDigits: 2 })}M`} -
- 2022:{" "} - {record["2022 All Programs Total"] / 1000000.0 >= 0 +
+ ))} + + ) : ( + + {title === "Crop Insurance" ? "Benefits:" : "Payments:"} +
+ {records.map((record) => ( +
+ {record["Fiscal Year"]}:{" "} + {Number(record.Amount / 1000000.0) >= 0 ? `$${Number( - Math.abs( - record["2022 All Programs Total"] - ) / 1000000.0 + Math.abs(record.Amount) / 1000000.0 ).toLocaleString(undefined, { maximumFractionDigits: 2 })}M` : `-$${Number( - Math.abs( - record["2022 All Programs Total"] - ) / 1000000.0 + Math.abs(record.Amount) / 1000000.0 ).toLocaleString(undefined, { maximumFractionDigits: 2 })}M`} -
))}
- + )} - ); - const fillColour = () => { - if (total) { - if (total !== 0) return colorScale(total); - return "#D2D2D2"; - } - return "#D2D2D2"; - }; - return ( - { - setTooltipContent(hoverContent); - }} - onMouseLeave={() => { - setTooltipContent(""); - }} - fill={fillColour()} - stroke="#FFF" - style={{ - default: { stroke: "#FFFFFF", strokeWidth: 0.75, outline: "none" }, - hover: { - stroke: "#232323", - strokeWidth: 2, - outline: "none" - }, - pressed: { - fill: "#345feb", - outline: "none" - } + + ) : ( + + > + + + {cur ? stateCodes[cur.id] : ""} + + Total Benefit + + {Math.round(Number(total / 1000000.0)) >= 0 + ? `$${Number(Math.abs(total) / 1000000.0).toLocaleString( + undefined, + { + maximumFractionDigits: 2 + } + )}M` + : `-$${Number(Math.abs(total) / 1000000.0).toLocaleString( + undefined, + { + maximumFractionDigits: 2 + } + )}M`} + + + + + + Payments: +
+ {records.map((record) => ( +
+ 2018:{" "} + {record["2018 All Programs Total"] / 1000000.0 >= 0 + ? `$${Number( + Math.abs(record["2018 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M` + : `-$${Number( + Math.abs(record["2018 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M`} +
+ 2019:{" "} + {record["2019 All Programs Total"] / 1000000.0 >= 0 + ? `$${Number( + Math.abs(record["2019 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M` + : `-$${Number( + Math.abs(record["2019 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M`} +
+ 2020:{" "} + {record["2020 All Programs Total"] / 1000000.0 >= 0 + ? `$${Number( + Math.abs(record["2020 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M` + : `-$${Number( + Math.abs(record["2020 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M`} +
+ 2021:{" "} + {record["2021 All Programs Total"] / 1000000.0 >= 0 + ? `$${Number( + Math.abs(record["2021 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M` + : `-$${Number( + Math.abs(record["2021 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M`} +
+ 2022:{" "} + {record["2022 All Programs Total"] / 1000000.0 >= 0 + ? `$${Number( + Math.abs(record["2022 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M` + : `-$${Number( + Math.abs(record["2022 All Programs Total"]) / + 1000000.0 + ).toLocaleString(undefined, { + maximumFractionDigits: 2 + })}M`} +
+
+ ))} +
+
+
); - } - return null; - })} - {geographies.map((geo) => { - const centroid = geoCentroid(geo); - const cur = allStates.find((s) => s.val === geo.id); + const fillColour = () => { + if (total) { + if (total !== 0) return colorScale(total); + return "#D2D2D2"; + } + return "#D2D2D2"; + }; return ( - - {cur && - centroid[0] > -160 && - centroid[0] < -67 && - (Object.keys(offsets).indexOf(cur.id) === -1 ? ( - - - {cur.id} - - - ) : ( - - - {cur.id} - - - ))} - + { + setTooltipContent(hoverContent); + }} + onMouseLeave={() => { + setTooltipContent(""); + }} + fill={fillColour()} + stroke="#FFF" + style={{ + default: { stroke: "#FFFFFF", strokeWidth: 0.75, outline: "none" }, + hover: { + stroke: "#232323", + strokeWidth: 2, + outline: "none" + }, + pressed: { + fill: "#345feb", + outline: "none" + } + }} + /> ); - })} - - )} - - - )} + } + return null; + })} + {geographies.map((geo) => { + const centroid = geoCentroid(geo); + const cur = allStates.find((s) => s.val === geo.id); + return ( + + {cur && + centroid[0] > -160 && + centroid[0] < -67 && + (Object.keys(offsets).indexOf(cur.id) === -1 ? ( + + + {cur.id} + + + ) : ( + + + {cur.id} + + + ))} + + ); + })} + + )} + +
); }; @@ -495,57 +479,39 @@ MapChart.propTypes = { title: PropTypes.string }; -const LandingPageMap = ({ programTitle }: { programTitle: string }): JSX.Element => { +const LandingPageMap = ({ + programTitle, + allStates, + stateCodes, + allPrograms, + summary +}: { + programTitle: string; + allStates: any; + stateCodes: any; + allPrograms: any; + summary: any; +}): JSX.Element => { const [content, setContent] = useState(""); - const [stateCodesData, setStateCodesData] = useState([]); - const [allProgramsData, setAllProgramsData] = useState([]); - const [allStatesData, setAllStatesData] = useState([]); - const [summaryData, setSummaryData] = useState([]); const [screenWidth, setScreenWidth] = useState(window.innerWidth); - React.useEffect(() => { - const statecode_url = `${config.apiUrl}/statecodes`; - getJsonDataFromUrl(statecode_url).then((response) => { - const converted_json = convertAllState(response); - setStateCodesData(converted_json); - }); - const allprograms_url = `${config.apiUrl}/allprograms`; - getJsonDataFromUrl(allprograms_url).then((response) => { - setAllProgramsData(response); - }); - const allstates_url = `${config.apiUrl}/states`; - getJsonDataFromUrl(allstates_url).then((response) => { - setAllStatesData(response); - }); - const summary_url = `${config.apiUrl}/summary`; - getJsonDataFromUrl(summary_url).then((response) => { - setSummaryData(response); - }); - }, []); return (
- {allProgramsData.length > 0 ? ( -
- -
- - {content} - -
-
- ) : ( -
- - Loading data... +
+ +
+ + {content} +
- )} +
); }; diff --git a/src/components/LandingPageMapTab.tsx b/src/components/LandingPageMapTab.tsx index 2cbec526..7680bbf6 100644 --- a/src/components/LandingPageMapTab.tsx +++ b/src/components/LandingPageMapTab.tsx @@ -1,13 +1,11 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import Tabs from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; import Box from "@mui/material/Box"; -import { CardMedia, createTheme, styled, Typography, ThemeProvider } from "@mui/material"; +import { createTheme, styled, Typography, ThemeProvider } from "@mui/material"; import Divider from "@mui/material/Divider"; import LandingPageMap from "./LandingPageMap"; import LandingDisplay from "./LandingDisplay"; -import { config } from "../app.config"; -import { getJsonDataFromUrl } from "../utils/apiutil"; const theme = createTheme({ palette: { @@ -17,18 +15,27 @@ const theme = createTheme({ } }); -interface TabPanelProps { - index: number; - value: number; +function TabPanel({ + value, + index, + title, + allStates, + stateCodes, + allPrograms, + summary +}: { + value: any; + index: any; title: string; -} - -function TabPanel(props: TabPanelProps) { - const { value, index, title, ...other } = props; + allStates: any; + stateCodes: any; + allPrograms: any; + summary: any; +}) { return (
{window.innerWidth > 1679 ? ( - ); } diff --git a/src/pages/LandingPage.tsx b/src/pages/LandingPage.tsx index f8f4c451..81f36ba8 100644 --- a/src/pages/LandingPage.tsx +++ b/src/pages/LandingPage.tsx @@ -1,68 +1,112 @@ import * as React from "react"; -import { CardMedia, Typography } from "@mui/material"; +import { CardMedia, createTheme, ThemeProvider, Typography } from "@mui/material"; import Box from "@mui/material/Box"; import NavBar from "../components/NavBar"; import forest from "../images/forest.png"; import News from "../components/News"; import Footer from "../components/Footer"; import LandingPageMapTab from "../components/LandingPageMapTab"; +import { config } from "../app.config"; +import { convertAllState, getJsonDataFromUrl } from "../utils/apiutil"; export default function LandingPage(): JSX.Element { + // connect to api endpoint + const [stateCodes, setStateCodes] = React.useState([]); + const [allPrograms, setAllPrograms] = React.useState([]); + const [allStates, setAllStates] = React.useState([]); + const [summary, setSummary] = React.useState([]); + + const defaultTheme = createTheme(); + + React.useEffect(() => { + const statecode_url = `${config.apiUrl}/statecodes`; + getJsonDataFromUrl(statecode_url).then((response) => { + const converted_json = convertAllState(response); + setStateCodes(converted_json); + }); + + const allprograms_url = `${config.apiUrl}/allprograms`; + getJsonDataFromUrl(allprograms_url).then((response) => { + setAllPrograms(response); + }); + + const allstates_url = `${config.apiUrl}/states`; + getJsonDataFromUrl(allstates_url).then((response) => { + setAllStates(response); + }); + + const summary_url = `${config.apiUrl}/summary`; + getJsonDataFromUrl(summary_url).then((response) => { + setSummary(response); + }); + }, []); + return ( - - -
- - - Understanding - - - - Policy Design: - - - - Applying Public Data and Computational Resources to - - - Visualize Federal Agricultural, Conservation and Food Policies - -
- - -