Skip to content

Commit 851614d

Browse files
Improve column overview in phase table
We make the header two rows and a vertical line separates initial and final. Both states will initially contain all phases in addition to a Total column. We apply filters: 1. Only show a column if there are any value >0 (removes aq phase initial, as there is only co2 feed) 2. Only show total if there are more than 1 column with any value >0 (removes total phase for initial, as aq is already removed)
1 parent 62269c7 commit 851614d

1 file changed

Lines changed: 92 additions & 14 deletions

File tree

frontend/src/components/Simulation/PhaseResultTable.tsx

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,44 @@ function unitLabel(phase: Phase): string {
1212
return phase.kind === "aqueous" ? "wt%" : "ppm";
1313
}
1414

15-
function ConvertUnitAccordingToPhase(phase: Phase): Record<string, number> {
15+
function convertUnitAccordingToPhase(phase: Phase): Record<string, number> {
1616
if (phase.kind === "aqueous") {
1717
return ppmMolToWeightPercent(phase.concentrations);
1818
}
1919
return phase.concentrations;
2020
}
2121

22-
const PhaseResultTable: React.FC<PhaseResultTableProps> = ({ initialConcentrations, phases }) => {
23-
const phaseDisplayData = phases.map((phase) => ConvertUnitAccordingToPhase(phase));
22+
function phaseLabel(phase: Phase): string {
23+
return phase.kind === "aqueous" ? "Aqueous" : "CO2-rich";
24+
}
25+
26+
function sortPhases(phases: Phase[]): Phase[] {
27+
return [...phases].sort((a, b) => {
28+
if (a.kind === "co2-rich" && b.kind === "aqueous") return -1;
29+
if (a.kind === "aqueous" && b.kind === "co2-rich") return 1;
30+
return 0;
31+
});
32+
}
33+
34+
interface PhaseGroup {
35+
label: string;
36+
phases: Phase[];
37+
displayData: Record<string, number>[];
38+
showTotal: boolean;
39+
}
2440

41+
function buildPhaseGroup(label: string, phases: Phase[]): PhaseGroup {
42+
const sorted = sortPhases(phases);
43+
const visible = sorted.filter((phase) => Object.values(phase.concentrations).some((v) => v > 0));
44+
return {
45+
label,
46+
phases: visible,
47+
displayData: visible.map((phase) => convertUnitAccordingToPhase(phase)),
48+
showTotal: visible.length > 1,
49+
};
50+
}
51+
52+
const PhaseResultTable: React.FC<PhaseResultTableProps> = ({ initialConcentrations, phases }) => {
2553
const allComponents = Array.from(
2654
new Set([
2755
...Object.keys(initialConcentrations),
@@ -35,29 +63,79 @@ const PhaseResultTable: React.FC<PhaseResultTableProps> = ({ initialConcentratio
3563
return init >= 0.001 || hasSignificantPhaseValue;
3664
});
3765

66+
const initialPhases: Phase[] = [
67+
{ kind: "co2-rich", fraction: 1, concentrations: initialConcentrations },
68+
{ kind: "aqueous", fraction: 0, concentrations: {} },
69+
];
70+
71+
const groups: PhaseGroup[] = [buildPhaseGroup("Initial", initialPhases), buildPhaseGroup("Final", phases)];
72+
73+
const separatorStyle = { borderLeft: "2px solid #dcdcdc" };
74+
3875
return (
3976
<Table>
4077
<Table.Head>
4178
<Table.Row>
42-
<Table.Cell>Component</Table.Cell>
43-
<Table.Cell>Initial [ppm]</Table.Cell>
44-
{phases.map((phase) => (
45-
<Table.Cell key={phase.kind}>
46-
{phase.kind} [{unitLabel(phase)}] ({formatPhaseFraction(phase.fraction)})
79+
<Table.Cell rowSpan={2}>Component</Table.Cell>
80+
{groups.map((group, gi) => (
81+
<Table.Cell
82+
key={group.label}
83+
colSpan={group.phases.length + (group.showTotal ? 1 : 0)}
84+
style={{ textAlign: "center", ...(gi > 0 ? separatorStyle : {}) }}
85+
>
86+
{group.label}
4787
</Table.Cell>
4888
))}
4989
</Table.Row>
90+
<Table.Row>
91+
{groups.map((group, gi) =>
92+
group.phases
93+
.map((phase, pi) => (
94+
<Table.Cell
95+
key={`${group.label}-${phase.kind}`}
96+
style={gi > 0 && pi === 0 ? separatorStyle : undefined}
97+
>
98+
{`${phaseLabel(phase)} [${unitLabel(phase)}]${phase.fraction < 1 ? ` (${formatPhaseFraction(phase.fraction)})` : ""}`}
99+
</Table.Cell>
100+
))
101+
.concat(
102+
group.showTotal
103+
? [<Table.Cell key={`${group.label}-total`}>Total [ppm]</Table.Cell>]
104+
: []
105+
)
106+
)}
107+
</Table.Row>
50108
</Table.Head>
51109
<Table.Body>
52110
{visibleComponents.map((key) => (
53111
<Table.Row key={key}>
54112
<Table.Cell>{key}</Table.Cell>
55-
<Table.Cell>{formatConcentration(initialConcentrations[key] ?? 0)}</Table.Cell>
56-
{phaseDisplayData.map((concentrations, idx) => (
57-
<Table.Cell key={phases[idx].kind}>
58-
{formatConcentration(concentrations[key] ?? 0)}
59-
</Table.Cell>
60-
))}
113+
{groups.map((group, gi) =>
114+
group.displayData
115+
.map((concentrations, pi) => (
116+
<Table.Cell
117+
key={`${group.label}-${group.phases[pi].kind}`}
118+
style={gi > 0 && pi === 0 ? separatorStyle : undefined}
119+
>
120+
{formatConcentration(concentrations[key] ?? 0)}
121+
</Table.Cell>
122+
))
123+
.concat(
124+
group.showTotal
125+
? [
126+
<Table.Cell key={`${group.label}-total`}>
127+
{formatConcentration(
128+
group.phases.reduce(
129+
(sum, phase) =>
130+
sum + (phase.concentrations[key] ?? 0) * phase.fraction,
131+
0
132+
)
133+
)}
134+
</Table.Cell>,
135+
]
136+
: []
137+
)
138+
)}
61139
</Table.Row>
62140
))}
63141
</Table.Body>

0 commit comments

Comments
 (0)