Skip to content

Commit d4464cd

Browse files
committed
fix(time-series): improve location filters and reset behavior
1 parent aaa3b21 commit d4464cd

File tree

13 files changed

+208
-75
lines changed

13 files changed

+208
-75
lines changed

src/components/filter-bar/index.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,28 +52,28 @@ const mapStateToProps = (state, ownProps) => {
5252
};
5353
};
5454

55-
const mapDispatchToProps = (dispatch) => ({
56-
clearAllSelections: () => {
55+
const mapDispatchToProps = (dispatch, ownProps) => ({
56+
clearAllSelections: ownProps.onClearSelections || (() => {
5757
dispatch(clearSelections());
58-
},
59-
setPredictionYear: (year) => {
58+
}),
59+
setPredictionYear: ownProps.onSetPredictionYear || ((year) => {
6060
dispatch(setPredictionYear(year));
61-
},
61+
}),
6262
setStartYear: (year) => {
6363
dispatch(setStartYear(year));
6464
},
6565
setEndYear: (year) => {
6666
dispatch(setEndYear(year));
6767
},
68-
setCounty: (county) => {
68+
setCounty: ownProps.onSetCounty || ((county) => {
6969
dispatch(setCounty(county));
70-
},
71-
setRangerDistrict: (rangerDistrict) => {
70+
}),
71+
setRangerDistrict: ownProps.onSetRangerDistrict || ((rangerDistrict) => {
7272
dispatch(setRangerDistrict(rangerDistrict));
73-
},
74-
setState: (state) => {
73+
}),
74+
setState: ownProps.onSetState || ((state) => {
7575
dispatch(setState(state));
76-
},
76+
}),
7777
setDataMode: (mode) => {
7878
dispatch(setDataMode(mode));
7979
},

src/components/historical-data/trapping-data-map/component.js

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,18 @@ const HistoricalMap = (props) => {
4343
const {
4444
availableStates,
4545
availableSublocations,
46+
county,
4647
dataMode,
4748
predictionYear,
49+
rangerDistrict,
4850
selectedState,
4951
setCounty,
5052
setRangerDistrict,
5153
setState,
54+
setCountyFilter,
55+
setRangerDistrictFilter,
56+
setStateFilter,
57+
clearAllSelections,
5258
sublocationData: rawData,
5359
} = props;
5460

@@ -114,14 +120,27 @@ const HistoricalMap = (props) => {
114120
const filteredData = d.filter((item) => {
115121
const itemYear = parseYearFromItem(item);
116122
if (itemYear === null) return false;
117-
return itemYear === selectedYear;
123+
if (itemYear !== selectedYear) return false;
124+
125+
// Apply visual filtering based on selected state, county, and rangerDistrict
126+
if (selectedState && item.state !== selectedState) return false;
127+
128+
if (dataMode === DATA_MODES.COUNTY && county && county.length > 0) {
129+
if (!county.includes(item.county)) return false;
130+
}
131+
132+
if (dataMode === DATA_MODES.RANGER_DISTRICT && rangerDistrict && rangerDistrict.length > 0) {
133+
if (!rangerDistrict.includes(item.rangerDistrict)) return false;
134+
}
135+
136+
return true;
118137
});
119138

120139
const trappingsByLocality = filteredData.reduce((acc, curr) => {
121140
const {
122-
county,
123-
rangerDistrict,
124-
state,
141+
county: itemCounty,
142+
rangerDistrict: itemRangerDistrict,
143+
state: itemState,
125144
sumSpotst0,
126145
spotst0,
127146
spots,
@@ -136,8 +155,8 @@ const HistoricalMap = (props) => {
136155
spotsValue = spots;
137156
}
138157

139-
const countyFormatName = county && state ? `${county} ${state}`.toUpperCase() : '';
140-
const rangerDistrictFormatName = rangerDistrict ? getMapboxRDNameFormat(rangerDistrict)?.toUpperCase() : '';
158+
const countyFormatName = itemCounty && itemState ? `${itemCounty} ${itemState}`.toUpperCase() : '';
159+
const rangerDistrictFormatName = itemRangerDistrict ? getMapboxRDNameFormat(itemRangerDistrict)?.toUpperCase() : '';
141160

142161
const localityDescription = dataMode === DATA_MODES.COUNTY ? countyFormatName : rangerDistrictFormatName;
143162

@@ -266,7 +285,7 @@ const HistoricalMap = (props) => {
266285

267286
zoomToSelectedState(selectedState, map);
268287
// eslint-disable-next-line react-hooks/exhaustive-deps
269-
}, [rawData, selectedState, map, predictionYear]);
288+
}, [rawData, selectedState, map, predictionYear, county, rangerDistrict]);
270289

271290
useEffect(() => {
272291
if (!initialFill && map && rawData.length > 0) {
@@ -368,16 +387,16 @@ const HistoricalMap = (props) => {
368387
availableStates={availableStates}
369388
availableYears={[]}
370389
availableSublocations={availableSublocations}
371-
county={props.county}
390+
county={county}
372391
dataMode={dataMode}
373392
predictionYear={predictionYear}
374-
rangerDistrict={props.rangerDistrict}
393+
rangerDistrict={rangerDistrict}
375394
selectedState={selectedState}
376-
setCounty={setCounty}
395+
setCounty={setCountyFilter}
377396
setPredictionYear={() => {}}
378-
setRangerDistrict={setRangerDistrict}
379-
setState={setState}
380-
clearAllSelections={props.clearAllSelections}
397+
setRangerDistrict={setRangerDistrictFilter}
398+
setState={setStateFilter}
399+
clearAllSelections={clearAllSelections}
381400
legendItems={legendItems}
382401
legendTitle="Total Number of Spots"
383402
downloadCallback={() => downloadMap(

src/components/historical-data/trapping-data-map/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
setCounty,
77
setRangerDistrict,
88
setState,
9+
ActionTypes,
910
} from '../../../state/actions';
1011

1112
const mapStateToProps = (state) => {
@@ -50,6 +51,20 @@ const mapDispatchToProps = (dispatch) => {
5051
setState: (state) => {
5152
dispatch(setState(state));
5253
},
54+
setCountyFilter: (county) => {
55+
dispatch({ type: ActionTypes.SET_COUNTY_FILTER, payload: { county: county === '' ? [] : county } });
56+
},
57+
setRangerDistrictFilter: (rangerDistrict) => {
58+
dispatch({ type: ActionTypes.SET_RANGER_DISTRICT_FILTER, payload: { rangerDistrict: rangerDistrict === '' ? [] : rangerDistrict } });
59+
},
60+
setStateFilter: (state) => {
61+
dispatch({ type: ActionTypes.SET_STATE, payload: { state } });
62+
},
63+
clearAllSelections: () => {
64+
dispatch({ type: ActionTypes.SET_STATE, payload: { state: '' } });
65+
dispatch({ type: ActionTypes.SET_COUNTY_FILTER, payload: { county: [] } });
66+
dispatch({ type: ActionTypes.SET_RANGER_DISTRICT_FILTER, payload: { rangerDistrict: [] } });
67+
},
5368
};
5469
};
5570

src/hooks/useDataTableData.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ const useDataTableData = (filters, dataFormat, dataMode) => {
3939
);
4040

4141
const fetchAvailableYears = useCallback(
42-
(filterParams) => dispatch(getAvailableYears(filterParams)),
42+
() => dispatch(getAvailableYears()),
4343
[dispatch]
4444
);
4545

4646
useEffect(() => {
47-
fetchAvailableYears({ isHistorical: true });
47+
fetchAvailableYears();
4848
fetchAvailableStates({ isHistorical: true });
4949
}, [dataMode, fetchAvailableYears, fetchAvailableStates]);
5050

src/screens/download-data/component.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const DownloadDataScreen = (props) => {
2626

2727
// Load available data when component mounts or dataMode changes
2828
useEffect(() => {
29-
dispatch(getAvailableYears({ isHistorical: true }));
29+
dispatch(getAvailableYears());
3030
dispatch(getAvailableStates({ isHistorical: true }, { historical: true, prediction: false }));
3131
}, [dataMode, dispatch]);
3232

src/screens/observed-outcomes/component.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,24 @@ import './style.scss';
88

99
const ObservedOutcomes = (props) => {
1010
const {
11-
isLoading, predictionYear, dataMode, fetchData, yearsLoaded, fetchAvailableYears,
11+
isLoading,
12+
predictionYear,
13+
dataMode,
14+
fetchData,
15+
yearsLoaded,
16+
fetchAvailableYears,
17+
clearFilters,
18+
setStateFilter,
19+
setCountyFilter,
20+
setRangerDistrictFilter,
1221
} = props;
1322

1423
// Fetch available years on mount
1524
useEffect(() => {
1625
fetchAvailableYears();
1726
}, []); // eslint-disable-line react-hooks/exhaustive-deps
1827

19-
// Fetch data when year or dataMode changes
28+
// Fetch data when year or dataMode changes (state filtering is done visually)
2029
useEffect(() => {
2130
if (yearsLoaded && predictionYear) {
2231
fetchData(predictionYear);
@@ -30,7 +39,12 @@ const ObservedOutcomes = (props) => {
3039
<OverviewText />
3140
<div className="observed-outcomes-content">
3241
<div className="container">
33-
<FilterBar />
42+
<FilterBar
43+
onClearSelections={clearFilters}
44+
onSetState={setStateFilter}
45+
onSetCounty={setCountyFilter}
46+
onSetRangerDistrict={setRangerDistrictFilter}
47+
/>
3448
</div>
3549
<ComparisonMap />
3650
<div className="container">

src/screens/observed-outcomes/components/comparison-map/component.js

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,19 @@ const ComparisonMap = (props) => {
7474
const {
7575
availableStates,
7676
availableSublocations,
77+
county,
7778
data,
7879
dataMode,
80+
rangerDistrict,
7981
selectedState,
8082
setCounty,
83+
setCountyFilter,
8184
setDataMode,
8285
setRangerDistrict,
86+
setRangerDistrictFilter,
8387
setState,
88+
clearAllSelections,
8489
year,
85-
isLoading,
86-
yearsLoaded,
8790
} = props;
8891

8992
const {
@@ -196,19 +199,36 @@ const ComparisonMap = (props) => {
196199

197200
const { fillExpression, strokeExpression } = createBaseExpressions(dataMode);
198201

199-
comparisonData.forEach(({
200-
county,
202+
// Filter data based on selected state and county/rangerDistrict
203+
const filteredData = comparisonData.filter((item) => {
204+
// First filter by state if selected
205+
if (selectedState && item.state !== selectedState) {
206+
return false;
207+
}
208+
// Then filter by county/rangerDistrict if selected
209+
if (dataMode === DATA_MODES.COUNTY) {
210+
if (county && county.length > 0) {
211+
return county.includes(item.county);
212+
}
213+
} else if (rangerDistrict && rangerDistrict.length > 0) {
214+
return rangerDistrict.includes(item.rangerDistrict);
215+
}
216+
return true;
217+
});
218+
219+
filteredData.forEach(({
220+
county: countyName,
201221
probSpotsGT50: fillProb,
202222
sumSpots,
203-
rangerDistrict,
204-
state,
223+
rangerDistrict: rdName,
224+
state: stateName,
205225
}) => {
206226
const color = getFillColor(fillProb, sumSpots);
207227

208228
const locationName = formatLocationForMapbox(dataMode, {
209-
county,
210-
rangerDistrict,
211-
state,
229+
county: countyName,
230+
rangerDistrict: rdName,
231+
state: stateName,
212232
});
213233

214234
if (locationName) {
@@ -223,7 +243,7 @@ const ComparisonMap = (props) => {
223243
addDefaultExpressions(fillExpression, strokeExpression);
224244

225245
addMapLayer(map, fillExpression, strokeExpression, getSourceLayer(dataMode));
226-
}, [map, dataMode]);
246+
}, [map, dataMode, selectedState, county, rangerDistrict]);
227247

228248
const mapInitializedRef = useRef(false);
229249
const lastDataModeRef = useRef(dataMode);
@@ -325,7 +345,7 @@ const ComparisonMap = (props) => {
325345
if (year.toString().length === 4 && data.length > 0) colorResults(data);
326346

327347
zoomToSelectedState(selectedState, map);
328-
}, [data, selectedState, map, dataMode, year, colorResults]);
348+
}, [data, selectedState, county, rangerDistrict, map, dataMode, year, colorResults]);
329349

330350
useEffect(() => {
331351
if (!initialFill && map && data.length > 0) {
@@ -401,8 +421,6 @@ const ComparisonMap = (props) => {
401421
label: getShortLabel(threshold),
402422
}));
403423

404-
const shouldShowMessage = !isLoading && !data.length && year && year.toString().length === 4 && yearsLoaded;
405-
406424
return (
407425
<div className="container flex-item-left observed-outcomes-map" id="map-container">
408426
<TogglesOverlay dataMode={dataMode} setDataMode={setDataMode} />
@@ -413,16 +431,16 @@ const ComparisonMap = (props) => {
413431
availableStates={availableStates}
414432
availableYears={[]}
415433
availableSublocations={availableSublocations}
416-
county={props.county}
434+
county={county}
417435
dataMode={dataMode}
418436
predictionYear={year}
419-
rangerDistrict={props.rangerDistrict}
437+
rangerDistrict={rangerDistrict}
420438
selectedState={selectedState}
421-
setCounty={setCounty}
439+
setCounty={setCountyFilter}
422440
setPredictionYear={() => {}}
423-
setRangerDistrict={setRangerDistrict}
441+
setRangerDistrict={setRangerDistrictFilter}
424442
setState={setState}
425-
clearAllSelections={props.clearAllSelections}
443+
clearAllSelections={clearAllSelections}
426444
legendItems={legendItems}
427445
legendTitle="Results comparison"
428446
downloadCallback={() => downloadMap(
@@ -437,13 +455,6 @@ const ComparisonMap = (props) => {
437455
isDownloadingMap={isDownloadingMap}
438456
hideFilters
439457
/>
440-
{shouldShowMessage && (
441-
<div className="observed-outcomes-message">
442-
<p>
443-
{`Map for ${year} not yet available. Spot data for the previous year usually come online sometime in January or February of the following year.`}
444-
</p>
445-
</div>
446-
)}
447458
</div>
448459
);
449460
};

src/screens/observed-outcomes/components/comparison-map/index.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { connect } from 'react-redux';
22
import {
3-
setCounty, setDataMode, setRangerDistrict, setState,
3+
ActionTypes,
4+
setCounty,
5+
setCountyFilter,
6+
setDataMode,
7+
setRangerDistrict,
8+
setRangerDistrictFilter,
9+
setState,
410
} from '../../../../state/actions';
511
import ComparisonMap from './component';
612

@@ -42,15 +48,28 @@ const mapDispatchToProps = (dispatch) => {
4248
setCounty: (county) => {
4349
dispatch(setCounty(county));
4450
},
51+
setCountyFilter: (county) => {
52+
dispatch(setCountyFilter(county));
53+
},
4554
setDataMode: (mode) => {
4655
dispatch(setDataMode(mode));
4756
},
4857
setRangerDistrict: (rangerDistrict) => {
4958
dispatch(setRangerDistrict(rangerDistrict));
5059
},
60+
setRangerDistrictFilter: (rangerDistrict) => {
61+
dispatch(setRangerDistrictFilter(rangerDistrict));
62+
},
5163
setState: (state) => {
5264
dispatch(setState(state));
5365
},
66+
clearAllSelections: () => {
67+
// Only reset filter selections without clearing data
68+
// Reset state, county, and rangerDistrict to empty
69+
dispatch({ type: ActionTypes.SET_STATE, payload: { state: '' } });
70+
dispatch({ type: ActionTypes.SET_COUNTY_FILTER, payload: { county: [] } });
71+
dispatch({ type: ActionTypes.SET_RANGER_DISTRICT_FILTER, payload: { rangerDistrict: [] } });
72+
},
5473
};
5574
};
5675

0 commit comments

Comments
 (0)