Skip to content

Commit

Permalink
🔧 Extract the scenario library button from the filter dialog.
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasGilg committed Dec 12, 2024
1 parent b8eff10 commit a5d02fc
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 141 deletions.
41 changes: 39 additions & 2 deletions frontend/src/DataContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ import {
selectScenario,
setActiveScenario,
setMinMaxDates,
setScenarioColors,
setStartDate,
} from './store/DataSelectionSlice';
import theme from './util/Theme';

// Create the context
export const DataContext = createContext<{
Expand All @@ -50,6 +52,7 @@ export const DataContext = createContext<{
lineChartData: Record<string, InfectionData> | undefined;
referenceDateValues: InfectionData | undefined;
scenarioCardData: Record<string, InfectionData> | undefined;
groupFilterData: Record<string, InfectionData> | undefined;
groupCategories: GroupCategories | undefined;
groups: Groups | undefined;
scenarios: Scenarios | undefined;
Expand All @@ -65,6 +68,7 @@ export const DataContext = createContext<{
lineChartData: undefined,
referenceDateValues: undefined,
scenarioCardData: undefined,
groupFilterData: undefined,
groupCategories: undefined,
groups: undefined,
scenarios: undefined,
Expand All @@ -89,6 +93,7 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
const selectedCompartment = useAppSelector((state) => state.dataSelection.compartment);
const referenceDate = useAppSelector((state) => state.dataSelection.simulationStart);
const selectedDate = useAppSelector((state) => state.dataSelection.date);
const groupFilters = useAppSelector((state) => state.dataSelection.groupFilters);

const {data: scenarios} = useGetScenariosQuery();
const {data: compartments} = useGetCompartmentsQuery();
Expand Down Expand Up @@ -128,7 +133,23 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
}
);

// TODO: GroupFilterData
const {data: groupFilterData} = useGetMultiScenarioInfectionDataQuery(
{
pathIds: activeScenarios ?? [],
query: {
startDate: selectedDate!,
endDate: selectedDate!,
nodes: [selectedDistrict],
percentiles: ['50'],
groups: Object.values(groupFilters)
.filter((groupFilter) => groupFilter.isVisible) // Filter visible groups
.flatMap((groupFilter) => Object.values(groupFilter.groups).flat()), // Extract and flatten group Ids.
},
},
{
skip: !activeScenarios || !selectedDate || !selectedDistrict || Object.keys(groupFilters).length === 0,
}
);

const {data: lineChartData} = useGetMultiScenarioInfectionDataQuery(
{
Expand Down Expand Up @@ -179,6 +200,20 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
}
}, [caseDataScenario, dispatch, selectedScenario]);

// Set scenario colors
useEffect(() => {
if (caseDataScenario) {
dispatch(setScenarioColors({id: caseDataScenario.id, colors: theme.custom.scenarios[0]}));
}

scenarios?.forEach((scenario, index) => {
if (scenario.id !== caseDataScenario?.id) {
const colorIndex = (index + 1) % theme.custom.scenarios.length; // +1 to avoid using the first predefined color set
dispatch(setScenarioColors({id: scenario.id, colors: theme.custom.scenarios[colorIndex]}));
}
});
}, [caseDataScenario, dispatch, scenarios]);

// If we have no selected compartment, we try to set the first one as selected.
useEffect(() => {
if (!selectedCompartment && compartments && compartments.length > 0) {
Expand All @@ -191,7 +226,7 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
if (!referenceDate && caseDataScenario) {
dispatch(setStartDate(caseDataScenario.endDate));
}
});
}, [caseDataScenario, dispatch, referenceDate]);

