Skip to content

Commit

Permalink
add option to customize cell vs. solution labels
Browse files Browse the repository at this point in the history
resolves #27
  • Loading branch information
swharden committed Feb 7, 2024
1 parent 7085c7d commit 311953b
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 105 deletions.
90 changes: 53 additions & 37 deletions src/LJPcalc.Web/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
<span class="fw-normal">S·cm<sup>2</sup>/mol</span>
</th>
<th>
<span class="fw-strong">A</span><br />
<span class="fw-strong">@NameA</span><br />
<span class="fw-normal">mM</span>
</th>
<th>
<span class="fw-strong">B</span><br />
<span class="fw-strong">@NameB</span><br />
<span class="fw-normal">mM</span>
</th>
<th>Edit</th>
Expand Down Expand Up @@ -58,34 +58,11 @@
</table>
</div>

@if (KnownIonSet is not null)
{
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" />
</symbol>
</svg>

<div class="alert alert-primary" role="alert">
<strong>The "@KnownIonSet.Name" ion set has been loaded.</strong>
@KnownIonSet.Details
</div>
}

<EditIonModal @ref="MyEditIonModal" OnSaveIon="EditedIonSave" />

<EditTextModal @ref="MyEditTextModal" OnSave="@EditedTextSave" />

<div class="d-flex justify-content-between">

<div>
<div class="d-inline-block">
<div class="input-group" style="width: 100px;">
<span class="input-group-text" id="basic-addon1">ºC</span>
<input type="text" class="form-control" @bind=TemperatureC>
</div>
</div>
</div>
<div class="d-flex justify-content-end">

<div class="mb-4">
<div class="dropdown d-inline-block">
Expand Down Expand Up @@ -147,25 +124,46 @@
</div>
</div>

<div class="d-flex py-3 align-items-center flex-wrap">
<div>
Model
</div>
<select class="form-select w-auto mx-2" @onchange=DoStuff>
<option value="cell">a cell</option>
<option value="solution">liquids</option>
</select>
<div>
at
</div>
<div class="input-group mx-2" style="width: 6em;">
<input type="text" class="form-control" @bind=TemperatureC>
<span class="input-group-text" id="basic-addon1">ºC</span>
</div>

@if (ContinueCalculating)
{
<button class="btn btn-secondary" @onclick=CalcStop>Calculating...</button>
}
else
{
<button class="btn btn-primary" @onclick=CalcStart disabled=@IsIonTableError>Calculate LJP</button>
}
</div>

@if (IsIonTableError)
{
<ErrorAlert Title="Error" Message=@IonTableErrorMessage />
}

@if (ContinueCalculating)
{
<button class="btn btn-primary" type="button" disabled>
Calculating...
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
</button>
<button class="btn btn-primary ms-1" @onclick=CalcStop>Stop</button>
}
else
@if (KnownIonSet is not null)
{
<button class="btn btn-primary" @onclick=CalcStart disabled=@IsIonTableError>Calculate LJP</button>
<div class="alert alert-primary text-break" role="alert">
<strong>The "@KnownIonSet.Name" ion set has been loaded.</strong>
@KnownIonSet.Details
</div>
}

<LjpResultTable LatestResult="LatestResult" BestResult="BestResult" />
<LjpResultTable LatestResult="LatestResult" BestResult="BestResult" NameA="@NameA" NameB="@NameB" />

