@@ -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