// Set start and end date.
useEffect(() => {
Expand Down Expand Up @@ -279,6 +314,7 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
lineChartData,
referenceDateValues,
scenarioCardData,
groupFilterData,
groupCategories,
groups,
scenarios,
Expand All @@ -298,6 +334,7 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
groupCategories,
groups,
scenarios,
groupFilterData,
selectedScenarioData,
simulationModels,
selectedSimulationModel,
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/LineChartContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default function LineChartContainer() {
const referenceDay = useAppSelector((state) => state.dataSelection.simulationStart);
const minDate = useAppSelector((state) => state.dataSelection.minDate);
const maxDate = useAppSelector((state) => state.dataSelection.maxDate);
const scenarioColors = useAppSelector((state) => state.dataSelection.scenarioColors);

const [referenceDayBottomPosition, setReferenceDayBottomPosition] = useState<number>(0);

Expand All @@ -41,7 +42,7 @@ export default function LineChartContainer() {
name: scenarios?.find((scenario) => scenario.id === id)?.name,
visible: true,
stroke: {
color: 'red', // TODO
color: scenarioColors?.[id]?.[0] ?? 'transparent',
},
valueYField: id,
values: infectionDataToLineChartData(data, ['50']),
Expand All @@ -61,7 +62,7 @@ export default function LineChartContainer() {
seriesId: `${id}-${percentile.lower}-${percentile.upper}`,
name: scenarios?.find((scenario) => scenario.id === id)?.name,
visible: true,
fill: 'red', // TODO
fill: scenarioColors?.[id]?.[0] ?? 'transparent',
fillOpacity: 0.2 + 0.6 * (index / percentiles.length),
valueYField: 'percentileUp',
openValueYField: 'percentileDown',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2024 German Aerospace Center (DLR)
// SPDX-License-Identifier: Apache-2.0

import {Box, Button, Dialog, useTheme} from '@mui/material';
import Dialog from '@mui/material/Dialog';
import ConfirmDialog from '../../shared/ConfirmDialog';
import React, {Dispatch, useState} from 'react';
import ManageGroupDialog from './ManageGroupDialog';
Expand Down Expand Up @@ -48,7 +48,6 @@ export default function FilterDialogContainer({
const [groupEditorUnsavedChanges, setGroupEditorUnsavedChanges] = useState(false);
const {t: defaultT} = useTranslation();
const {t: customT} = useTranslation(localization.customLang);
const theme = useTheme();
const dispatch = useAppDispatch();

/**
Expand All @@ -66,108 +65,45 @@ export default function FilterDialogContainer({
};

return (
<>
<Box
id='scenario-footer-container'
sx={{
minHeight: '20vh',
paddingLeft: 4,
paddingRight: 4,
paddingTop: 2,
display: 'flex',
flexDirection: 'column',
}}
>
<Button
id='scenario-add-button'
variant='outlined'
color='success'
sx={{
height: '244px',
width: '200px',
fontWeight: 'bolder',
fontSize: '3rem',
border: `2px ${theme.palette.divider} dashed`,
borderRadius: '3px',
color: `${theme.palette.divider}`,
alignSelf: 'top',
'&:hover': {
border: `2px ${theme.palette.divider} dashed`,
background: '#E7E7E7',
},
}}
aria-label={
localization.overrides && localization.overrides['scenario.add']
? customT(localization.overrides['scenario.add'])
: defaultT('scenario.add')
}
>
+
</Button>
<Button
id='manage-filters-button'
variant='outlined'
color='primary'
sx={{
width: '200px',
alignSelf: 'center',
marginTop: '20px',
}}
onClick={() => {
setOpen(true);
dispatch(setIsFilterDialogOpen(true));
}}
aria-label={
localization.overrides && localization.overrides['group-filters.title']
? customT(localization.overrides['group-filters.title'])
: defaultT('group-filters.title')
}
>
{localization.overrides && localization.overrides['scenario.manage-groups']
? customT(localization.overrides['scenario.manage-groups'])
: defaultT('scenario.manage-groups')}
</Button>
</Box>
<Dialog id='manage-filters-dialog' maxWidth='lg' fullWidth={true} open={open} onClose={handleClose}>
<ManageGroupDialog
groupFilters={groupFilters}
setGroupFilters={setGroupFilters}
categories={categories}
groups={groups}
onCloseRequest={handleClose}
unsavedChangesCallback={(unsavedChanges) => setGroupEditorUnsavedChanges(unsavedChanges)}
localization={localization}
/>
<ConfirmDialog
open={closeDialogOpen}
title={
localization.overrides && localization.overrides['group-filters.confirm-discard-title']
? customT(localization.overrides['group-filters.confirm-discard-title'])
: defaultT('group-filters.confirm-discard-title')
}
text={
localization.overrides && localization.overrides['group-filters.confirm-discard-text']
? customT(localization.overrides['group-filters.confirm-discard-text'])
: defaultT('group-filters.confirm-discard-text')
<Dialog id='manage-filters-dialog' maxWidth='lg' fullWidth={true} open={open} onClose={handleClose}>
<ManageGroupDialog
groupFilters={groupFilters}
setGroupFilters={setGroupFilters}
categories={categories}
groups={groups}
onCloseRequest={handleClose}
unsavedChangesCallback={(unsavedChanges) => setGroupEditorUnsavedChanges(unsavedChanges)}
localization={localization}
/>
<ConfirmDialog
open={closeDialogOpen}
title={
localization?.overrides?.['group-filters.confirm-discard-title']
? customT(localization.overrides['group-filters.confirm-discard-title'])
: defaultT('group-filters.confirm-discard-title')
}
text={
localization?.overrides?.['group-filters.confirm-discard-text']
? customT(localization.overrides['group-filters.confirm-discard-text'])
: defaultT('group-filters.confirm-discard-text')
}
abortButtonText={
localization?.overrides?.['group-filters.close']
? customT(localization.overrides['group-filters.close'])
: defaultT('group-filters.close')
}
confirmButtonText={
localization?.overrides?.['group-filters.discard']
? customT(localization.overrides['group-filters.discard'])
: defaultT('group-filters.discard')
}
onAnswer={(answer) => {
if (answer) {
setOpen(false);
}
abortButtonText={
localization.overrides && localization.overrides['group-filters.close']
? customT(localization.overrides['group-filters.close'])
: defaultT('group-filters.close')
}
confirmButtonText={
localization.overrides && localization.overrides['group-filters.discard']
? customT(localization.overrides['group-filters.discard'])
: defaultT('group-filters.discard')
}
onAnswer={(answer) => {
if (answer) {
setOpen(false);
}
setCloseDialogOpen(false);
}}
/>
</Dialog>
</>
setCloseDialogOpen(false);
}}
/>
</Dialog>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ interface GroupFilterCardProps {
/** A function that allows setting the groupFilter state so that if the user adds a filter, the new filter will be visible */
toggleGroupFilter: Dispatch<GroupFilter>;

/** TODO */
/**
* Dispatch function to handle deletion of a group filter.
*/
deleteGroupFilter: Dispatch<string>;

/** Whether the filter is selected or not. If it is selected, the detail view is displaying this filter's config. */
Expand Down
Loading

0 comments on commit a5d02fc

Please sign in to comment.