diff --git a/frontend/src/modules/SimulationTimeSeriesMatrix/settings.tsx b/frontend/src/modules/SimulationTimeSeriesMatrix/settings.tsx index ba6704345..feaa5343e 100644 --- a/frontend/src/modules/SimulationTimeSeriesMatrix/settings.tsx +++ b/frontend/src/modules/SimulationTimeSeriesMatrix/settings.tsx @@ -17,6 +17,7 @@ import { Label } from "@lib/components/Label"; import { RadioGroup } from "@lib/components/RadioGroup"; import { SmartNodeSelectorSelection, TreeDataNode } from "@lib/components/SmartNodeSelector"; import { VectorSelector } from "@lib/components/VectorSelector"; +import { useValidState } from "@lib/hooks/useValidState"; import { resolveClassNames } from "@lib/utils/resolveClassNames"; import { createVectorSelectorDataFromVectors } from "@lib/utils/vectorSelectorUtils"; @@ -45,11 +46,11 @@ export function settings({ moduleContext, workbenchSession }: ModuleFCProps([]); const [prevVisualizationMode, setPrevVisualizationMode] = React.useState(visualizationMode); - if (prevVisualizationMode !== visualizationMode) { + if (visualizationMode !== prevVisualizationMode) { setPrevVisualizationMode(visualizationMode); } + if (!isEqual(ensembleSet, previousEnsembleSet)) { + const newSelectedEnsembleIdents = selectedEnsembleIdents.filter( + (ensemble) => ensembleSet.findEnsemble(ensemble) !== null + ); + const validatedEnsembleIdents = fixupEnsembleIdents(newSelectedEnsembleIdents, ensembleSet) ?? []; + if (!isEqual(selectedEnsembleIdents, validatedEnsembleIdents)) { + setSelectedEnsembleIdents(validatedEnsembleIdents); + } + + setPreviousEnsembleSet(ensembleSet); + } + // Queries const vectorListQueries = useVectorListQueries(selectedEnsembleIdents); const ensembleVectorListsHelper = new EnsembleVectorListsHelper(selectedEnsembleIdents, vectorListQueries); - const vectorsUnion = ensembleVectorListsHelper.vectorsUnion(); const selectedVectorNamesHasHistorical = ensembleVectorListsHelper.hasAnyHistoricalVector(selectedVectorNames); - const currentVectorSelectorData = createVectorSelectorDataFromVectors(vectorsUnion); + const currentVectorSelectorData = createVectorSelectorDataFromVectors(ensembleVectorListsHelper.vectorsUnion()); - // Get union of continuous parameters for selected ensembles - const continuousParametersUnion: ParameterIdent[] = []; + // Get union of continuous and non-constant parameters for selected ensembles and set valid parameter ident str + const continuousAndNonConstantParametersUnion: ParameterIdent[] = []; for (const ensembleIdent of selectedEnsembleIdents) { const ensemble = ensembleSet.findEnsemble(ensembleIdent); if (ensemble === null) continue; for (const parameter of ensemble.getParameters().getParameterIdents(ParameterType.CONTINUOUS)) { - if (continuousParametersUnion.some((param) => param.equals(parameter))) continue; - - // TODO: Check if parameter is constant? + if (continuousAndNonConstantParametersUnion.some((param) => param.equals(parameter))) continue; if (ensemble.getParameters().getParameter(parameter).isConstant) continue; - continuousParametersUnion.push(parameter); + continuousAndNonConstantParametersUnion.push(parameter); } } + const [selectedParameterIdentStr, setSelectedParameterIdentStr] = useValidState(null, [ + continuousAndNonConstantParametersUnion, + (item: ParameterIdent) => item.toString(), + ]); - // Only update if all vector lists are retrieved before updating vectorSelectorData has changed + // Await update of vectorSelectorData until all vector lists are retrieved const hasVectorListQueriesErrorOrLoading = vectorListQueries.some((query) => query.isLoading || query.isError); if (!hasVectorListQueriesErrorOrLoading && !isEqual(currentVectorSelectorData, vectorSelectorData)) { setVectorSelectorData(currentVectorSelectorData); } - if (!isEqual(ensembleSet, previousEnsembleSet)) { - const newSelectedEnsembleIdents = selectedEnsembleIdents.filter( - (ensemble) => ensembleSet.findEnsemble(ensemble) !== null - ); - const validatedEnsembleIdents = fixupEnsembleIdents(newSelectedEnsembleIdents, ensembleSet) ?? []; - if (!isEqual(selectedEnsembleIdents, validatedEnsembleIdents)) { - setSelectedEnsembleIdents(validatedEnsembleIdents); - } - - setPreviousEnsembleSet(ensembleSet); - } - React.useEffect( function propagateVectorSpecsToView() { const newVectorSpecifications: VectorSpec[] = []; @@ -120,20 +122,36 @@ export function settings({ moduleContext, workbenchSession }: ModuleFCProps parameter.equals(newParameterIdent)) + ? setParameterIdent(newParameterIdent) + : setParameterIdent(null); + } catch { + setParameterIdent(null); + } + }, + [selectedParameterIdentStr] + ); + function handleGroupByChange(event: React.ChangeEvent) { setGroupBy(event.target.value as GroupBy); } function handleColorByParameterChange(parameterIdentStr: string) { - const parameterIdent = ParameterIdent.fromString(parameterIdentStr); - const newParameterIdent = continuousParametersUnion.find((elm) => elm.equals(parameterIdent)) ?? null; - setParameterIdent(newParameterIdent); + setSelectedParameterIdentStr(parameterIdentStr); } function handleEnsembleSelectChange(ensembleIdentArr: EnsembleIdent[]) { @@ -263,7 +281,6 @@ export function settings({ moduleContext, workbenchSession }: ModuleFCProps - + { @@ -291,10 +308,13 @@ export function settings({ moduleContext, workbenchSession }: ModuleFCProps { - return { value: elm.toString(), label: elm.toString() }; + options={continuousAndNonConstantParametersUnion.map((elm) => { + return { + value: elm.toString(), + label: elm.groupName ? `${elm.groupName}:${elm.name}` : elm.name, + }; })} - value={parameterIdent?.toString() ?? undefined} + value={selectedParameterIdentStr?.toString() ?? undefined} onChange={handleColorByParameterChange} /> diff --git a/frontend/src/modules/SimulationTimeSeriesMatrix/utils/PlotlyTraceUtils/createVectorTracesUtils.ts b/frontend/src/modules/SimulationTimeSeriesMatrix/utils/PlotlyTraceUtils/createVectorTracesUtils.ts index c21cbbdb7..2bbb9dfc7 100644 --- a/frontend/src/modules/SimulationTimeSeriesMatrix/utils/PlotlyTraceUtils/createVectorTracesUtils.ts +++ b/frontend/src/modules/SimulationTimeSeriesMatrix/utils/PlotlyTraceUtils/createVectorTracesUtils.ts @@ -5,8 +5,6 @@ import { VectorStatisticData_api, } from "@api"; -import { type } from "os"; - import { FanchartData, FreeLineData, LowHighData, MinMaxData } from "./fanchartPlotting"; import { createFanchartTraces } from "./fanchartPlotting"; import { LineData, StatisticsData, createStatisticsTraces } from "./statisticsPlotting"; diff --git a/frontend/src/modules/SimulationTimeSeriesMatrix/utils/parameterColoringUtils.ts b/frontend/src/modules/SimulationTimeSeriesMatrix/utils/ensemblesContinuousParameterColoring.ts similarity index 71% rename from frontend/src/modules/SimulationTimeSeriesMatrix/utils/parameterColoringUtils.ts rename to frontend/src/modules/SimulationTimeSeriesMatrix/utils/ensemblesContinuousParameterColoring.ts index b5d7457d4..137569aa8 100644 --- a/frontend/src/modules/SimulationTimeSeriesMatrix/utils/parameterColoringUtils.ts +++ b/frontend/src/modules/SimulationTimeSeriesMatrix/utils/ensemblesContinuousParameterColoring.ts @@ -3,16 +3,22 @@ import { ContinuousParameter, ParameterIdent, ParameterType } from "@framework/E import { ColorScale } from "@lib/utils/ColorScale"; import { MinMax } from "@lib/utils/MinMax"; -export class ContinuousParameterColorScaleHelper { +export class EnsemblesContinuousParameterColoring { + /** + * Helper class working with coloring according to selected continuous parameter across multiple ensembles + * + * Retrieves min/max parameter value across all ensembles and provides interface for retrieving parameter + * value within the min/max range for specific realization in ensemble. + */ + private _parameterIdent: ParameterIdent; private _ensembleContinuousParameterSet: { [ensembleName: string]: ContinuousParameter }; - private _minMax: MinMax; private _colorScale: ColorScale; - constructor(parameterIdent: ParameterIdent, selectedEnsembles: Ensemble[], colorScale: ColorScale) { + constructor(selectedEnsembles: Ensemble[], parameterIdent: ParameterIdent, colorScale: ColorScale) { this._parameterIdent = parameterIdent; this._ensembleContinuousParameterSet = {}; - this._minMax = MinMax.createInvalid(); + let minMax = MinMax.createInvalid(); for (const ensemble of selectedEnsembles) { const parameters = ensemble.getParameters(); if (!parameters.hasParameter(parameterIdent)) continue; @@ -20,28 +26,20 @@ export class ContinuousParameterColorScaleHelper { const parameter = parameters.getParameter(parameterIdent); if (parameter.type === ParameterType.CONTINUOUS) { this._ensembleContinuousParameterSet[ensemble.getEnsembleName()] = parameter; - this._minMax = this._minMax.extendedBy(parameters.getContinuousParameterMinMax(parameterIdent)); + minMax = minMax.extendedBy(parameters.getContinuousParameterMinMax(parameterIdent)); } } - // TODO: Set Range [0,0] if parameterMinMax is invalid? + // Consider: Set Range [0,0] if parameterMinMax is invalid? this._colorScale = colorScale; - const midValue = this._minMax.min + (this._minMax.max - this._minMax.min) / 2; - this._colorScale.setRangeAndMidPoint(this._minMax.min, this._minMax.max, midValue); + const midValue = minMax.min + (minMax.max - minMax.min) / 2; + this._colorScale.setRangeAndMidPoint(minMax.min, minMax.max, midValue); } getColorScale(): ColorScale { return this._colorScale; } - getMinMax(): MinMax { - return this._minMax; - } - - getParameterIdent(): ParameterIdent { - return this._parameterIdent; - } - hasEnsembleName(ensembleName: string): boolean { return ensembleName in this._ensembleContinuousParameterSet; } diff --git a/frontend/src/modules/SimulationTimeSeriesMatrix/utils/subplotBuilder.ts b/frontend/src/modules/SimulationTimeSeriesMatrix/utils/subplotBuilder.ts index f09e22e2a..303bd8b20 100644 --- a/frontend/src/modules/SimulationTimeSeriesMatrix/utils/subplotBuilder.ts +++ b/frontend/src/modules/SimulationTimeSeriesMatrix/utils/subplotBuilder.ts @@ -1,5 +1,4 @@ import { VectorHistoricalData_api, VectorRealizationData_api, VectorStatisticData_api } from "@api"; -import { ColorScale } from "@lib/utils/ColorScale"; import { ColorSet } from "@lib/utils/ColorSet"; import { PlotMarker } from "plotly.js"; @@ -14,7 +13,7 @@ import { createVectorStatisticsTraces, } from "./PlotlyTraceUtils/createVectorTracesUtils"; import { scaleHexColorLightness } from "./colorUtils"; -import { ContinuousParameterColorScaleHelper } from "./parameterColoringUtils"; +import { EnsemblesContinuousParameterColoring } from "./ensemblesContinuousParameterColoring"; import { TimeSeriesPlotData } from "./timeSeriesPlotData"; import { VectorSpec } from "../state"; @@ -58,9 +57,9 @@ export class SubplotBuilder { private _width = 0; private _height = 0; - private _defaultScatterType = "scatter"; + private _scatterType: "scatter" | "scattergl"; - private _parameterColorScaleHelper: ContinuousParameterColorScaleHelper | null = null; + private _ensemblesParameterColoring: EnsemblesContinuousParameterColoring | null = null; private _parameterFallbackColor = "#808080"; constructor( @@ -69,7 +68,8 @@ export class SubplotBuilder { colorSet: ColorSet, width: number, height: number, - parameterColorScaleHelper?: ContinuousParameterColorScaleHelper + ensemblesParameterColoring?: EnsemblesContinuousParameterColoring, + scatterType: "scatter" | "scattergl" = "scatter" ) { this._selectedVectorSpecifications = selectedVectorSpecifications; this._width = width; @@ -96,7 +96,8 @@ export class SubplotBuilder { ? this._uniqueVectorNames.length : this._uniqueEnsembleNames.length; - this._parameterColorScaleHelper = parameterColorScaleHelper ?? null; + this._ensemblesParameterColoring = ensemblesParameterColoring ?? null; + this._scatterType = scatterType; // TODO: // - Handle keep uirevision? @@ -227,15 +228,15 @@ export class SubplotBuilder { this._plotData.push(observationLegendTrace); } - // Add color scale for color by parameter - if (this._hasRealizationsTracesColoredByParameter && this._parameterColorScaleHelper !== null) { + // Add color scale for color by parameter below the legends + if (this._hasRealizationsTracesColoredByParameter && this._ensemblesParameterColoring !== null) { const colorScaleMarker: Partial = { - ...this._parameterColorScaleHelper.getColorScale().getAsPlotlyColorScaleMarkerObject(), + ...this._ensemblesParameterColoring.getColorScale().getAsPlotlyColorScaleMarkerObject(), colorbar: { title: "Parameter range", titleside: "right", ticks: "outside", - len: 0.75, + len: 0.75, // Note: If too many legends are added, this len might have to be reduced? }, }; const parameterColorLegendTrace: Partial = { @@ -251,9 +252,7 @@ export class SubplotBuilder { addRealizationTracesColoredByParameter( vectorsRealizationData: { vectorSpecification: VectorSpec; data: VectorRealizationData_api[] }[] ): void { - if (this._parameterColorScaleHelper === null) return; - - this._defaultScatterType = "scattergl"; + if (this._ensemblesParameterColoring === null) return; // Only allow selected vectors const selectedVectorsRealizationData = vectorsRealizationData.filter((vec) => @@ -268,7 +267,7 @@ export class SubplotBuilder { // Create traces for each vector for (const elm of selectedVectorsRealizationData) { const subplotIndex = this.getSubplotIndex(elm.vectorSpecification); - if (subplotIndex === -1) return; + if (subplotIndex === -1) continue; // Get legend group and color const legendGroup = this.getLegendGroupAndUpdateTracker(elm.vectorSpecification); @@ -278,16 +277,16 @@ export class SubplotBuilder { let parameterColor = this._parameterFallbackColor; const ensembleName = elm.vectorSpecification.ensembleIdent.getEnsembleName(); if ( - this._parameterColorScaleHelper.hasParameterRealizationNumericalValue( + this._ensemblesParameterColoring.hasParameterRealizationNumericalValue( ensembleName, realizationData.realization ) ) { - const value = this._parameterColorScaleHelper.getParameterRealizationValue( + const value = this._ensemblesParameterColoring.getParameterRealizationValue( ensembleName, realizationData.realization ); - parameterColor = this._parameterColorScaleHelper.getColorScale().getColorForValue(value); + parameterColor = this._ensemblesParameterColoring.getColorScale().getColorForValue(value); } const vectorRealizationTrace = createVectorRealizationTrace({ @@ -298,6 +297,7 @@ export class SubplotBuilder { hoverTemplate: hoverTemplate, showLegend: addLegendForTraces, yaxis: `y${subplotIndex + 1}`, + type: this._scatterType, }); this._plotData.push(vectorRealizationTrace); this._hasRealizationsTracesColoredByParameter = true; @@ -309,8 +309,6 @@ export class SubplotBuilder { vectorsRealizationData: { vectorSpecification: VectorSpec; data: VectorRealizationData_api[] }[], useIncreasedBrightness: boolean ): void { - this._defaultScatterType = "scattergl"; - // Only allow selected vectors const selectedVectorsRealizationData = vectorsRealizationData.filter((vec) => this._selectedVectorSpecifications.some( @@ -322,9 +320,9 @@ export class SubplotBuilder { const hoverTemplate = ""; // No template yet // Create traces for each vector - selectedVectorsRealizationData.forEach((elm) => { + for (const elm of selectedVectorsRealizationData) { const subplotIndex = this.getSubplotIndex(elm.vectorSpecification); - if (subplotIndex === -1) return; + if (subplotIndex === -1) continue; // Get legend group and color const legendGroup = this.getLegendGroupAndUpdateTracker(elm.vectorSpecification); @@ -349,11 +347,12 @@ export class SubplotBuilder { hoverTemplate: hoverTemplate, showLegend: addLegendForTraces, yaxis: `y${subplotIndex + 1}`, + type: this._scatterType, }); this._plotData.push(...vectorRealizationTraces); this._hasRealizationsTraces = true; - }); + } } addFanchartTraces( @@ -367,9 +366,9 @@ export class SubplotBuilder { ); // Create traces for each vector - selectedVectorsStatisticData.forEach((elm) => { + for (const elm of selectedVectorsStatisticData) { const subplotIndex = this.getSubplotIndex(elm.vectorSpecification); - if (subplotIndex === -1) return; + if (subplotIndex === -1) continue; // Get legend group and color const legendGroup = this.getLegendGroupAndUpdateTracker(elm.vectorSpecification); @@ -380,10 +379,11 @@ export class SubplotBuilder { hexColor: color, legendGroup: legendGroup, yaxis: `y${subplotIndex + 1}`, + type: this._scatterType, }); this._plotData.push(...vectorFanchartTraces); - }); + } } addStatisticsTraces( @@ -400,9 +400,9 @@ export class SubplotBuilder { const lineWidth = highlightStatisticTraces ? 3 : 2; // Create traces for each vector - selectedVectorsStatisticData.forEach((elm) => { + for (const elm of selectedVectorsStatisticData) { const subplotIndex = this.getSubplotIndex(elm.vectorSpecification); - if (subplotIndex === -1) return; + if (subplotIndex === -1) continue; // Get legend group and color const legendGroup = this.getLegendGroupAndUpdateTracker(elm.vectorSpecification); @@ -414,10 +414,11 @@ export class SubplotBuilder { legendGroup: legendGroup, yaxis: `y${subplotIndex + 1}`, lineWidth: lineWidth, + type: this._scatterType, }); this._plotData.push(...vectorStatisticsTraces); - }); + } } addHistoryTraces( @@ -434,18 +435,19 @@ export class SubplotBuilder { ); // Create traces for each vector - selectedVectorsHistoricalData.forEach((elm) => { + for (const elm of selectedVectorsHistoricalData) { const subplotIndex = this.getSubplotIndex(elm.vectorSpecification); - if (subplotIndex === -1) return; + if (subplotIndex === -1) continue; this._hasHistoryTraces = true; const vectorHistoryTrace = createHistoricalVectorTrace({ vectorHistoricalData: elm.data, color: this._historyVectorColor, yaxis: `y${subplotIndex + 1}`, + type: this._scatterType, }); this._plotData.push(vectorHistoryTrace); - }); + } } addVectorObservations(): void { diff --git a/frontend/src/modules/SimulationTimeSeriesMatrix/view.tsx b/frontend/src/modules/SimulationTimeSeriesMatrix/view.tsx index 873d0fb27..deb6a8920 100644 --- a/frontend/src/modules/SimulationTimeSeriesMatrix/view.tsx +++ b/frontend/src/modules/SimulationTimeSeriesMatrix/view.tsx @@ -2,17 +2,14 @@ import React from "react"; import Plot from "react-plotly.js"; import { Ensemble } from "@framework/Ensemble"; -import { EnsembleIdent } from "@framework/EnsembleIdent"; import { ModuleFCProps } from "@framework/Module"; import { useEnsembleSet } from "@framework/WorkbenchSession"; import { useElementSize } from "@lib/hooks/useElementSize"; import { ColorScaleGradientType } from "@lib/utils/ColorScale"; -// Note: Have for debug render count info -import { isDevMode } from "@lib/utils/devMode"; import { useHistoricalVectorDataQueries, useStatisticalVectorDataQueries, useVectorDataQueries } from "./queryHooks"; import { GroupBy, State, VisualizationMode } from "./state"; -import { ContinuousParameterColorScaleHelper } from "./utils/parameterColoringUtils"; +import { EnsemblesContinuousParameterColoring } from "./utils/ensemblesContinuousParameterColoring"; import { SubplotBuilder, SubplotOwner } from "./utils/subplotBuilder"; import { createLoadedVectorSpecificationAndDataArray, @@ -21,12 +18,6 @@ import { } from "./utils/vectorSpecificationsAndQueriesUtils"; export const view = ({ moduleContext, workbenchSession, workbenchSettings }: ModuleFCProps) => { - // Leave this in until we get a feeling for React18/Plotly - const renderCount = React.useRef(0); - React.useEffect(function incrementRenderCount() { - renderCount.current = renderCount.current + 1; - }); - const wrapperDivRef = React.useRef(null); const wrapperDivSize = useElementSize(wrapperDivRef); @@ -49,29 +40,6 @@ export const view = ({ moduleContext, workbenchSession, workbenchSettings }: Mod gradientType: ColorScaleGradientType.Diverging, }); - // Get range for color scale - const uniqueEnsembleIdents: EnsembleIdent[] = []; - vectorSpecifications?.forEach((specification) => { - if (uniqueEnsembleIdents.some((ensembleIdent) => ensembleIdent.equals(specification.ensembleIdent))) return; - - uniqueEnsembleIdents.push(specification.ensembleIdent); - }); - - // Get ensemble objects from ensemble set - const selectedEnsembles: Ensemble[] = []; - for (const ensembleIdent of uniqueEnsembleIdents) { - const ensemble = ensembleSet.findEnsemble(ensembleIdent); - if (ensemble === null) continue; - - selectedEnsembles.push(ensemble); - } - - // Create parameter color scale helper - const doColorByParameter = colorRealizationsByParameter && parameterIdent !== null && selectedEnsembles.length > 0; - const parameterColorScaleHelper = doColorByParameter - ? new ContinuousParameterColorScaleHelper(parameterIdent, selectedEnsembles, parameterColorScale) - : null; - // Queries const vectorDataQueries = useVectorDataQueries( vectorSpecifications, @@ -96,6 +64,9 @@ export const view = ({ moduleContext, workbenchSession, workbenchSettings }: Mod ); // Map vector specifications and queries with data + // TODO: + // - Add loading state if 1 or more queries are loading? + // - Can check for equal length of useQueries arrays and the loadedVectorSpecificationsAndData arrays? const loadedVectorSpecificationsAndRealizationData = vectorSpecifications ? createLoadedVectorSpecificationAndDataArray(vectorSpecifications, vectorDataQueries) : []; @@ -109,40 +80,52 @@ export const view = ({ moduleContext, workbenchSession, workbenchSettings }: Mod ) : []; - // TODO: - // - Add loading state if 1 or more queries are loading? - // - Can check for equal length of useQueries arrays and the loadedVectorSpecificationsAndData arrays? + // Retrieve selected ensembles from vector specifications + const selectedEnsembles: Ensemble[] = []; + vectorSpecifications?.forEach((vectorSpecification) => { + if (selectedEnsembles.some((ensemble) => ensemble.getIdent().equals(vectorSpecification.ensembleIdent))) { + return; + } - // Iterate over unique ensemble names and assign color from color palette - if (vectorSpecifications) { - const uniqueEnsembleNames: string[] = []; - vectorSpecifications.forEach((vectorSpec) => { - const ensembleName = vectorSpec.ensembleIdent.getEnsembleName(); - if (!uniqueEnsembleNames.includes(ensembleName)) { - uniqueEnsembleNames.push(vectorSpec.ensembleIdent.getEnsembleName()); - } - }); - } + const ensemble = ensembleSet.findEnsemble(vectorSpecification.ensembleIdent); + if (ensemble === null) return; - // Plot builder - // NOTE: useRef? + selectedEnsembles.push(ensemble); + }); + + // Create parameter color scale helper + const doColorByParameter = + colorRealizationsByParameter && + parameterIdent !== null && + selectedEnsembles.some((ensemble) => ensemble.getParameters().findParameter(parameterIdent)); + const ensemblesParameterColoring = doColorByParameter + ? new EnsemblesContinuousParameterColoring(selectedEnsembles, parameterIdent, parameterColorScale) + : null; + + // Create Plot Builder const subplotOwner = groupBy === GroupBy.TIME_SERIES ? SubplotOwner.VECTOR : SubplotOwner.ENSEMBLE; + const scatterType = + visualizationMode === VisualizationMode.INDIVIDUAL_REALIZATIONS || + visualizationMode === VisualizationMode.STATISTICS_AND_REALIZATIONS + ? "scattergl" + : "scatter"; const subplotBuilder = new SubplotBuilder( subplotOwner, vectorSpecifications ?? [], colorSet, wrapperDivSize.width, wrapperDivSize.height, - parameterColorScaleHelper ?? undefined + ensemblesParameterColoring ?? undefined, + scatterType ); - if (visualizationMode === VisualizationMode.INDIVIDUAL_REALIZATIONS) { - if (doColorByParameter) { - subplotBuilder.addRealizationTracesColoredByParameter(loadedVectorSpecificationsAndRealizationData); - } else { - const useIncreasedBrightness = false; - subplotBuilder.addRealizationsTraces(loadedVectorSpecificationsAndRealizationData, useIncreasedBrightness); - } + // Add traces based on visualization mode + if (doColorByParameter && visualizationMode === VisualizationMode.INDIVIDUAL_REALIZATIONS) { + subplotBuilder.addRealizationTracesColoredByParameter(loadedVectorSpecificationsAndRealizationData); + } + if (!doColorByParameter && visualizationMode === VisualizationMode.INDIVIDUAL_REALIZATIONS) { + const useIncreasedBrightness = false; + subplotBuilder.addRealizationsTraces(loadedVectorSpecificationsAndRealizationData, useIncreasedBrightness); } if (visualizationMode === VisualizationMode.STATISTICAL_FANCHART) { const selectedVectorsFanchartStatisticData = filterVectorSpecificationAndFanchartStatisticsDataArray( @@ -194,12 +177,6 @@ export const view = ({ moduleContext, workbenchSession, workbenchSettings }: Mod onHover={handleHover} onUnhover={handleUnHover} /> - {isDevMode() && ( - <> -
(rc={renderCount.current})
-
Traces: {plotData.length}
- - )} ); };