forked from equinor/webviz
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactored SimulationTimeSeries with Jotai atoms
- Loading branch information
1 parent
76dc727
commit e384041
Showing
31 changed files
with
3,216 additions
and
630 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
frontend/src/modules/SimulationTimeSeries/atoms/baseAtoms.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Frequency_api, StatisticFunction_api } from "@api"; | ||
import { atom } from "jotai"; | ||
import { isEqual } from "lodash"; | ||
import { FanchartStatisticOption, GroupBy, StatisticsSelection, VisualizationMode } from "../typesAndEnums"; | ||
import { EnsembleIdent } from "@framework/EnsembleIdent"; | ||
import { atomWithCompare } from "@framework/utils/atomUtils"; | ||
import { ParameterIdent } from "@framework/EnsembleParameters"; | ||
|
||
export const resampleFrequencyAtom = atom<Frequency_api | null>(Frequency_api.MONTHLY); | ||
|
||
export const groupByAtom = atom<GroupBy>(GroupBy.TIME_SERIES); | ||
|
||
export const colorRealizationsByParameterAtom = atom<boolean>(false); | ||
|
||
export const visualizationModeAtom = atom<VisualizationMode>(VisualizationMode.STATISTICAL_FANCHART); | ||
|
||
export const showHistoricalAtom = atom<boolean>(true); | ||
|
||
export const showObservationsAtom = atom<boolean>(true); | ||
|
||
export const statisticsSelectionAtom = atom<StatisticsSelection>({ | ||
IndividualStatisticsSelection: Object.values(StatisticFunction_api), | ||
FanchartStatisticsSelection: Object.values(FanchartStatisticOption), | ||
}); | ||
|
||
export const userSelectedEnsembleIdentsAtom = atomWithCompare<EnsembleIdent[]>([], isEqual); | ||
|
||
export const selectedVectorNamesAtom = atomWithCompare<string[]>([], isEqual); | ||
|
||
export const filteredParameterIdentListAtom = atom<ParameterIdent[]>([]); | ||
|
||
export const userSelectedParameterIdentStringAtom = atom<string | null>(null); | ||
|
||
export const userSelectedActiveTimestampUtcMsAtom = atom<number | null>(null); |
201 changes: 201 additions & 0 deletions
201
frontend/src/modules/SimulationTimeSeries/atoms/derivedSettingsAtoms.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
import { EnsembleIdent } from "@framework/EnsembleIdent"; | ||
import { StatisticsType, VectorSpec, VisualizationMode } from "../typesAndEnums"; | ||
import { filteredParameterIdentListAtom, selectedVectorNamesAtom, userSelectedEnsembleIdentsAtom, userSelectedParameterIdentStringAtom, visualizationModeAtom } from "./baseAtoms"; | ||
import { EnsembleSetAtom } from "@framework/GlobalAtoms"; | ||
import { fixupEnsembleIdents } from "@framework/utils/ensembleUiHelpers"; | ||
import { Ensemble } from "@framework/Ensemble"; | ||
|
||
import { atom } from "jotai"; | ||
|
||
import { isEqual } from "lodash"; | ||
import { Parameter, ParameterIdent, ParameterType } from "@framework/EnsembleParameters"; | ||
import { vectorListQueriesAtom } from "./queryAtoms"; | ||
import { VectorDescription_api } from "@api"; | ||
import { createVectorSelectorDataFromVectors } from "@framework/components/VectorSelector"; | ||
import { EnsembleVectorListsHelper } from "../utils/ensemblesVectorListHelper"; | ||
|
||
export const statisticsTypeAtom = atom<StatisticsType>((get) => { | ||
const visualizationMode = get(visualizationModeAtom); | ||
|
||
if (visualizationMode === VisualizationMode.STATISTICAL_FANCHART) { | ||
return StatisticsType.FANCHART; | ||
} | ||
|
||
return StatisticsType.INDIVIDUAL; | ||
}); | ||
|
||
|
||
export const selectedEnsembleIdentsAtom = atom<EnsembleIdent[]>((get) => { | ||
const ensembleSet = get(EnsembleSetAtom); | ||
const selectedEnsembleIdents = get(userSelectedEnsembleIdentsAtom); | ||
|
||
const newSelectedEnsembleIdents = selectedEnsembleIdents.filter((ensemble) => ensembleSet.hasEnsemble(ensemble)); | ||
|
||
const validatedEnsembleIdents = fixupEnsembleIdents(newSelectedEnsembleIdents, ensembleSet); | ||
|
||
return validatedEnsembleIdents ?? []; | ||
}); | ||
|
||
export const selectedEnsemblesAtom = atom((get) => { | ||
const ensembleSet = get(EnsembleSetAtom); | ||
const selectedEnsembleIdents = get(selectedEnsembleIdentsAtom); | ||
|
||
const selectedEnsembles: Ensemble[] = []; | ||
|
||
for (const ensembleIdent of selectedEnsembleIdents) { | ||
const ensemble = ensembleSet.findEnsemble(ensembleIdent); | ||
if (ensemble) { | ||
selectedEnsembles.push(ensemble); | ||
} | ||
} | ||
|
||
return selectedEnsembles; | ||
}); | ||
|
||
export const continuousAndNonConstantParametersUnionAtom = atom<Parameter[]>((get) => { | ||
const ensembleSet = get(EnsembleSetAtom); | ||
const selectedEnsembleIdents = get(selectedEnsembleIdentsAtom); | ||
|
||
const continuousAndNonConstantParametersUnion: Parameter[] = []; | ||
|
||
for (const ensembleIdent of selectedEnsembleIdents) { | ||
const ensemble = ensembleSet.findEnsemble(ensembleIdent); | ||
|
||
if (!ensemble) { | ||
continue; | ||
} | ||
|
||
const continuousAndNonConstantParameters = ensemble | ||
.getParameters() | ||
.getParameterArr() | ||
.filter((parameter) => parameter.type === ParameterType.CONTINUOUS && !parameter.isConstant); | ||
|
||
// Add non-duplicate parameters to list - verified by ParameterIdent | ||
for (const parameter of continuousAndNonConstantParameters) { | ||
const parameterIdent = ParameterIdent.fromNameAndGroup(parameter.name, parameter.groupName); | ||
const isParameterInUnion = continuousAndNonConstantParametersUnion.some((elm) => | ||
parameterIdent.equals(ParameterIdent.fromNameAndGroup(elm.name, elm.groupName)) | ||
); | ||
|
||
if (isParameterInUnion) continue; | ||
continuousAndNonConstantParametersUnion.push(parameter); | ||
} | ||
} | ||
|
||
return continuousAndNonConstantParametersUnion; | ||
}); | ||
|
||
|
||
export const vectorListDataAtom = atom<(VectorDescription_api[] | null)[]>((get) => { | ||
const vectorListQueries = get(vectorListQueriesAtom); | ||
const oldVectorListData: (VectorDescription_api[] | null)[] = get(vectorListDataAtom); | ||
|
||
const newVectorListData = vectorListQueries.map((query) => { | ||
return query.data ?? null; | ||
}); | ||
|
||
if (isEqual(newVectorListData, oldVectorListData)) { | ||
return oldVectorListData; | ||
} | ||
|
||
return newVectorListData; | ||
}); | ||
|
||
export const isVectorListQueriesFetchingAtom = atom<boolean>((get) => { | ||
const vectorListQueries = get(vectorListQueriesAtom); | ||
|
||
return vectorListQueries.some((query) => query.isFetching); | ||
}); | ||
|
||
export const availableVectorNamesAtom = atom((get) => { | ||
const ensembleVectorListsHelper = get(ensembleVectorListsHelperAtom); | ||
|
||
const vectorNamesUnion = ensembleVectorListsHelper.vectorsUnion(); | ||
|
||
return vectorNamesUnion; | ||
}); | ||
|
||
export const vectorSelectorDataAtom = atom((get) => { | ||
const isFetching = get(isVectorListQueriesFetchingAtom); | ||
const availableVectorNames = get(availableVectorNamesAtom); | ||
|
||
if (isFetching) { | ||
return []; | ||
} | ||
|
||
return createVectorSelectorDataFromVectors(availableVectorNames); | ||
}); | ||
|
||
export const ensembleVectorListsHelperAtom = atom((get) => { | ||
const vectorListQueries = get(vectorListQueriesAtom); | ||
const selectedEnsembleIdents = get(selectedEnsembleIdentsAtom); | ||
|
||
return new EnsembleVectorListsHelper(selectedEnsembleIdents, vectorListQueries); | ||
}); | ||
|
||
|
||
export const vectorSpecificationsAtom = atom<VectorSpec[]>((get) => { | ||
const ensembleVectorListsHelper = get(ensembleVectorListsHelperAtom); | ||
const selectedEnsembleIdents = get(selectedEnsembleIdentsAtom); | ||
const selectedVectorNames = get(selectedVectorNamesAtom); | ||
|
||
const vectorSpecifications: VectorSpec[] = []; | ||
|
||
for (const ensembleIdent of selectedEnsembleIdents) { | ||
for (const vectorName of selectedVectorNames) { | ||
if (!ensembleVectorListsHelper.isVectorInEnsemble(ensembleIdent, vectorName)) { | ||
continue; | ||
} | ||
|
||
vectorSpecifications.push({ | ||
ensembleIdent, | ||
vectorName, | ||
hasHistoricalVector: ensembleVectorListsHelper.hasHistoricalVector(ensembleIdent, vectorName), | ||
}); | ||
} | ||
} | ||
|
||
return vectorSpecifications; | ||
}); | ||
|
||
export const selectedParameterIdentStringAtom = atom<string | null>((get) => { | ||
const filteredParameterIdentList = get(filteredParameterIdentListAtom); | ||
const userSelectedParameterIdentString = get(userSelectedParameterIdentStringAtom); | ||
|
||
if (filteredParameterIdentList.length === 0) { | ||
return null; | ||
} | ||
|
||
if (userSelectedParameterIdentString === null) { | ||
return filteredParameterIdentList[0].toString(); | ||
} | ||
|
||
if (filteredParameterIdentList.some((elm) => elm.toString() === userSelectedParameterIdentString)) { | ||
return userSelectedParameterIdentString; | ||
} | ||
|
||
return filteredParameterIdentList[0].toString(); | ||
}); | ||
|
||
export const parameterIdentAtom = atom<ParameterIdent | null>((get) => { | ||
const selectedParameterIdentString = get(selectedParameterIdentStringAtom); | ||
const filteredParameterIdentList = get(filteredParameterIdentListAtom); | ||
|
||
if (selectedParameterIdentString === null) { | ||
return null; | ||
} | ||
|
||
try { | ||
const newParameterIdent = ParameterIdent.fromString(selectedParameterIdentString); | ||
const isParameterAmongFiltered = filteredParameterIdentList.some((parameter) => | ||
parameter.equals(newParameterIdent) | ||
); | ||
if (isParameterAmongFiltered) { | ||
return newParameterIdent; | ||
} else { | ||
return null; | ||
} | ||
} catch { | ||
return null; | ||
} | ||
}); |
98 changes: 98 additions & 0 deletions
98
frontend/src/modules/SimulationTimeSeries/atoms/derivedViewAtoms.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { atom } from "jotai"; | ||
import { historicalVectorDataQueriesAtom, vectorDataQueriesAtom, vectorObservationsQueriesAtom, vectorStatisticsQueriesAtom } from "./queryAtoms"; | ||
import { createLoadedVectorSpecificationAndDataArray } from "../utils/vectorSpecificationsAndQueriesUtils"; | ||
import { parameterIdentAtom, selectedEnsemblesAtom, vectorSpecificationsAtom } from "./derivedSettingsAtoms"; | ||
import { colorRealizationsByParameterAtom, userSelectedActiveTimestampUtcMsAtom, visualizationModeAtom } from "./baseAtoms"; | ||
import { VisualizationMode } from "../typesAndEnums"; | ||
|
||
export const queryIsFetchingAtom = atom((get) => { | ||
const vectorDataQueries = get(vectorDataQueriesAtom); | ||
const vectorStatisticsQueries = get(vectorStatisticsQueriesAtom); | ||
const historicalVectorDataQueries = get(historicalVectorDataQueriesAtom); | ||
const vectorObservationsQueries = get(vectorObservationsQueriesAtom); | ||
|
||
const vectorDataIsFetching = vectorDataQueries.some((query) => query.isFetching); | ||
const vectorStatisticsIsFetching = vectorStatisticsQueries.some((query) => query.isFetching); | ||
const historicalVectorDataIsFetching = historicalVectorDataQueries.some((query) => query.isFetching); | ||
const vectorObservationsIsFetching = vectorObservationsQueries.isFetching; | ||
|
||
const isFetching = ( | ||
vectorDataIsFetching || | ||
vectorStatisticsIsFetching || | ||
historicalVectorDataIsFetching || | ||
vectorObservationsIsFetching | ||
); | ||
|
||
return isFetching; | ||
}); | ||
|
||
export const realizationsQueryHasErrorAtom = atom((get) => { | ||
const vectorDataQueries = get(vectorDataQueriesAtom); | ||
|
||
return vectorDataQueries.some((query) => query.isError); | ||
}); | ||
|
||
export const statisticsQueryHasErrorAtom = atom((get) => { | ||
const vectorStatisticsQueries = get(vectorStatisticsQueriesAtom); | ||
|
||
return vectorStatisticsQueries.some((query) => query.isError); | ||
}); | ||
|
||
export const historicalDataQueryHasErrorAtom = atom((get) => { | ||
const historicalVectorDataQueries = get(historicalVectorDataQueriesAtom); | ||
|
||
return historicalVectorDataQueries.some((query) => query.isError); | ||
}); | ||
|
||
export const loadedVectorSpecificationsAndRealizationDataAtom = atom((get) => { | ||
const vectorDataQueries = get(vectorDataQueriesAtom); | ||
const vectorSpecifications = get(vectorSpecificationsAtom); | ||
|
||
return createLoadedVectorSpecificationAndDataArray(vectorSpecifications, vectorDataQueries); | ||
}); | ||
|
||
export const loadedVectorSpecificationsAndStatisticsDataAtom = atom((get) => { | ||
const vectorStatisticsQueries = get(vectorStatisticsQueriesAtom); | ||
const vectorSpecifications = get(vectorSpecificationsAtom); | ||
|
||
return createLoadedVectorSpecificationAndDataArray(vectorSpecifications, vectorStatisticsQueries); | ||
}); | ||
|
||
export const loadedVectorSpecificationsAndHistoricalDataAtom = atom((get) => { | ||
const historicalVectorDataQueries = get(historicalVectorDataQueriesAtom); | ||
const vectorSpecifications = get(vectorSpecificationsAtom); | ||
|
||
return createLoadedVectorSpecificationAndDataArray(vectorSpecifications, historicalVectorDataQueries); | ||
}); | ||
|
||
export const activeTimestampUtcMsAtom = atom<number | null>((get) => { | ||
const loadedVectorSpecificationsAndRealizationData = get(loadedVectorSpecificationsAndRealizationDataAtom); | ||
const isQueryFetching = get(queryIsFetchingAtom); | ||
const userSelectedActiveTimestampUtcMs = get(userSelectedActiveTimestampUtcMsAtom); | ||
|
||
if ( | ||
!isQueryFetching && | ||
userSelectedActiveTimestampUtcMs === null && | ||
loadedVectorSpecificationsAndRealizationData.length > 0 | ||
) { | ||
const firstTimeStamp = | ||
loadedVectorSpecificationsAndRealizationData.at(0)?.data.at(0)?.timestamps_utc_ms[0] ?? null; | ||
return firstTimeStamp; | ||
} | ||
|
||
return userSelectedActiveTimestampUtcMs; | ||
}); | ||
|
||
export const colorByParameterAtom = atom<boolean>((get) => { | ||
const colorRealizationsByParameter = get(colorRealizationsByParameterAtom); | ||
const visualizationMode = get(visualizationModeAtom); | ||
const parameterIdent = get(parameterIdentAtom); | ||
const selectedEnsembles = get(selectedEnsemblesAtom); | ||
|
||
return ( | ||
colorRealizationsByParameter && | ||
visualizationMode === VisualizationMode.INDIVIDUAL_REALIZATIONS && | ||
parameterIdent !== null && | ||
selectedEnsembles.some((ensemble) => ensemble.getParameters().hasParameter(parameterIdent)) | ||
); | ||
}); |
Oops, something went wrong.