Skip to content

Commit 682160b

Browse files
Update results tables to handle phases
1 parent 06fe60d commit 682160b

5 files changed

Lines changed: 90 additions & 47 deletions

File tree

frontend/src/components/BarChart.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ const BarChart: React.FC<BarChartProps> = ({ graphData, aspectRatio = 4, xLabel,
2020

2121
const allX = Array.from(new Set(graphData.flatMap((ds) => ds.data.map((point) => point.x))));
2222

23+
const hasStacking = graphData.some((ds) => ds.stack);
24+
2325
const datasets = graphData.map((ds, idx) => ({
2426
label: ds.label,
2527
hidden: ds.hidden || false,
@@ -30,6 +32,7 @@ const BarChart: React.FC<BarChartProps> = ({ graphData, aspectRatio = 4, xLabel,
3032
backgroundColor: ds.pattern
3133
? createBarPattern(ds.color ?? getDistributedColor(idx, graphData.length), ds.pattern)
3234
: (ds.color ?? getDistributedColor(idx, graphData.length)),
35+
...(ds.stack ? { stack: ds.stack } : {}),
3336
}));
3437

3538
const chartData = {
@@ -79,6 +82,7 @@ const BarChart: React.FC<BarChartProps> = ({ graphData, aspectRatio = 4, xLabel,
7982
y: {
8083
grid: { display: true },
8184
title: { display: !!yLabel, text: yLabel ?? "" },
85+
stacked: hasStacking,
8286
},
8387
},
8488
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Table } from "@equinor/eds-core-react";
2+
import { Phase } from "@/dto/SimulationResults";
3+
import { formatConcentration, formatPhaseFraction } from "@/functions/Formatting";
4+
5+
interface PhaseResultTableProps {
6+
initialConcentrations: Record<string, number>;
7+
phases: Phase[];
8+
}
9+
10+
const PhaseResultTable: React.FC<PhaseResultTableProps> = ({ initialConcentrations, phases }) => {
11+
const allComponents = Array.from(
12+
new Set([
13+
...Object.keys(initialConcentrations),
14+
...phases.flatMap((phase) => Object.keys(phase.concentrations)),
15+
])
16+
);
17+
18+
const visibleComponents = allComponents.filter((key) => {
19+
const init = initialConcentrations[key] ?? 0;
20+
const hasSignificantPhaseValue = phases.some((phase) => (phase.concentrations[key] ?? 0) >= 0.001);
21+
return init >= 0.001 || hasSignificantPhaseValue;
22+
});
23+
24+
return (
25+
<Table>
26+
<Table.Head>
27+
<Table.Row>
28+
<Table.Cell>Component</Table.Cell>
29+
<Table.Cell>Initial (ppm)</Table.Cell>
30+
{phases.map((phase) => (
31+
<Table.Cell key={phase.kind}>
32+
{phase.kind} ({formatPhaseFraction(phase.fraction)})
33+
</Table.Cell>
34+
))}
35+
</Table.Row>
36+
</Table.Head>
37+
<Table.Body>
38+
{visibleComponents.map((key) => (
39+
<Table.Row key={key}>
40+
<Table.Cell>{key}</Table.Cell>
41+
<Table.Cell>{formatConcentration(initialConcentrations[key] ?? 0)}</Table.Cell>
42+
{phases.map((phase) => (
43+
<Table.Cell key={phase.kind}>
44+
{formatConcentration(phase.concentrations[key] ?? 0)}
45+
</Table.Cell>
46+
))}
47+
</Table.Row>
48+
))}
49+
</Table.Body>
50+
</Table>
51+
);
52+
};
53+
54+
export default PhaseResultTable;

frontend/src/components/Simulation/Results.tsx

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import React from "react";
22
import { Tabs, Typography } from "@equinor/eds-core-react";
33
import { useState } from "react";
44
import { Panel, SimulationResults } from "@/dto/SimulationResults";
5-
import ResultConcTable from "@/components/Simulation/ConcResultTable";
5+
import PhaseResultTable from "@/components/Simulation/PhaseResultTable";
66
import Reactions from "../../pages/Reactions";
77
import { MassBalanceError } from "@/components/Simulation/MassBalanceError";
8-
import { extractPlotData, formatPhaseFraction } from "@/functions/Formatting";
8+
import { extractPlotData } from "@/functions/Formatting";
99
import BarChart from "@/components/BarChart";
1010
import GenericTable from "@/components/GenericTable";
1111

@@ -68,40 +68,28 @@ const Results: React.FC<ResultsProps> = ({ simulationResults }) => {
6868
simulationResults.results.forEach((result, modelIndex) => {
6969
const modelId = simulationResults.input.models[modelIndex]?.modelId || `Model ${modelIndex + 1}`;
7070
const modelPrefix = simulationResults.results.length > 1 ? `${modelId}: ` : "";
71+
const initialConcentrations = simulationResults.input.concentrations;
7172

72-
for (const phase of result.phases) {
73-
const hasConcentrations = Object.keys(phase.concentrations).length > 0;
74-
if (!hasConcentrations) continue;
73+
const phasesWithConcentrations = result.phases.filter((phase) => Object.keys(phase.concentrations).length > 0);
7574

76-
panelTabs.push(`${modelPrefix}${phase.kind} (${formatPhaseFraction(phase.fraction)})`);
77-
78-
const initialConcentrations = simulationResults.input.concentrations;
75+
if (phasesWithConcentrations.length > 0) {
76+
panelTabs.push(`${modelPrefix}Phases`);
7977

8078
panelContents.push(
81-
<Tabs.Panel key={`phase-${modelIndex}-${phase.kind}`}>
79+
<Tabs.Panel key={`phases-${modelIndex}`}>
8280
<MassBalanceError
8381
initialPhases={[{ kind: "aqueous", fraction: 1, concentrations: initialConcentrations }]}
8482
finalPhases={result.phases}
8583
/>
8684

8785
<BarChart
8886
aspectRatio={2}
89-
graphData={extractPlotData({
90-
...simulationResults,
91-
results: [{ phases: [phase], panels: [] }],
92-
input: {
93-
...simulationResults.input,
94-
concentrations: initialConcentrations,
95-
},
96-
})}
87+
graphData={extractPlotData(initialConcentrations, phasesWithConcentrations)}
9788
xLabel="Components"
9889
yLabel="Concentration (ppm)"
9990
/>
10091

101-
<ResultConcTable
102-
initialConcentrations={initialConcentrations}
103-
finalConcentrations={phase.concentrations}
104-
/>
92+
<PhaseResultTable initialConcentrations={initialConcentrations} phases={phasesWithConcentrations} />
10593
</Tabs.Panel>
10694
);
10795
}

frontend/src/dto/ChartData.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface ChartDataSet {
1212
hidden?: boolean;
1313
color?: string;
1414
pattern?: BarPattern;
15+
stack?: string;
1516
}
1617
export interface TabulatedResultRow {
1718
[key: string]: number | string;

frontend/src/functions/Formatting.tsx

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SimulationResults, getCo2RichConcentrations } from "@/dto/SimulationResults";
1+
import { SimulationResults, Phase, getCo2RichConcentrations } from "@/dto/SimulationResults";
22
import { ChartDataSet, TabulatedResultRow } from "@/dto/ChartData";
33
import { ExperimentResult } from "@/dto/ExperimentResult";
44

@@ -48,37 +48,33 @@ export const convertToSubscripts = (chemicalFormula: string): React.ReactNode =>
4848
return <p>{result}</p>;
4949
};
5050

51-
export const extractPlotData = (simulationResults: SimulationResults) => {
52-
const inputConcentrations = simulationResults.input.concentrations;
53-
const finalConcentrations = getCo2RichConcentrations(simulationResults.results[0]?.phases);
54-
const keys = Object.keys(finalConcentrations).filter(
55-
(key) => (inputConcentrations[key] ?? 0) >= 0.001 || (finalConcentrations[key] ?? 0) >= 0.001
51+
export const extractPlotData = (inputConcentrations: Record<string, number>, phases: Phase[]): ChartDataSet[] => {
52+
const allKeys = Array.from(
53+
new Set([...Object.keys(inputConcentrations), ...phases.flatMap((phase) => Object.keys(phase.concentrations))])
54+
);
55+
const keys = allKeys.filter(
56+
(key) =>
57+
(inputConcentrations[key] ?? 0) >= 0.001 ||
58+
phases.some((phase) => (phase.concentrations[key] ?? 0) >= 0.001)
5659
);
5760

58-
const initial = keys.map((key) => ({ x: key, y: inputConcentrations[key] }));
59-
const final = keys.map((key) => ({ x: key, y: finalConcentrations[key] }));
60-
const change = keys.map((key) => ({
61-
x: key,
62-
y: finalConcentrations[key] - (inputConcentrations[key] ?? 0),
63-
}));
64-
65-
return [
66-
{
67-
label: "Change",
68-
data: change,
69-
hidden: false,
70-
},
61+
const datasets: ChartDataSet[] = [
7162
{
7263
label: "Initial",
73-
data: initial,
74-
hidden: true,
75-
},
76-
{
77-
label: "Final",
78-
data: final,
79-
hidden: true,
64+
data: keys.map((key) => ({ x: key, y: inputConcentrations[key] ?? 0 })),
65+
stack: "initial",
8066
},
67+
...phases.map((phase) => ({
68+
label: `${phase.kind} (${formatPhaseFraction(phase.fraction)})`,
69+
data: keys.map((key) => ({
70+
x: key,
71+
y: (phase.concentrations[key] ?? 0) * phase.fraction,
72+
})),
73+
stack: "output",
74+
})),
8175
];
76+
77+
return datasets;
8278
};
8379

8480
export const convertSimulationToChartData = (simulation: SimulationResults, experimentName: string): ChartDataSet => {

0 commit comments

Comments
 (0)