@if (Calc is not null)
{
Expand Down Expand Up @@ -204,6 +202,9 @@ else

IKnownIonSet? KnownIonSet { get; set; } = null;

string NameA { get; set; } = "In";
string NameB { get; set; } = "Out";

protected override void OnInitialized()
{
JSRuntime.InvokeVoidAsync("updateFooterMessage", $"LJPcalc {LjpCalculator.GetVersion()} running on .NET {Environment.Version}");
Expand Down Expand Up @@ -246,6 +247,7 @@ else

private async Task CalcStart()
{
KnownIonSet = null;
ContinueCalculating = true;
await Task.Delay(1); // helps ensure a screen refresh happens
StateHasChanged();
Expand Down Expand Up @@ -375,4 +377,18 @@ else
ValidateIonSet();
KnownIonSet = null;
}

private void DoStuff(ChangeEventArgs e)
{
if ($"{e.Value}" == "cell")
{
NameA = "In";
NameB = "Out";
}
else if ($"{e.Value}" == "solution")
{
NameA = "A";
NameB = "B";
}
}
}
144 changes: 76 additions & 68 deletions src/LJPcalc.Web/Shared/LjpResultTable.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,86 +8,86 @@

@if (isSolved)
{
<div style="color: green">
<div class="display-5 mt-4">LJP = @ljpPrettyMillivolts mV</div>
<div>A solution was found!</div>
</div>

<div class="mb-3 mt-2">
<span class="fw-bold">
If you enjoy LJPcalc, consider citing it by name:
</span>
<span class="fst-italic">
Liquid junction potential was calculated according to the stationary NernstPlanck equation
(<a href="https://arxiv.org/abs/1403.3640">Marino et al., 2014</a>)
using LJPcalc software (<a href="https://swharden.com/LJPcalc">https://swharden.com/LJPcalc</a>).
</span>
<div class="alert alert-success d-inline-block text-success" role="alert">
<h2 class="alert-heading">LJP = @ljpPrettyMillivolts mV</h2>
<div>Liquid junction potential was calculated successfully.</div>
</div>
}
else
{
<div style="color: red">
<div class="display-5 mt-4">LJP = @ljpPrettyMillivolts mV</div>
<div class="alert alert-danger d-inline-block text-danger" role="alert">
<div class="d-flex">
<h2 class="alert-heading">
LJP@ljpPrettyMillivolts mV
</h2>
<div class="spinner-border text-danger mx-2" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div>Optimizing &Phi; to minimize solution B concentration error...</div>
</div>
}

<table class="table table-hover">
<thead>
<tr class="text-center">
<th></th>
<th colspan="2">Target</th>
<th colspan="3">Latest</th>
<th colspan="3">Best</th>
</tr>
<tr class="text-center">
<th class="text-start">Ion</th>
<th>A</th>
<th>B</th>
<th>&Phi;</th>
<th>B</th>
<th>Error</th>
<th>&Phi;</th>
<th>B</th>
<th>Error</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < BestResult.Ions.Length; i++)
{
double testError = LatestResult.SolvedIons[i].InitialCL == 0 ? 0 : Math.Round(LatestResult.SolvedIons[i].PercentChangeCL, 3);
double bestError = BestResult.SolvedIons[i].InitialCL == 0 ? 0 : Math.Round(BestResult.SolvedIons[i].PercentChangeCL, 3);
<h2 class="mt-5">Calculation Details</h2>

<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr class="text-center">
<th></th>
<th colspan="2">Target Concentrations</th>
<th colspan="3">Latest Solution</th>
<th colspan="3">Best Solution</th>
</tr>
<tr class="text-center">
<td class="text-start">@BestResult.SolvedIons[i].NameWithCharge</td>
<td>@Math.Round(BestResult.SolvedIons[i].C0, 4)</td>
<td>@Math.Round(BestResult.SolvedIons[i].InitialCL, 4)</td>
<th class="text-start">Ion</th>
<th>@NameA</th>
<th>@NameB</th>
<th>&Phi;</th>
<th>@NameB</th>
<th>Error</th>
<th>&Phi;</th>
<th>@NameB</th>
<th>Error</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < BestResult.Ions.Length; i++)
{
double testError = LatestResult.SolvedIons[i].InitialCL == 0 ? 0 : Math.Round(LatestResult.SolvedIons[i].PercentChangeCL, 3);
double bestError = BestResult.SolvedIons[i].InitialCL == 0 ? 0 : Math.Round(BestResult.SolvedIons[i].PercentChangeCL, 3);

<td>@Math.Round(LatestResult.SolvedIons[i].Phi, 4)</td>
<td>@Math.Round(LatestResult.SolvedIons[i].CL, 4)</td>
@if (testError < 1)
{
<td class="table-success">&lt;1%</td>
}
else
{
<td class="table-danger">@testError%</td>
}
<tr class="text-center">
<td class="text-start">@BestResult.SolvedIons[i].NameWithCharge</td>
<td>@Math.Round(BestResult.SolvedIons[i].C0, 4)</td>
<td>@Math.Round(BestResult.SolvedIons[i].InitialCL, 4)</td>

<td>@Math.Round(BestResult.SolvedIons[i].Phi, 4)</td>
<td>@Math.Round(BestResult.SolvedIons[i].CL, 4)</td>
@if (bestError < 1)
{
<td class="table-success">&lt;1%</td>
}
else
{
<td class="table-danger">@bestError%</td>
}
</tr>
}
</tbody>
</table>
<td>@Math.Round(LatestResult.SolvedIons[i].Phi, 4)</td>
<td>@Math.Round(LatestResult.SolvedIons[i].CL, 4)</td>
@if (testError < 1)
{
<td class="table-success">&lt;1%</td>
}
else
{
<td class="table-danger">@testError%</td>
}

<td>@Math.Round(BestResult.SolvedIons[i].Phi, 4)</td>
<td>@Math.Round(BestResult.SolvedIons[i].CL, 4)</td>
@if (bestError < 1)
{
<td class="table-success">&lt;1%</td>
}
else
{
<td class="table-danger">@bestError%</td>
}
</tr>
}
</tbody>
</table>
</div>
}

@code {
Expand All @@ -98,4 +98,12 @@
[Parameter]
[EditorRequired]
public LjpResult? BestResult { get; set; } = null;

[Parameter]
[EditorRequired]
public string NameA { get; set; } = "?A?";

[Parameter]
[EditorRequired]
public string NameB { get; set; } = "?B?";
}

0 comments on commit 311953b

Please sign in to comment.