Stabilize solver metrics and run notes
This commit is contained in:
parent
0417a46f22
commit
2c4721a96f
3 changed files with 89 additions and 18 deletions
|
|
@ -458,6 +458,7 @@ function renderInference(): void {
|
|||
|
||||
function renderStatusMetrics(): void {
|
||||
statusMetrics.innerHTML = "";
|
||||
statusMetrics.classList.toggle("status-metrics-fixed", state.stageKey === "solver");
|
||||
const items: Array<[string, string]> = [];
|
||||
const frame = getSelectedFrame();
|
||||
if (state.stageKey === "inference") {
|
||||
|
|
@ -505,15 +506,30 @@ function renderStatusMetrics(): void {
|
|||
items.push(["Confidence", formatNumber(state.phaseRerank.confidence, 3)]);
|
||||
}
|
||||
} else if (state.stageKey === "solver") {
|
||||
if (state.phaseFieldPrep) {
|
||||
items.push(["Grid", `${state.phaseFieldPrep.targetWidth} x ${state.phaseFieldPrep.targetHeight}`]);
|
||||
items.push(["Cell pitch", `${formatNumber(state.phaseFieldPrep.cellX, 1)} x ${formatNumber(state.phaseFieldPrep.cellY, 1)} px`]);
|
||||
}
|
||||
if (frame) {
|
||||
items.push(["Loss", frame.loss === null ? "n/a" : formatNumber(frame.loss, 4)]);
|
||||
for (const [key, value] of Object.entries(frame.terms).slice(0, 4)) {
|
||||
items.push([key.replaceAll("_", " "), formatNumber(value, 4)]);
|
||||
}
|
||||
const solverTerms: Array<[string, number | null]> = [
|
||||
["Coherence", frame?.terms.local_coherence ?? null],
|
||||
["Edge", frame?.terms.local_edge ?? null],
|
||||
["Smoothness", frame?.terms.smoothness ?? null],
|
||||
["Collapse", frame?.terms.collapse ?? null],
|
||||
["Magnitude", frame?.terms.magnitude ?? null],
|
||||
];
|
||||
items.push([
|
||||
"Grid",
|
||||
state.phaseFieldPrep ? `${state.phaseFieldPrep.targetWidth} x ${state.phaseFieldPrep.targetHeight}` : "pending",
|
||||
]);
|
||||
items.push([
|
||||
"Step",
|
||||
frame ? `${frame.step} / ${frame.totalSteps}` : `0 / ${Math.max(0, state.solverStepBudget)}`,
|
||||
]);
|
||||
items.push([
|
||||
"Cell pitch",
|
||||
state.phaseFieldPrep
|
||||
? `${formatNumber(state.phaseFieldPrep.cellX, 1)} x ${formatNumber(state.phaseFieldPrep.cellY, 1)} px`
|
||||
: "pending",
|
||||
]);
|
||||
items.push(["Loss", frame?.loss === null || frame?.loss === undefined ? "n/a" : formatNumber(frame.loss, 4)]);
|
||||
for (const [label, value] of solverTerms) {
|
||||
items.push([label, formatNumber(value, 4)]);
|
||||
}
|
||||
}
|
||||
for (const [label, value] of items) {
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ function renderInference() {
|
|||
}
|
||||
function renderStatusMetrics() {
|
||||
statusMetrics.innerHTML = "";
|
||||
statusMetrics.classList.toggle("status-metrics-fixed", state.stageKey === "solver");
|
||||
const items = [];
|
||||
const frame = getSelectedFrame();
|
||||
if (state.stageKey === "inference") {
|
||||
|
|
@ -372,15 +373,30 @@ function renderStatusMetrics() {
|
|||
}
|
||||
}
|
||||
else if (state.stageKey === "solver") {
|
||||
if (state.phaseFieldPrep) {
|
||||
items.push(["Grid", `${state.phaseFieldPrep.targetWidth} x ${state.phaseFieldPrep.targetHeight}`]);
|
||||
items.push(["Cell pitch", `${formatNumber(state.phaseFieldPrep.cellX, 1)} x ${formatNumber(state.phaseFieldPrep.cellY, 1)} px`]);
|
||||
}
|
||||
if (frame) {
|
||||
items.push(["Loss", frame.loss === null ? "n/a" : formatNumber(frame.loss, 4)]);
|
||||
for (const [key, value] of Object.entries(frame.terms).slice(0, 4)) {
|
||||
items.push([key.replaceAll("_", " "), formatNumber(value, 4)]);
|
||||
}
|
||||
const solverTerms = [
|
||||
["Coherence", frame?.terms.local_coherence ?? null],
|
||||
["Edge", frame?.terms.local_edge ?? null],
|
||||
["Smoothness", frame?.terms.smoothness ?? null],
|
||||
["Collapse", frame?.terms.collapse ?? null],
|
||||
["Magnitude", frame?.terms.magnitude ?? null],
|
||||
];
|
||||
items.push([
|
||||
"Grid",
|
||||
state.phaseFieldPrep ? `${state.phaseFieldPrep.targetWidth} x ${state.phaseFieldPrep.targetHeight}` : "pending",
|
||||
]);
|
||||
items.push([
|
||||
"Step",
|
||||
frame ? `${frame.step} / ${frame.totalSteps}` : `0 / ${Math.max(0, state.solverStepBudget)}`,
|
||||
]);
|
||||
items.push([
|
||||
"Cell pitch",
|
||||
state.phaseFieldPrep
|
||||
? `${formatNumber(state.phaseFieldPrep.cellX, 1)} x ${formatNumber(state.phaseFieldPrep.cellY, 1)} px`
|
||||
: "pending",
|
||||
]);
|
||||
items.push(["Loss", frame?.loss === null || frame?.loss === undefined ? "n/a" : formatNumber(frame.loss, 4)]);
|
||||
for (const [label, value] of solverTerms) {
|
||||
items.push([label, formatNumber(value, 4)]);
|
||||
}
|
||||
}
|
||||
for (const [label, value] of items) {
|
||||
|
|
|
|||
|
|
@ -201,6 +201,15 @@ p {
|
|||
gap: 10px;
|
||||
}
|
||||
|
||||
.sidebar,
|
||||
.section-block,
|
||||
.summary-panel,
|
||||
.candidate-list,
|
||||
.event-log,
|
||||
.info-stack {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:is(.hero, .card, .metric-chip, .summary-card, .app-shell-header, .viz-card, .loss-canvas, .editor-toolbar, .editor-surface, .dropzone, .field input, .field select, .button, .toggle-row) {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
|
@ -728,8 +737,14 @@ p {
|
|||
gap: 10px;
|
||||
}
|
||||
|
||||
.status-metrics.status-metrics-fixed {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.status-metric {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 10px;
|
||||
border: 2px solid rgba(8, 36, 62, 0.88);
|
||||
background: linear-gradient(180deg, rgba(9, 27, 44, 0.96), rgba(5, 16, 28, 0.95));
|
||||
|
|
@ -748,6 +763,8 @@ p {
|
|||
font-size: 1rem;
|
||||
line-height: 1.12;
|
||||
color: var(--ui-text);
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
@keyframes status-sweep {
|
||||
|
|
@ -764,6 +781,9 @@ p {
|
|||
.event-item,
|
||||
.metric-chip,
|
||||
.summary-card {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 3px solid rgba(8, 36, 62, 0.88);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(11, 32, 52, 0.96), rgba(6, 19, 35, 0.94));
|
||||
|
|
@ -781,6 +801,17 @@ p {
|
|||
font-size: 0.72rem;
|
||||
color: var(--ui-accent);
|
||||
text-transform: uppercase;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.candidate-card span,
|
||||
.event-item span,
|
||||
.summary-card span {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.editor-actions {
|
||||
|
|
@ -919,6 +950,10 @@ select:focus-visible {
|
|||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.status-metrics.status-metrics-fixed {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.card-head {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
|
@ -967,4 +1002,8 @@ select:focus-visible {
|
|||
.button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.status-metrics.status-metrics-fixed {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue