diff --git a/frontend/docs/changelog/changelog-de.md b/frontend/docs/changelog/changelog-de.md index 45542b35..6c81d211 100644 --- a/frontend/docs/changelog/changelog-de.md +++ b/frontend/docs/changelog/changelog-de.md @@ -22,6 +22,7 @@ SPDX-License-Identifier: CC-BY-4.0 - Fehlende Übersetzungen wurden ergänzt. - Die Auswahl der Farblegenden zeigt jetzt wieder eine Vorschau für alle Optionen. - Die Parameter werden jetzt korrekt dem ausgewählten Szenario zugeordnet und eine Info wird angezeigt, wenn keine Parameter verfügbar sind. +- Die Farben der Szenarien wurden zum Teil falsch berechnet, was zu mehreren Szenarien mit den gleichen Farben führte. --- diff --git a/frontend/docs/changelog/changelog-en.md b/frontend/docs/changelog/changelog-en.md index c06cf1f7..253820df 100644 --- a/frontend/docs/changelog/changelog-en.md +++ b/frontend/docs/changelog/changelog-en.md @@ -22,6 +22,7 @@ SPDX-License-Identifier: CC-BY-4.0 - Missing translations were fixed. - The heat legend selection now shows a preview for all legends again. - The Parameters will now correctly be associated with the selected scenario and an info will be displayed, when no parameters are available. +- The colors of the scenarios was calculated wrongly which could lead to multiple scenarios with the same colors. --- diff --git a/frontend/src/components/Scenario/DataCardList.tsx b/frontend/src/components/Scenario/DataCardList.tsx index 67b02076..d6bf4c17 100644 --- a/frontend/src/components/Scenario/DataCardList.tsx +++ b/frontend/src/components/Scenario/DataCardList.tsx @@ -17,6 +17,7 @@ import { import {setCompartments, setScenarios} from '../../store/ScenarioSlice'; import {useGetSimulationStartValues} from './hooks'; import {useGetCaseDataByDistrictQuery} from '../../store/services/caseDataApi'; +import {getScenarioPrimaryColor} from '../../util/Theme'; export default function DataCardList(): JSX.Element { const theme = useTheme(); @@ -139,13 +140,13 @@ export default function DataCardList(): JSX.Element { onClick={() => dispatch(selectScenario(0))} onToggle={() => dispatch(toggleScenario(0))} /> - {Object.entries(scenarioList.scenarios).map(([, scenario], i) => ( + {Object.entries(scenarioList.scenarios).map(([, scenario]) => ( { // set active scenario to this one and send dispatches diff --git a/frontend/src/components/Scenario/ScenarioCard.tsx b/frontend/src/components/Scenario/ScenarioCard.tsx index bddb7282..1f83eb56 100644 --- a/frontend/src/components/Scenario/ScenarioCard.tsx +++ b/frontend/src/components/Scenario/ScenarioCard.tsx @@ -8,6 +8,7 @@ import {useGetSingleSimulationEntryQuery} from 'store/services/scenarioApi'; import {Dictionary} from '../../util/util'; import {useTranslation} from 'react-i18next'; import {DataCard} from './DataCard'; +import {getScenarioPrimaryColor} from '../../util/Theme'; /** Type definition for the ScenarioCard props */ interface ScenarioCardProps { @@ -75,7 +76,7 @@ export function ScenarioCard(props: ScenarioCardProps): JSX.Element { 0 - ? color(theme.custom.scenarios[selectedScenario % theme.custom.scenarios.length][0]) + ? color(getScenarioPrimaryColor(selectedScenario, theme)) : undefined, }) ); @@ -315,11 +316,11 @@ export default function SimulationChart(): JSX.Element { // Fallback Tooltip (if HTML breaks for some reason) // For text color: loop around the theme's scenario color list if scenario IDs exceed color list length, then pick first color of sub-palette which is the main color tooltip: Tooltip.new(root, { - labelText: `[bold ${theme.custom.scenarios[scenario.id % theme.custom.scenarios.length][0]}]${tBackend( + labelText: `[bold ${getScenarioPrimaryColor(scenario.id, theme)}]${tBackend( `scenario-names.${scenario.label}` )}:[/] {${scenarioId}}`, }), - stroke: color(theme.custom.scenarios[scenario.id % theme.custom.scenarios.length][0]), + stroke: color(getScenarioPrimaryColor(scenario.id, theme)), }) ); series.strokes.template.setAll({ @@ -353,11 +354,11 @@ export default function SimulationChart(): JSX.Element { // Fallback Tooltip (if HTML breaks for some reason) // Use color of selected scenario (scenario ID is 1-based index, color list is 0-based index) loop if scenario ID exceeds length of color list; use first color of palette (main color) tooltip: Tooltip.new(root, { - labelText: `[bold ${theme.custom.scenarios[selectedScenario % theme.custom.scenarios.length][0]}]${ + labelText: `[bold ${getScenarioPrimaryColor(selectedScenario, theme)}]${ groupFilter.name }:[/] {${groupFilter.name}}`, }), - stroke: color(theme.custom.scenarios[selectedScenario % theme.custom.scenarios.length][0]), + stroke: color(getScenarioPrimaryColor(selectedScenario, theme)), }) ); series.strokes.template.setAll({ diff --git a/frontend/src/util/Theme.ts b/frontend/src/util/Theme.ts index 4ee6c77e..ea9ba5eb 100644 --- a/frontend/src/util/Theme.ts +++ b/frontend/src/util/Theme.ts @@ -3,7 +3,7 @@ // add List Element typography using module augmentation import React from 'react'; -import {createTheme} from '@mui/material/styles'; +import {createTheme, Theme} from '@mui/material/styles'; declare module '@mui/material/styles' { interface TypographyVariants { @@ -159,3 +159,17 @@ export default createTheme({ ], }, }); + +/** + * This function assigns a color palette to a scenario and consistently returns the same palette for the same id. + */ +export function getScenarioColorPalette(scenarioId: number, theme: Theme): Array { + return theme.custom.scenarios[(scenarioId % (theme.custom.scenarios.length - 1)) + 1]; +} + +/** + * This function assigns a primary color to a scenario and consistently returns the same color for the same id. + */ +export function getScenarioPrimaryColor(scenarioId: number, theme: Theme): string { + return getScenarioColorPalette(scenarioId, theme)[0]; +}