Update simulation preset and UI template
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"points": {
|
"points": {
|
||||||
"frequencies": "256\n870\n3140\n8900\n12000\n16000\n22000\n33000\n45000",
|
"frequencies": "256\n512\n1024\n3140\n8900\n12000\n16000\n22000\n33000\n45000",
|
||||||
"loads": "10\n50\n100\n200\n600\n2000",
|
"loads": "10\n50\n100\n200\n600\n2000",
|
||||||
"target_power_W": 25,
|
"target_power_W": 25,
|
||||||
"power_tol_pct": 2,
|
"power_tol_pct": 2,
|
||||||
|
|||||||
@@ -358,6 +358,10 @@
|
|||||||
.sweep-table .cell-ok { color: #166534; font-weight: 600; }
|
.sweep-table .cell-ok { color: #166534; font-weight: 600; }
|
||||||
.sweep-table .cell-bad { color: #b91c1c; }
|
.sweep-table .cell-bad { color: #b91c1c; }
|
||||||
.sweep-table .cell-null { color: #94a3b8; }
|
.sweep-table .cell-null { color: #94a3b8; }
|
||||||
|
/* Constraint proximity highlights — override row stripes */
|
||||||
|
.sweep-table td.cell-limit-met { background: #dcfce7 !important; } /* green — met target */
|
||||||
|
.sweep-table td.cell-limit-near { background: #fef9c3 !important; } /* yellow — near limit */
|
||||||
|
.sweep-table td.cell-limit-over { background: #fed7aa !important; } /* orange — over limit */
|
||||||
|
|
||||||
/* ---- Spinner ---- */
|
/* ---- Spinner ---- */
|
||||||
.spinner {
|
.spinner {
|
||||||
@@ -616,6 +620,13 @@
|
|||||||
<tbody id="sweep-table-body"></tbody>
|
<tbody id="sweep-table-body"></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="padding:6px 14px 10px;font-size:11px;color:#64748b;display:flex;gap:16px;align-items:center">
|
||||||
|
<span>P_out shading:</span>
|
||||||
|
<span><span style="display:inline-block;width:12px;height:12px;background:#dcfce7;border:1px solid #86efac;vertical-align:middle;margin-right:4px"></span>Met target</span>
|
||||||
|
<span><span style="display:inline-block;width:12px;height:12px;background:#fef9c3;border:1px solid #d4b800;vertical-align:middle;margin-right:4px"></span>Near limit (>90%)</span>
|
||||||
|
<span><span style="display:inline-block;width:12px;height:12px;background:#fed7aa;border:1px solid #c2590a;vertical-align:middle;margin-right:4px"></span>Over limit</span>
|
||||||
|
<span style="color:#94a3b8">Near/over applies to: B, Vs, Ip, Is, P_out</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div><!-- /right-col -->
|
</div><!-- /right-col -->
|
||||||
@@ -1003,6 +1014,14 @@ async function runSweep() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sweepData = data;
|
sweepData = data;
|
||||||
|
// Stash constraint limits so updateTable can shade near-limit cells
|
||||||
|
sweepData._constraints = {
|
||||||
|
B_max_T: parseFloat(document.getElementById('con-B').value) || Infinity,
|
||||||
|
Vs_max: parseFloat(document.getElementById('con-Vs').value) || Infinity,
|
||||||
|
Ip_max: parseFloat(document.getElementById('con-Ip').value) || Infinity,
|
||||||
|
Is_max: parseFloat(document.getElementById('con-Is').value) || Infinity,
|
||||||
|
P_out_max_W: parseFloat(document.getElementById('con-Pout').value) || Infinity,
|
||||||
|
};
|
||||||
setMsg(msg, 'ok', `Done — ${data.rows.length} operating points computed.`);
|
setMsg(msg, 'ok', `Done — ${data.rows.length} operating points computed.`);
|
||||||
|
|
||||||
// Populate frequency dropdown
|
// Populate frequency dropdown
|
||||||
@@ -1187,7 +1206,6 @@ const _TABLE_COLS = [
|
|||||||
{ key: 'freq_hz', label: 'freq (Hz)' },
|
{ key: 'freq_hz', label: 'freq (Hz)' },
|
||||||
{ key: 'Z_load_R', label: 'R (Ω)' },
|
{ key: 'Z_load_R', label: 'R (Ω)' },
|
||||||
{ key: 'Z_load_X', label: 'X (Ω)' },
|
{ key: 'Z_load_X', label: 'X (Ω)' },
|
||||||
{ key: 'met_target', label: 'met' },
|
|
||||||
{ key: 'primary_tap', label: 'P tap' },
|
{ key: 'primary_tap', label: 'P tap' },
|
||||||
{ key: 'secondary_tap', label: 'S tap' },
|
{ key: 'secondary_tap', label: 'S tap' },
|
||||||
{ key: 'Vp_rms', label: 'Vp (V)' },
|
{ key: 'Vp_rms', label: 'Vp (V)' },
|
||||||
@@ -1214,11 +1232,6 @@ function fmtCell(key, val, row) {
|
|||||||
if (key === '_T_rise') { val = row ? row._T_rise : null; }
|
if (key === '_T_rise') { val = row ? row._T_rise : null; }
|
||||||
if (key === '_T_copper') { val = row ? row._T_copper : null; }
|
if (key === '_T_copper') { val = row ? row._T_copper : null; }
|
||||||
if (val === null || val === undefined) return '<span class="cell-null">—</span>';
|
if (val === null || val === undefined) return '<span class="cell-null">—</span>';
|
||||||
if (key === 'met_target') {
|
|
||||||
return val
|
|
||||||
? '<span class="cell-ok">YES</span>'
|
|
||||||
: '<span class="cell-bad">NO</span>';
|
|
||||||
}
|
|
||||||
if (key === 'efficiency' && typeof val === 'number') {
|
if (key === 'efficiency' && typeof val === 'number') {
|
||||||
return (val * 100).toFixed(2) + '%';
|
return (val * 100).toFixed(2) + '%';
|
||||||
}
|
}
|
||||||
@@ -1228,6 +1241,35 @@ function fmtCell(key, val, row) {
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an object mapping column key → 'over' | 'near' | null for a row,
|
||||||
|
* based on how close each value is to its constraint limit.
|
||||||
|
*
|
||||||
|
* 'over' = value exceeds the limit
|
||||||
|
* 'near' = value is within NEAR_THRESHOLD of the limit (ratio > 0.9)
|
||||||
|
* null = fine
|
||||||
|
*/
|
||||||
|
const _LIMIT_NEAR_THRESHOLD = 0.90; // flag cell when value/limit > this
|
||||||
|
|
||||||
|
function limitingCells(row, constraints) {
|
||||||
|
if (!constraints) return {};
|
||||||
|
const result = {};
|
||||||
|
|
||||||
|
function check(colKey, value, limit) {
|
||||||
|
if (value == null || !isFinite(limit) || limit <= 0) return;
|
||||||
|
const ratio = value / limit;
|
||||||
|
if (ratio > 1.0) result[colKey] = 'over';
|
||||||
|
else if (ratio > _LIMIT_NEAR_THRESHOLD) result[colKey] = 'near';
|
||||||
|
}
|
||||||
|
|
||||||
|
check('B_peak_T', row.B_peak_T, constraints.B_max_T);
|
||||||
|
check('Vs_rms', row.Vs_rms, constraints.Vs_max);
|
||||||
|
check('Ip_rms', row.Ip_rms, constraints.Ip_max);
|
||||||
|
check('Is_rms', row.Is_rms, constraints.Is_max);
|
||||||
|
check('P_out_W', row.P_out_W, constraints.P_out_max_W);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function updateTable(rows, T_rise, T_copper) {
|
function updateTable(rows, T_rise, T_copper) {
|
||||||
document.getElementById('table-card').style.display = 'block';
|
document.getElementById('table-card').style.display = 'block';
|
||||||
|
|
||||||
@@ -1239,12 +1281,24 @@ function updateTable(rows, T_rise, T_copper) {
|
|||||||
|
|
||||||
const thead = document.getElementById('sweep-table-head');
|
const thead = document.getElementById('sweep-table-head');
|
||||||
const tbody = document.getElementById('sweep-table-body');
|
const tbody = document.getElementById('sweep-table-body');
|
||||||
|
const constraints = sweepData && sweepData._constraints;
|
||||||
|
|
||||||
thead.innerHTML = '<tr>' + _TABLE_COLS.map(c => `<th>${c.label}</th>`).join('') + '</tr>';
|
thead.innerHTML = '<tr>' + _TABLE_COLS.map(c => `<th>${c.label}</th>`).join('') + '</tr>';
|
||||||
|
|
||||||
tbody.innerHTML = rows.map(r =>
|
tbody.innerHTML = rows.map(r => {
|
||||||
'<tr>' + _TABLE_COLS.map(c => `<td>${fmtCell(c.key, r[c.key], r)}</td>`).join('') + '</tr>'
|
const limits = limitingCells(r, constraints);
|
||||||
).join('');
|
const cells = _TABLE_COLS.map(c => {
|
||||||
|
const lvl = limits[c.key];
|
||||||
|
// P_out_W gets green when the optimizer met its target (and isn't near/over a limit)
|
||||||
|
const metGreen = c.key === 'P_out_W' && r.met_target && !lvl;
|
||||||
|
const cls = lvl === 'over' ? ' class="cell-limit-over"'
|
||||||
|
: lvl === 'near' ? ' class="cell-limit-near"'
|
||||||
|
: metGreen ? ' class="cell-limit-met"'
|
||||||
|
: '';
|
||||||
|
return `<td${cls}>${fmtCell(c.key, r[c.key], r)}</td>`;
|
||||||
|
});
|
||||||
|
return '<tr>' + cells.join('') + '</tr>';
|
||||||
|
}).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function triggerCsvDownload() {
|
function triggerCsvDownload() {
|
||||||
|
|||||||
Reference in New Issue
Block a user