Skip to content

Commit fb9d2d3

Browse files
authored
fix: feedback on GOES interface (#281)
# Description: This PR addresses several UI/UX improvements and bug fixes for the GOES Plume Viewer, focusing on date filtering functionality and animation timeline improvements. # Changes: 1. Date Picker Temporal Extent Restrictions (Commit: 0eb8684) Implemented dynamic calculation of min/max dates from regions data and added constraints to DatePicker components to grey out dates outside the available data range. Added reset functionality to restore date range when the home button is clicked, preventing users from selecting dates with no available data. 2. Animation Timeline First Plume Display Fix (Commit: e51e64f) Resolved issue where the first plume would disappear when dragging the animation slider to the beginning by moving the initial plume display call outside of the timeline onStart handler, ensuring proper rendering before timeline initialization. 3. Measurement Tool Icon Visibility Fix (Commit: 140ccdf) Fixed ruler icon turning white and blending with button background when selected by replacing the undefined CSS variable with the correct color variable, ensuring proper contrast between icon and button background. 4. Animation Replay Button Fix (Commit: 005d427) Fixed replay button incorrectly restarting the animation from the middle of the timeline instead of the beginning. The issue was caused by the [mapboxgl-timeline](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) library passing a string value to the Date constructor. Applied a monkey patch to correctly parse the slider's minimum value as a number, and updated the onStart callback to properly reset animation state and clear all buffered layers. PR is made on the timeline library too. [ref](markusand/mapboxgl-timeline#2)
2 parents 30da1a8 + 005d427 commit fb9d2d3

File tree

4 files changed

+69
-18
lines changed

4 files changed

+69
-18
lines changed

goes-plume-viewer/src/components/filter/index.jsx

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,48 @@
1-
import { useState, useEffect } from "react";
1+
import { useState, useEffect, useMemo } from "react";
22
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
33
import moment from "moment";
44

5-
export function FilterByDate({regions, plumes, setFilteredRegions, setFilteredSelectedPlumes}) {
6-
const [startDate, setStartDate] = useState(moment("2018-01-01"));
7-
const [endDate, setEndDate] = useState(() => moment());
5+
export function FilterByDate({regions, plumes, setFilteredRegions, setFilteredSelectedPlumes, resetFilterDates, setResetFilterDates}) {
6+
// Calculate the overall temporal extent from regions data
7+
const { minDate, maxDate } = useMemo(() => {
8+
if (!regions.length) {
9+
return {
10+
minDate: moment("2018-01-01"),
11+
maxDate: moment()
12+
};
13+
}
14+
15+
let min = moment(regions[0].startDate);
16+
let max = moment(regions[0].endDate);
17+
18+
regions.forEach(region => {
19+
const regionStart = moment(region.startDate);
20+
const regionEnd = moment(region.endDate);
21+
22+
if (regionStart.isBefore(min)) min = regionStart;
23+
if (regionEnd.isAfter(max)) max = regionEnd;
24+
});
25+
26+
return { minDate: min, maxDate: max };
27+
}, [regions]);
28+
29+
const [startDate, setStartDate] = useState(minDate);
30+
const [endDate, setEndDate] = useState(maxDate);
31+
32+
// Update filter dates when the temporal extent changes
33+
useEffect(() => {
34+
setStartDate(minDate);
35+
setEndDate(maxDate);
36+
}, [minDate, maxDate]);
37+
38+
// Reset filter dates when home button is clicked
39+
useEffect(() => {
40+
if (resetFilterDates) {
41+
setStartDate(minDate);
42+
setEndDate(maxDate);
43+
setResetFilterDates(false);
44+
}
45+
}, [resetFilterDates, minDate, maxDate, setResetFilterDates]);
846

947
useEffect(() => {
1048
if (!regions.length) return;
@@ -44,6 +82,8 @@ export function FilterByDate({regions, plumes, setFilteredRegions, setFilteredSe
4482
label="Start Date"
4583
value={startDate}
4684
onChange={setStartDate}
85+
minDate={minDate}
86+
maxDate={maxDate}
4787
sx={{
4888
"& .MuiOutlinedInput-root": {
4989
"& fieldset": {
@@ -67,6 +107,8 @@ export function FilterByDate({regions, plumes, setFilteredRegions, setFilteredSe
67107
label="End Date"
68108
value={endDate}
69109
onChange={setEndDate}
110+
minDate={minDate}
111+
maxDate={maxDate}
70112
sx={{
71113
"& .MuiOutlinedInput-root": {
72114
"& fieldset": {

goes-plume-viewer/src/components/mapControls/measureDistance.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ function MeasureButton({ icon: iconClicked, onClick }) {
88
<Tooltip title="Measurement Scale">
99
<IconButton className="measure-icon map-control-icon"
1010
style={{
11-
backgroundColor: !iconClicked ? "": "var(--heading-gray)",
12-
color: !iconClicked ? "var(--heading-gray)" : "white"
11+
backgroundColor: !iconClicked ? "": "var(--light-grey)",
12+
color: !iconClicked ? "var(--light-grey)" : "white"
1313
}}
1414
onClick={onClick}
1515
>

goes-plume-viewer/src/components/plumeAnimation/index.jsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,14 @@ export const PlumeAnimation = ({ plumes }) => {
3333

3434
let startDatetime = plumes[0]["properties"]["datetime"];
3535
let endDatetime = plumes[plumes.length - 1]["properties"]["datetime"];
36+
37+
handleAnimation(map, startDatetime, plumeDateIdxMap, plumes, bufferedLayer, bufferedSource, rasterApiUrl);
38+
3639
timeline.current = new TimelineControl({
3740
start: startDatetime,
3841
end: endDatetime,
3942
initial: startDatetime,
4043
step: 1000 * 60 * 5, // 5 minute for GOES satellite; TODO: get this from the difference between the time of consecutive elements
41-
onStart: (date) => {
42-
// executed on initial step tick.
43-
handleAnimation(
44-
map,
45-
date,
46-
plumeDateIdxMap,
47-
plumes,
48-
bufferedLayer,
49-
bufferedSource,
50-
rasterApiUrl
51-
);
52-
},
5344
onChange: (date) => {
5445
// executed on each changed step tick.
5546
handleAnimation(
@@ -67,6 +58,20 @@ export const PlumeAnimation = ({ plumes }) => {
6758
return dateStr
6859
}
6960
});
61+
62+
/*
63+
* Monkey patch reset method to fix issue with slider reseting in mid when replaying.
64+
* It was caused by the string timestamp from slider.min incompatible in the mapboxgl-timeline library
65+
* Use monkey patch until the fix is made on the library.
66+
*/
67+
timeline.current.reset = function(t) {
68+
if (t === undefined) {
69+
t = parseFloat(this.slider.min); // fix
70+
}
71+
this.slider.value = `${new Date(t).getTime()}`;
72+
this.slider.dispatchEvent(new Event("change"));
73+
};
74+
7075
const timelineElement = timeline.current.onAdd(map);
7176
timelineComponent.current.append(timelineElement);
7277

goes-plume-viewer/src/pages/dashboard/index.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export function Dashboard({
5353

5454
const [ filteredRegions, setFilteredRegions ] = useState([]); // all regions with the filter applied
5555
const [ filteredSelectedPlumes, setFilteredSelectedPlumes ] = useState([]); // plumes for the selected region with the filter applied
56+
const [ resetFilterDates, setResetFilterDates ] = useState(false); // trigger to reset filter dates
5657

5758
const [ plumeIds, setPlumeIds ] = useState([]); // list of plume_ids for the search feature.
5859
const [ plumesForAnimation, setPlumesForAnimation ] = useState([]); // list of subdaily_plumes used for animation
@@ -124,6 +125,7 @@ export function Dashboard({
124125
setOpenDrawer(false);
125126
setZoomLevel(4);
126127
setZoomLocation([-98.771556, 32.967243]);
128+
setResetFilterDates(true);
127129
}
128130

129131
const handleResetToSelectedRegion = () => {
@@ -185,6 +187,8 @@ export function Dashboard({
185187
plumes={selectedPlumes}
186188
setFilteredRegions={setFilteredRegions}
187189
setFilteredSelectedPlumes={setFilteredSelectedPlumes}
190+
resetFilterDates={resetFilterDates}
191+
setResetFilterDates={setResetFilterDates}
188192
/>
189193
</HorizontalLayout>
190194
<HorizontalLayout>

0 commit comments

Comments
 (0)