Skip to content

Commit

Permalink
🔨 Reworking charts.
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasGilg committed Dec 9, 2024
1 parent 9798f46 commit 1829994
Show file tree
Hide file tree
Showing 31 changed files with 667 additions and 758 deletions.
66 changes: 61 additions & 5 deletions frontend/src/DataContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
useGetModelsQuery,
useGetGroupsQuery,
useGetGroupCategoriesQuery,
useGetModelQuery,
useGetMultiParameterDefinitionsQuery,
} from 'store/services/scenarioApi';
import data from '../assets/lk_germany_reduced.geojson?url';
import {GeoJSON, GeoJsonProperties} from 'geojson';
Expand All @@ -24,14 +26,19 @@ import {
Groups,
InfectionData,
InfectionDataParameters,
Model,
Models,
ParameterDefinition,
Scenario,
ScenarioPreview,
Scenarios,
} from './store/services/APITypes';
import {
selectCompartment,
selectDate,
selectScenario,
setActiveScenario,
setMinMaxDates,
setStartDate,
} from './store/DataSelectionSlice';

Expand All @@ -46,7 +53,10 @@ export const DataContext = createContext<{
groupCategories: GroupCategories | undefined;
groups: Groups | undefined;
scenarios: Scenarios | undefined;
selectedScenarioData: Scenario | undefined;
simulationModels: Models | undefined;
selectedSimulationModel: Model | undefined;
parameterDefinitions: Record<string, ParameterDefinition> | undefined;
compartments: Compartments | undefined;
}>({
geoData: undefined,
Expand All @@ -58,7 +68,10 @@ export const DataContext = createContext<{
groupCategories: undefined,
groups: undefined,
scenarios: undefined,
selectedScenarioData: undefined,
simulationModels: undefined,
selectedSimulationModel: undefined,
parameterDefinitions: undefined,
compartments: undefined,
});

Expand Down Expand Up @@ -115,6 +128,8 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
}
);

// TODO: GroupFilterData

const {data: lineChartData} = useGetMultiScenarioInfectionDataQuery(
{
pathIds: activeScenarios ?? [],
Expand All @@ -138,14 +153,22 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
},
});

const {data: selectedScenarioData} = useGetScenarioQuery(selectedScenario!, {skip: !selectedScenario});
const {data: simulationModels} = useGetModelsQuery();
const {data: selectedSimulationModel} = useGetModelQuery(selectedScenarioData!.modelId, {
skip: !selectedScenarioData,
});
const {data: parameterDefinitions} = useGetMultiParameterDefinitionsQuery(
selectedSimulationModel!.parameterDefinitions,
{skip: !selectedSimulationModel}
);
const {data: groups} = useGetGroupsQuery();
const {data: groupCategories} = useGetGroupCategoriesQuery();

// Try to set at least one active scenario.
useEffect(() => {
if (activeScenarios?.length === 0 && caseDataScenario) {
dispatch(setActiveScenario([caseDataScenario.id]));
dispatch(setActiveScenario({id: caseDataScenario.id, state: true}));
}
}, [activeScenarios, caseDataScenario, dispatch]);

Expand All @@ -170,6 +193,33 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
}
});

// Set start and end date.
useEffect(() => {
if (activeScenarios && scenarios) {
const active = activeScenarios
.map((activeScenario) => scenarios.find((scenario) => scenario.id === activeScenario))
.filter((scenario) => scenario !== undefined) as Array<ScenarioPreview>;

const minMax = active.reduce(
(
previous: {
min: string;
max: string;
},
current
) => ({
min: previous.min.localeCompare(current.startDate) < 0 ? previous.min : current.startDate,
max: previous.max.localeCompare(current.endDate) > 0 ? previous.max : current.endDate,
}),
{min: 'XXXX-XX-XX', max: '0000-00-00'}
);

if (minMax) {
dispatch(setMinMaxDates({minDate: minMax.min, maxDate: minMax.max}));
}
}
}, [activeScenarios, dispatch, scenarios]);

