diff --git a/atd-vzv/src/views/map/Map.js b/atd-vzv/src/views/map/Map.js index ddc3080435..1d13fc75ad 100644 --- a/atd-vzv/src/views/map/Map.js +++ b/atd-vzv/src/views/map/Map.js @@ -6,7 +6,10 @@ import MapPolygonFilter from "./MapPolygonFilter"; import MapCompassSpinner from "./MapCompassSpinner"; import { createMapDataUrl, useMapEventHandler } from "./helpers"; import { mapInit, travisCountyBboxGeoJSON, mapNavBbox } from "./mapData"; -import { crashGeoJSONEndpointUrl } from "../../views/summary/queries/socrataQueries"; +import { + crashGeoJSONEndpointUrl, + mapRequestFields, +} from "../../views/summary/queries/socrataQueries"; import { baseSourceAndLayer, fatalitiesDataLayer, @@ -101,6 +104,7 @@ const Map = () => { filters, dateRange, mapPolygon, + mapRequestFields, mapTimeWindow ); diff --git a/atd-vzv/src/views/map/helpers.js b/atd-vzv/src/views/map/helpers.js index c4e653a9b6..d3f7455437 100644 --- a/atd-vzv/src/views/map/helpers.js +++ b/atd-vzv/src/views/map/helpers.js @@ -1,5 +1,4 @@ import { useEffect } from "react"; -import { mapRequestFields } from "../summary/queries/socrataQueries"; import { format } from "date-fns"; const convertDateToSocrataFormat = (date, suffix) => @@ -39,6 +38,7 @@ export const createMapDataUrl = ( filters, dateRange, mapPolygon, + fieldsToRequest, mapTimeWindow = "" ) => { const whereFilterString = generateWhereFilters(filters); @@ -53,7 +53,7 @@ export const createMapDataUrl = ( // Return null to prevent populating map with unfiltered data return filterCount === 0 ? null - : `${endpoint}?$select=${mapRequestFields.join(",")}` + + : `${endpoint}?$select=${fieldsToRequest.join(",")}` + `&$limit=100000` + `&$where=crash_date between '${startDate}' and '${endDate}'` + // if there is a polygon selected, add as filter diff --git a/atd-vzv/src/views/nav/SideMapControl.js b/atd-vzv/src/views/nav/SideMapControl.js index 5046dbf17e..99ba9f2584 100644 --- a/atd-vzv/src/views/nav/SideMapControl.js +++ b/atd-vzv/src/views/nav/SideMapControl.js @@ -435,7 +435,7 @@ const SideMapControl = ({ type }) => { ))} - + diff --git a/atd-vzv/src/views/nav/SideMapTimeOfDayChart.js b/atd-vzv/src/views/nav/SideMapTimeOfDayChart.js index d636475ce5..5e3b648e0d 100644 --- a/atd-vzv/src/views/nav/SideMapTimeOfDayChart.js +++ b/atd-vzv/src/views/nav/SideMapTimeOfDayChart.js @@ -9,13 +9,20 @@ import { Container, Button } from "reactstrap"; import { HorizontalBar } from "react-chartjs-2"; import { colors } from "../../constants/colors"; -export const SideMapTimeOfDayChart = ({ filters }) => { +const fieldsToRequest = [ + "death_cnt", + "sus_serious_injry_cnt", + "crash_id", + "crash_date", +]; + +export const SideMapTimeOfDayChart = ({ timeWindowConfig }) => { const chartRef = useRef(); const defaultBarColor = colors.dark; const inactiveBarColor = colors.white; - const [chartData, setChartData] = useState(null); + const [crashes, setCrashes] = useState(null); const [timeWindowData, setTimeWindowData] = useState([]); const [timeWindowPercentages, setTimeWindowPercentages] = useState([]); const [barColors, setBarColors] = useState(defaultBarColor); @@ -33,36 +40,47 @@ export const SideMapTimeOfDayChart = ({ filters }) => { crashEndpointUrl, mapFilters, dateRange, - mapPolygon + mapPolygon, + fieldsToRequest ); + !!apiUrl && axios.get(apiUrl).then((res) => { - setChartData(res.data); + setCrashes(res.data); }); }, [dateRange, mapPolygon, mapFilters]); useMemo(() => { - const crashes = chartData; // When chartData is set, accumulate time window data if (!!crashes) { - const crashTimeWindowAccumulatorArray = Object.keys(filters).map( - (filter) => 0 + // For each window of time in the config, add fatalities and serious injuries to initial count of 0 + const crashTimeWindows = Object.values(timeWindowConfig).map( + (windowArray) => windowArray + ); + const crashTimeWindowAccumulatorArray = Object.keys(timeWindowConfig).map( + () => 0 ); - const crashTimeWindows = Object.values(filters).map((filter) => filter); + const crashTimeTotals = crashes.reduce((accumulator, crash) => { crashTimeWindows.forEach((timeWindow, i) => { const crashDate = crash.crash_date; const crashHour = parseInt(format(new Date(crashDate), "H")); - crashHour >= timeWindow[0] && - crashHour <= timeWindow[1] && - accumulator[i]++; + + const crashFatalities = parseInt(crash.death_cnt); + const seriousInjuries = parseInt(crash.sus_serious_injry_cnt); + const isCrashInTimeWindow = + crashHour >= timeWindow[0] && crashHour <= timeWindow[1]; + + if (isCrashInTimeWindow) { + accumulator[i] = accumulator[i] + crashFatalities + seriousInjuries; + } }); return accumulator; }, crashTimeWindowAccumulatorArray); setTimeWindowData(crashTimeTotals); } - }, [chartData, filters]); + }, [crashes, timeWindowConfig]); useMemo(() => { // When timeWindowData is set, calc percentages @@ -86,12 +104,12 @@ export const SideMapTimeOfDayChart = ({ filters }) => { const handleBarClick = (elems) => { // Store bar label, if click is within a bar - const timeWindow = elems.length > 0 ? elems[0]._model.label : null; + const timeWindowLabel = elems.length > 0 ? elems[0]._model.label : null; const index = elems.length > 0 ? elems[0]._index : null; // If valid click, set mapTimeWindow state - if (!!timeWindow) { - const timeWindowArray = filters[timeWindow]; + if (!!timeWindowLabel) { + const timeWindowArray = timeWindowConfig[timeWindowLabel]; const timeWindowStart = timeWindowArray[0]; const timeWindowEnd = timeWindowArray[1]; const timeWindowFilterString = ` AND date_extract_hh(crash_date) between ${timeWindowStart} and ${timeWindowEnd} AND date_extract_mm(crash_date) between 0 and 59`; @@ -100,7 +118,7 @@ export const SideMapTimeOfDayChart = ({ filters }) => { // Style unselected bars as inactive if (index !== null) { - const newBarColors = Object.keys(filters).map((filter, i) => + const newBarColors = Object.keys(timeWindowConfig).map((_, i) => i === index ? defaultBarColor : inactiveBarColor ); setBarColors(newBarColors); @@ -113,7 +131,7 @@ export const SideMapTimeOfDayChart = ({ filters }) => { }; const createChartTimeLabels = () => - Object.keys(filters).map((label) => label); + Object.keys(timeWindowConfig).map((label) => label); const isMapTimeWindowSet = !!mapTimeWindow;