// Cache for the full dxstats API response, so we can reload on the fly if the user changes the value of their continent // in the select box let dxStatsData = null; // Load solar conditions function loadSolarConditions() { $.getJSON('/api/v1/solar', function(jsonData) { // HF const hfConditionClass = { 'Good': 'bg-success-subtle', 'Fair': 'bg-warning-subtle', 'Poor': 'bg-danger-subtle' }; if (jsonData.hf_conditions) { Object.entries(jsonData.hf_conditions).forEach(function([key, condition]) { const cell = $('#hf-conditions-' + key); cell.text(condition); cell.addClass(hfConditionClass[condition]); }); } // VHF if (jsonData.vhf_conditions) { Object.entries(jsonData.vhf_conditions).forEach(function([key, condition]) { const cell = $('#vhf-conditions-' + key); cell.text(condition); let vhfClass; if (condition === 'Band Closed') { vhfClass = 'bg-danger-subtle'; } else if (condition.includes('High')) { vhfClass = 'bg-warning-subtle'; } else { vhfClass = 'bg-success-subtle'; } cell.addClass(vhfClass); }); } if (jsonData.aurora_latitude !== null && jsonData.aurora_latitude !== undefined) { $('#vhf-conditions-aurora-lat').text(jsonData.aurora_latitude + '°'); } // Solar Weather const swFields = { 'sfi': 'sw-sfi', 'sunspots': 'sw-sunspots', 'band_conditions_desc': 'sw-solar-flux-desc', 'k_index': 'sw-k-index', 'a_index': 'sw-a-index', 'geomag_field': 'sw-geomag-field', 'geomag_storm_scale': 'sw-geomag-storm-scale', 'geomag_storm_desc': 'sw-geomag-storm-desc', 'geomag_noise': 'sw-geomag-noise', 'x_ray': 'sw-x-ray', 'blackout_desc': 'sw-xray-desc', 'proton_flux': 'sw-proton-flux', 'solar_storm_scale': 'sw-solar-storm-scale', 'proton_flux_desc': 'sw-proton-desc', 'electron_flux': 'sw-electron-flux', 'electron_flux_desc': 'sw-electron-desc', }; Object.entries(swFields).forEach(function([field, id]) { const val = jsonData[field]; if (val !== null && val !== undefined) { $('#' + id).text(val); } }); // Solar Weather - colouring function applySwClass(valsId, descId, cls) { $('#' + valsId).addClass(cls); $('#' + descId).addClass(cls); } const sfi = jsonData.sfi; if (sfi !== null && sfi !== undefined) { applySwClass('sw-solar-flux-vals', 'sw-solar-flux-desc', sfi > 150 ? 'bg-success-subtle' : sfi > 90 ? 'bg-warning-subtle' : 'bg-danger-subtle'); } const kIndex = jsonData.k_index; if (kIndex !== null && kIndex !== undefined) { applySwClass('sw-geomag-vals', 'sw-geomag-desc', kIndex < 5 ? 'bg-success-subtle' : kIndex < 7 ? 'bg-warning-subtle' : 'bg-danger-subtle'); } const xRay = jsonData.x_ray; if (xRay) { const letter = xRay[0].toUpperCase(); const xRayClass = (letter === 'X') ? 'bg-danger-subtle' : (letter === 'M') ? 'bg-warning-subtle' : 'bg-success-subtle'; applySwClass('sw-xray-vals', 'sw-xray-desc', xRayClass); } const protonFlux = jsonData.proton_flux; if (protonFlux !== null && protonFlux !== undefined) { applySwClass('sw-proton-vals', 'sw-proton-desc', protonFlux <= 100 ? 'bg-success-subtle' : protonFlux <= 10000 ? 'bg-warning-subtle' : 'bg-danger-subtle'); } const electronFlux = jsonData.electron_flux; if (electronFlux !== null && electronFlux !== undefined) { applySwClass('sw-electron-vals', 'sw-electron-desc', electronFlux <= 100 ? 'bg-success-subtle' : electronFlux <= 1000 ? 'bg-warning-subtle' : 'bg-danger-subtle'); } }); } // Render the DX stats table for the currently selected DE continent function renderDxStats() { if (!dxStatsData) { return; } const deContinent = $('#dxstats-de-continent').val(); const deData = dxStatsData[deContinent]; if (!deData) { return; } const cells = []; Object.entries(deData).forEach(function([dxContinent, bands]) { Object.entries(bands).forEach(function([band, count]) { const cell = $('#dxstats-' + dxContinent + '-' + band); cell.text(count); cells.push({ cell, count }); }); }); const counts = cells.map(function(c) { return c.count; }); const min = Math.min(...counts); const max = Math.max(...counts); const range = max - min; cells.forEach(function({ cell, count }) { const t = range > 0 ? (count - min) / range : 0; const cls = t === 0 ? 'bg-danger-subtle' : t < 0.05 ? 'bg-warning-subtle' : 'bg-success-subtle'; cell.removeClass('bg-danger-subtle bg-warning-subtle bg-success-subtle').addClass(cls); }); } // Called when the DE continent select changes function dxStatsContientChanged() { saveSettings(); renderDxStats(); } // Fetch DX stats from the API and render function loadDxStats() { $.getJSON('/api/v1/dxstats', function(jsonData) { dxStatsData = jsonData; renderDxStats(); }); } // Startup $(document).ready(function() { loadSettings(); loadSolarConditions(); loadDxStats(); });