// Try to select a date if none is selected.
useEffect(() => {
if (!selectedDate && scenarios && scenarios.length > 0) {
Expand Down Expand Up @@ -232,20 +282,26 @@ export const DataProvider = ({children}: {children: React.ReactNode}) => {
groupCategories,
groups,
scenarios,
selectedScenarioData,
simulationModels,
selectedSimulationModel,
parameterDefinitions,
compartments,
}),
[
geoData,
groupCategories,
groups,
lineChartData,
mapData,
searchBarData,
lineChartData,
referenceDateValues,
scenarioCardData,
groupCategories,
groups,
scenarios,
searchBarData,
selectedScenarioData,
simulationModels,
selectedSimulationModel,
parameterDefinitions,
compartments,
]
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import CardContainer from 'components/ScenarioComponents/CardsComponents/CardContainer';
import React, {useState} from 'react';
import {FilterValue, CardValue} from 'types/card';
import {FilterValues, CardValues} from 'types/card';
import {GroupFilter} from 'types/group';
import {Dictionary} from 'util/util';
import {describe, test, expect} from 'vitest';
Expand All @@ -19,7 +19,7 @@ const CardContainerTest = () => {
const compartments = ['Compartment 1', 'Compartment 2', 'Compartment 3'];
const minCompartmentsRows = 1;
const maxCompartmentsRows = 3;
const filterValues: Dictionary<FilterValue[]> = {
const filterValues: Dictionary<FilterValues[]> = {
'Compartment 1': [
{filteredTitle: 'Title 1', filteredValues: {'Compartment 1': 10, 'Compartment 2': 20, 'Compartment 3': 30}},
],
Expand All @@ -35,7 +35,7 @@ const CardContainerTest = () => {
{id: 1, label: 'Scenario 2'},
{id: 2, label: 'Scenario 3'},
];
const cardValues: Dictionary<CardValue> = {
const cardValues: Dictionary<CardValues> = {
'0': {
compartmentValues: {'Compartment 1': 10, 'Compartment 2': 20, 'Compartment 3': 30},
startValues: {'Compartment 1': 100, 'Compartment 2': 200, 'Compartment 3': 307},
Expand Down Expand Up @@ -79,14 +79,14 @@ const CardContainerTest = () => {
<CardContainer
compartmentsExpanded={compartmentsExpanded}
filterValues={filterValues}
selectedCompartment={selectedCompartment}
selectedCompartmentId={selectedCompartment}
compartments={compartments}
scenarios={scenarios}
activeScenarios={activeScenarios}
cardValues={cardValues}
minCompartmentsRows={minCompartmentsRows}
maxCompartmentsRows={maxCompartmentsRows}
setActiveScenarios={setActiveScenarios}
setActiveScenario={setActiveScenarios}
setSelectedScenario={setSelectedScenario}
groupFilters={groupFilters}
selectedScenario={selectedScenario}
Expand All @@ -111,7 +111,7 @@ describe('CardContainer', () => {
});
const compartments: string[] = ['Compartment 1', 'Compartment 2', 'Compartment 3'];

const filterValues: Dictionary<FilterValue[]> = {
const filterValues: Dictionary<FilterValues[]> = {
'Compartment 1': [
{filteredTitle: 'Title 1', filteredValues: {'Compartment 1': 10, 'Compartment 2': 20, 'Compartment 3': 30}},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@ const DataCardTest = () => {
<DataCard
index={Index}
compartmentValues={CompartmentValues}
startValues={StartValues}
label={Label}
referenceValues={StartValues}
title={Label}
compartmentsExpanded={CompartmentsExpanded}
compartments={Compartments}
selectedCompartment={SelectedCompartment}
selectedScenario={SelectedScenario}
selectedCompartmentId={SelectedCompartment}
isSelected={SelectedScenario}
color={Color}
activeScenarios={activeScenarios}
isActive={activeScenarios}
filterValues={FilterValues}
numberSelectedScenario={Index}
minCompartmentsRows={MinCompartmentsRows}
maxCompartmentsRows={MaxCompartmentsRows}
setSelectedScenario={setSelectedScenario}
setSelected={setSelectedScenario}
setActiveScenarios={setActiveScenarios}
groupFilters={GroupFilters}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ describe('CardRows Component', () => {
index={0}
compartments={compartments}
compartmentValues={compartmentValues}
startValues={startValues}
selectedCompartment={selectedCompartment}
referenceValues={startValues}
selectedCompartmentId={selectedCompartment}
color={color}
minCompartmentsRows={minCompartmentsRows}
maxCompartmentsRows={maxCompartmentsRows}
Expand All @@ -51,8 +51,8 @@ describe('CardRows Component', () => {
index={0}
compartments={compartments}
compartmentValues={compartmentValues}
startValues={startValues}
selectedCompartment={selectedCompartment}
referenceValues={startValues}
selectedCompartmentId={selectedCompartment}
color={color}
minCompartmentsRows={minCompartmentsRows}
maxCompartmentsRows={maxCompartmentsRows}
Expand All @@ -71,8 +71,8 @@ describe('CardRows Component', () => {
index={0}
compartments={compartments}
compartmentValues={compartmentValues}
startValues={startValues}
selectedCompartment={selectedCompartment}
referenceValues={startValues}
selectedCompartmentId={selectedCompartment}
color={color}
minCompartmentsRows={minCompartmentsRows}
maxCompartmentsRows={maxCompartmentsRows}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ const CardTooltipTest = ({hovertest, scenarios, index, activeScenario}: CardTool
return (
<ThemeProvider theme={Theme}>
<CardTooltip
index={index}
id={index}
hover={hovertest}
color={color}
activeScenario={activeScenario}
isActive={activeScenario}
activeScenarios={activeScenarios}
numberSelectedScenario={numberSelectedScenario}
setActiveScenarios={setActiveScenarios}
setSelectedScenario={setSelectedScenario}
setActive={setActiveScenarios}
setSelected={setSelectedScenario}
/>
</ThemeProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ const MainCardTest = () => {
label={Label}
hover={hover}
compartmentValues={CompartmentValues}
startValues={StartValues}
referenceValues={StartValues}
setHover={setHover}
compartments={Compartments}
compartmentsExpanded={CompartmentsExpanded}
selectedCompartment={SelectedCompartment}
selectedCompartmentId={SelectedCompartment}
color={Color}
selectedScenario={SelectedScenario}
activeScenario={true}
isSelected={SelectedScenario}
isActive={true}
numberSelectedScenario={Index}
minCompartmentsRows={MinCompartmentsRows}
maxCompartmentsRows={MaxCompartmentsRows}
setSelectedScenario={setSelectedScenario}
setActiveScenarios={setActiveScenarios}
setSelected={setSelectedScenario}
setActive={setActiveScenarios}
activeScenarios={activeScenarios}
arrow={true}
/>
Expand Down
22 changes: 11 additions & 11 deletions frontend/src/components/LineChartComponents/LineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ interface LineChartProps {
chartId?: string;

/** Array of line chart data points to be plotted on the chart. */
lineChartData: LineChartData[] | undefined;
lineChartData: Array<LineChartData> | undefined;

/** The currently selected date in the chart in ISO format (YYYY-MM-DD). */
selectedDate: string;
selectedDate: string | null;

/** Callback function to update the selected date in the chart. */
setSelectedDate: (date: string) => void;
Expand Down Expand Up @@ -343,7 +343,7 @@ export default function LineChart({
return {
xAxis: xAxis,
yAxis: yAxis,
id: `${chartId}_${line.serieId}`,
id: `${chartId}_${line.seriesId}`,
name: line.name ?? '',
valueXField: 'date',
valueYField: String(line.valueYField),
Expand All @@ -353,8 +353,8 @@ export default function LineChart({
tooltip: Tooltip.new(root, {
labelText: line.tooltipText,
}),
stroke: line.stroke.color,
fill: line.fill ?? undefined,
stroke: line.stroke.color ? color(line.stroke.color) : undefined,
fill: line.fill ? color(line.fill) : undefined,
};
});
}, [lineChartData, root, xAxis, yAxis, chartId]);
Expand All @@ -366,7 +366,7 @@ export default function LineChart({
useCallback(
(series: LineSeries) => {
if (!lineChartData) return;
const seriesSettings = lineChartData.find((line) => line.serieId === series.get('id')?.split('_')[1]);
const seriesSettings = lineChartData.find((line) => line.seriesId === series.get('id')?.split('_')[1]);
series.strokes.template.setAll({
strokeWidth: seriesSettings?.stroke.strokeWidth ?? 2,
strokeDasharray: seriesSettings?.stroke.strokeDasharray ?? undefined,
Expand All @@ -393,7 +393,7 @@ export default function LineChart({
const dataMap = new Map<string, {[key: string]: number}>();

lineChartData.forEach((serie) => {
const id = serie.serieId;
const id = serie.seriesId;
if (typeof id === 'string' && id.startsWith('group-filter-')) {
serie.values.forEach((entry) => {
dataMap.set(entry.day, {...dataMap.get(entry.day), [serie.name!]: entry.value as number});
Expand Down Expand Up @@ -585,17 +585,17 @@ export default function LineChart({

if (lineChartData) {
lineChartData.forEach((serie) => {
if (serie.serieId === 'percentiles' || serie.serieId.toString().startsWith('group-filter-')) return;
if (serie.seriesId === 'percentiles' || serie.seriesId.toString().startsWith('group-filter-')) return;

// Add scenario label to export data field names
dataFields = {
...dataFields,
[String(serie.serieId)]: serie.name ?? '',
[String(serie.seriesId)]: serie.name ?? '',
};
// Add scenario id to export data field order (for sorted export like csv)
dataFieldsOrder.push(`${serie.serieId}`);
dataFieldsOrder.push(`${serie.seriesId}`);
// If this is the selected scenario also add percentiles after it
if (lineChartData.find((line) => line.openValueYField && line.parentId == serie.serieId)) {
if (lineChartData.find((line) => line.openValueYField && line.parentId == serie.seriesId)) {
dataFieldsOrder.push('percentileDown', 'percentileUp');
}
});
Expand Down
Loading

0 comments on commit 1829994

Please sign in to comment.