Show a warning instead of an empty canvas if the ionosonde station has no data, and also show a warning if we have data but it's old.

This commit is contained in:
Ian Renton
2026-05-16 11:26:23 +01:00
parent a7a45190cb
commit d655354d05
12 changed files with 54 additions and 31 deletions

View File

@@ -1691,9 +1691,8 @@ components:
type: object
nullable: true
description: >
Ionosonde measurements from the GIRO Data Center, keyed by URSI station code. Only
stations for which data was successfully retrieved are included. Null if the
GIROIonosonde provider has not yet completed its first poll or if this data source is disabled.
Ionosonde measurements from the GIRO Data Center, keyed by URSI station code. All known stations are
included, but not all of them may contain data.
additionalProperties:
$ref: '#/components/schemas/IonosondeStation'
@@ -1712,7 +1711,7 @@ components:
fof2:
type: object
nullable: true
description: F2 layer critical frequency (foF2) measurements in MHz, keyed by UNIX timestamp (UTC seconds since epoch) of each measurement.
description: F2 layer critical frequency (foF2) measurements in MHz, keyed by UNIX timestamp (UTC seconds since epoch) of each measurement. Can be null if there is no data.
additionalProperties:
type: number
example:
@@ -1721,7 +1720,7 @@ components:
muf:
type: object
nullable: true
description: Maximum Usable Frequency (MUF) for a 3000 km path in MHz, keyed by UNIX timestamp (UTC seconds since epoch) of each measurement.
description: Maximum Usable Frequency (MUF) for a 3000 km path in MHz, keyed by UNIX timestamp (UTC seconds since epoch) of each measurement. Can be null if there is no data.
additionalProperties:
type: number
example:

View File

@@ -380,7 +380,9 @@ function populateIonosondeDropdown(data) {
// Render the foF2/MUF data and line chart for the currently selected station
function renderIonosondeData() {
// First make sure that we have some data, that a station entry is selected in the drop-down box, and that the
// data contains an entry for that station. If not, bail out at this point.
// data contains an entry for that station. If not, this represents an odd state (over and above just "no data for
// this station", so bail out at this point. The user will have to reselect something from the list, or wait until
// the API is behaving itself again.
if (!ionosondeData) return;
const ursi = $('#ionosonde-station').val();
if (!ursi) return;
@@ -406,7 +408,12 @@ function renderIonosondeData() {
const fof2Entries = toSeries(station.fof2);
const mufEntries = toSeries(station.muf);
const allTs = [...fof2Entries, ...mufEntries].map(e => e.ts);
if (allTs.length === 0) return;
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-chart').hide();
if (ionosondeChart) { ionosondeChart.destroy(); ionosondeChart = null; }
return;
}
// Populate latest values summary (visible on all screen sizes)
const latestFof2 = fof2Entries.length ? fof2Entries[fof2Entries.length - 1].val : null;
@@ -418,12 +425,16 @@ function renderIonosondeData() {
const latestDate = moment.utc(maxTs * 1000);
latestTimeStr = latestDate.format('DD MMM YYYY HH:mm [UTC]') + ' (' + latestDate.fromNow() + ')';
}
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 border-bottom align-items-center me-0">' +
'<div class="col-12 col-md-6 py-2 text-muted">Latest values as of ' + latestTimeStr + '</div>' +
'<div class="col-12 col-md-2 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>'
);
@@ -564,6 +575,9 @@ function renderIonosondeData() {
},
plugins: [bandLinesPlugin],
});
// Chart canvas is normally hidden until we get here with some definitely good data. Now we have that so show it
$('#ionosonde-chart').show();
}
// Called when the ionosonde station select changes