Skip to content

Commit 551d647

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 551d647

1 file changed

Lines changed: 102 additions & 20 deletions

File tree

frontend/src/components/Simulation/PhaseResultTable.tsx

Lines changed: 102 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,68 @@ 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+
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+
colSpan: number;
40+
}
41+
42+
function buildPhaseGroup(label: string, phases: Phase[]): PhaseGroup {
43+
const sorted = sortPhases(phases);
44+
const visible = sorted.filter((phase) => Object.values(phase.concentrations).some((v) => v > 0));
45+
const showTotal = visible.length > 1;
46+
return {
47+
label,
48+
phases: visible,
49+
displayData: visible.map((phase) => convertUnitAccordingToPhase(phase)),
50+
showTotal,
51+
colSpan: visible.length + (showTotal ? 1 : 0),
52+
};
53+
}
54+
55+
function phaseColumnHeader(phase: Phase): string {
56+
const fraction = phase.fraction < 1 ? ` (${formatPhaseFraction(phase.fraction)})` : "";
57+
return `${phaseLabel(phase)} [${unitLabel(phase)}]${fraction}`;
58+
}
59+
60+
function weightedTotal(phases: Phase[], component: string): number {
61+
return phases.reduce((sum, phase) => sum + (phase.concentrations[component] ?? 0) * phase.fraction, 0);
62+
}
63+
64+
const solidLine = { borderLeft: "2px solid #dcdcdc" };
65+
66+
function groupBorderStyle(groupIndex: number, phaseIndex: number): React.CSSProperties | undefined {
67+
return groupIndex > 0 && phaseIndex === 0 ? solidLine : undefined;
68+
}
69+
2270
const PhaseResultTable: React.FC<PhaseResultTableProps> = ({ initialConcentrations, phases }) => {
23-
const phaseDisplayData = phases.map((phase) => ConvertUnitAccordingToPhase(phase));
71+
const initialPhases: Phase[] = [
72+
{ kind: "co2-rich", fraction: 1, concentrations: initialConcentrations },
73+
{ kind: "aqueous", fraction: 0, concentrations: {} },
74+
];
75+
76+
const groups: PhaseGroup[] = [buildPhaseGroup("Initial", initialPhases), buildPhaseGroup("Final", phases)];
2477

2578
const allComponents = Array.from(
2679
new Set([
@@ -29,35 +82,64 @@ const PhaseResultTable: React.FC<PhaseResultTableProps> = ({ initialConcentratio
2982
])
3083
);
3184

32-
const visibleComponents = allComponents.filter((key) => {
33-
const init = initialConcentrations[key] ?? 0;
34-
const hasSignificantPhaseValue = phases.some((phase) => (phase.concentrations[key] ?? 0) >= 0.001);
35-
return init >= 0.001 || hasSignificantPhaseValue;
85+
const visibleComponents = allComponents.filter((component) => {
86+
return groups.some((group) => group.phases.some((phase) => (phase.concentrations[component] ?? 0) >= 0.001));
3687
});
3788

3889
return (
3990
<Table>
4091
<Table.Head>
4192
<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)})
93+
<Table.Cell rowSpan={2}>Component</Table.Cell>
94+
{groups.map((group, groupIndex) => (
95+
<Table.Cell
96+
key={group.label}
97+
colSpan={group.colSpan}
98+
style={{ textAlign: "center", ...(groupIndex > 0 ? solidLine : {}) }}
99+
>
100+
{group.label}
47101
</Table.Cell>
48102
))}
49103
</Table.Row>
104+
<Table.Row>
105+
{groups.flatMap((group, groupIndex) => {
106+
const cells = group.phases.map((phase, phaseIndex) => (
107+
<Table.Cell
108+
key={`${group.label}-${phase.kind}`}
109+
style={groupBorderStyle(groupIndex, phaseIndex)}
110+
>
111+
{phaseColumnHeader(phase)}
112+
</Table.Cell>
113+
));
114+
if (group.showTotal) {
115+
cells.push(<Table.Cell key={`${group.label}-total`}>Total [ppm]</Table.Cell>);
116+
}
117+
return cells;
118+
})}
119+
</Table.Row>
50120
</Table.Head>
51121
<Table.Body>
52-
{visibleComponents.map((key) => (
53-
<Table.Row key={key}>
54-
<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-
))}
122+
{visibleComponents.map((component) => (
123+
<Table.Row key={component}>
124+
<Table.Cell>{component}</Table.Cell>
125+
{groups.flatMap((group, groupIndex) => {
126+
const cells = group.displayData.map((concentrations, phaseIndex) => (
127+
<Table.Cell
128+
key={`${group.label}-${group.phases[phaseIndex].kind}`}
129+
style={groupBorderStyle(groupIndex, phaseIndex)}
130+
>
131+
{formatConcentration(concentrations[component] ?? 0)}
132+
</Table.Cell>
133+
));
134+
if (group.showTotal) {
135+
cells.push(
136+
<Table.Cell key={`${group.label}-total`}>
137+
{formatConcentration(weightedTotal(group.phases, component))}
138+
</Table.Cell>
139+
);
140+
}
141+
return cells;
142+
})}
61143
</Table.Row>
62144
))}
63145
</Table.Body>

0 commit comments

Comments
 (0)