Short/long/closed display for each band calculated from latest data for each ionosonde station

This commit is contained in:
Ian Renton
2026-05-21 20:54:08 +01:00
parent c38be5b588
commit c939a5c1a1
15 changed files with 151 additions and 58 deletions

View File

@@ -411,11 +411,15 @@ function renderIonosondeData() {
const lufEntries = toSeries(station.luf);
const allTs = [...fof2Entries, ...mufEntries, ...lufEntries].map(e => e.ts);
if (allTs.length === 0) {
$('#ionosonde-latest').html('<div class="alert alert-warning mt-2 mb-0 py-2">No data available for this station.</div>');
$('#ionosonde-no-data').show();
$('#ionosonde-data-rows').hide();
$('#ionosonde-band-state').hide();
$('#ionosonde-chart').hide();
if (ionosondeChart) { ionosondeChart.destroy(); ionosondeChart = null; }
return;
}
$('#ionosonde-no-data').hide();
$('#ionosonde-data-rows').show();
// Populate latest values summary (visible on all screen sizes)
const latestFof2 = fof2Entries.length ? fof2Entries[fof2Entries.length - 1].val : null;
@@ -423,25 +427,33 @@ function renderIonosondeData() {
const latestLuf = lufEntries.length ? lufEntries[lufEntries.length - 1].val : null;
const minTs = allTs.length ? Math.min(...allTs) : null;
const maxTs = allTs.length ? Math.max(...allTs) : null;
let latestTimeStr = '';
if (maxTs != null) {
const latestDate = moment.utc(maxTs * 1000);
latestTimeStr = latestDate.format('DD MMM YYYY HH:mm [UTC]') + ' (' + latestDate.fromNow() + ')';
$('#ionosonde-latest-time').text(latestDate.format('DD MMM YYYY HH:mm [UTC]') + ' (' + latestDate.fromNow() + ')');
}
$('#ionosonde-latest-luf').text(latestLuf !== null ? latestLuf.toFixed(2) + ' MHz' : 'N/A');
$('#ionosonde-latest-fof2').text(latestFof2 !== null ? latestFof2.toFixed(2) + ' MHz' : 'N/A');
$('#ionosonde-latest-muf').text(latestMuf !== null ? latestMuf.toFixed(2) + ' MHz' : 'N/A');
$('#ionosonde-stale-warning').toggle(maxTs !== null && (Date.now() / 1000 - maxTs) > 12 * 3600);
// Populate band state tables. There are actually two tables to populate, which is pretty janky, but allows us to
// display horizontally on desktop but flip it around to become a vertical list on mobile.
const bandStateClass = {'Closed': 'bg-danger-subtle', 'Short': 'bg-primary-subtle', 'Long': 'bg-success-subtle'};
const bandStates = station.band_states;
if (bandStates && Object.keys(bandStates).length > 0) {
const headRow = $('#ionosonde-band-state-head').empty();
const dataRow = $('#ionosonde-band-state-row').empty();
const vBody = $('#ionosonde-band-state-body').empty();
Object.entries(bandStates).forEach(([band, state]) => {
const cls = bandStateClass[state] || '';
headRow.append($('<th>').addClass('text-center').text(band));
dataRow.append($('<td>').addClass('text-center ' + cls).text(state));
vBody.append($('<tr>').append($('<td>').addClass('fw-bold').text(band)).append($('<td>').addClass(cls).text(state)));
});
$('#ionosonde-band-state').show();
} else {
$('#ionosonde-band-state').hide();
}
const staleWarning = (maxTs !== null && (Date.now() / 1000 - maxTs) > 12 * 3600)
? '<div class="alert alert-warning mt-2 mb-0 py-2">Data is more than 12 hours old!</div>'
: '';
$('#ionosonde-latest').html(
'<div class="row align-items-center me-0">' +
'<div class="col-12 py-2 text-muted">Latest values as of ' + latestTimeStr + '</div></div>' +
'<div class="row border-bottom align-items-center me-0">' +
'<div class="col-12 col-md-4 py-2">LUF: <strong>' + (latestLuf !== null ? latestLuf.toFixed(2) + ' MHz' : 'N/A') + '</strong></div>' +
'<div class="col-12 col-md-4 py-2">foF2: <strong>' + (latestFof2 !== null ? latestFof2.toFixed(2) + ' MHz' : 'N/A') + '</strong></div>' +
'<div class="col-12 col-md-4 py-2">MUF (3000 km): <strong>' + (latestMuf !== null ? latestMuf.toFixed(2) + ' MHz' : 'N/A') + '</strong></div>' +
'</div>' +
staleWarning +
'</div>'
);
if (ionosondeChart) {
ionosondeChart.destroy();