Spaces:
Build error
Build error
| let currentPredictions = []; | |
| let locations = {}; | |
| let variables = {}; | |
| $(document).ready(function() { | |
| loadInitialData(); | |
| setupEventListeners(); | |
| }); | |
| function loadInitialData() { | |
| // Load locations | |
| $.get('/api/locations', function(data) { | |
| locations = data; | |
| updateLocationSelector(); | |
| }); | |
| // Load variables | |
| $.get('/api/variables', function(data) { | |
| variables = data; | |
| }); | |
| // Load map | |
| loadMap(); | |
| } | |
| function setupEventListeners() { | |
| $('#locationSelect').change(function() { | |
| const selected = $(this).val(); | |
| $('#predictBtn').prop('disabled', !selected); | |
| if (selected) { | |
| $('#currentConditions').hide(); | |
| } | |
| }); | |
| $('#stepsSlider').on('input', function() { | |
| $('#stepsValue').text($(this).val()); | |
| }); | |
| $('#predictBtn').click(function() { | |
| const location = $('#locationSelect').val(); | |
| const steps = $('#stepsSlider').val(); | |
| if (location) { | |
| getPredictions(location, steps); | |
| } | |
| }); | |
| } | |
| function updateLocationSelector() { | |
| const select = $('#locationSelect'); | |
| select.empty(); | |
| select.append('<option value="">Select a location...</option>'); | |
| Object.keys(locations).forEach(location => { | |
| select.append(`<option value="${location}">${location}</option>`); | |
| }); | |
| } | |
| function loadMap() { | |
| $.get('/api/map', function(mapHtml) { | |
| $('#map-container').html(mapHtml); | |
| }).fail(function() { | |
| $('#map-container').html('<div class="loading">Map failed to load</div>'); | |
| }); | |
| } | |
| function getPredictions(location, steps) { | |
| $('#predictBtn').text('🔄 Predicting...').prop('disabled', true); | |
| $.get(`/api/predict/${location}?steps=${steps}`, function(data) { | |
| currentPredictions = data; | |
| updateCharts(); | |
| showCurrentConditions(data[0]); | |
| $('#predictBtn').text('🔮 Get Wave Predictions').prop('disabled', false); | |
| }).fail(function() { | |
| alert('Failed to get predictions. Please try again.'); | |
| $('#predictBtn').text('🔮 Get Wave Predictions').prop('disabled', false); | |
| }); | |
| } | |
| function updateCharts() { | |
| if (currentPredictions.length === 0) return; | |
| updateWavePeriodChart(); | |
| updateDirectionChart(); | |
| updateSummaryChart(); | |
| } | |
| function updateWavePeriodChart() { | |
| const times = currentPredictions.map(p => p.timestamp); | |
| const mwpTrace = { | |
| x: times, | |
| y: currentPredictions.map(p => p.predictions.mwp), | |
| type: 'scatter', | |
| mode: 'lines+markers', | |
| name: 'Mean Wave Period', | |
| line: {color: '#667eea', width: 3} | |
| }; | |
| const pp1dTrace = { | |
| x: times, | |
| y: currentPredictions.map(p => p.predictions.pp1d), | |
| type: 'scatter', | |
| mode: 'lines+markers', | |
| name: 'Peak Wave Period', | |
| line: {color: '#764ba2', width: 3} | |
| }; | |
| const layout = { | |
| title: 'Wave Period Predictions', | |
| xaxis: {title: 'Time'}, | |
| yaxis: {title: 'Period (seconds)'}, | |
| plot_bgcolor: '#f8f9ff', | |
| paper_bgcolor: 'white' | |
| }; | |
| Plotly.newPlot('wavePeriodChart', [mwpTrace, pp1dTrace], layout); | |
| } | |
| function updateDirectionChart() { | |
| const times = currentPredictions.map(p => p.timestamp); | |
| const directionTrace = { | |
| x: times, | |
| y: currentPredictions.map(p => p.predictions.mwd), | |
| type: 'scatter', | |
| mode: 'lines+markers', | |
| name: 'Wave Direction', | |
| line: {color: '#48bb78', width: 3}, | |
| yaxis: 'y' | |
| }; | |
| const windTrace = { | |
| x: times, | |
| y: currentPredictions.map(p => p.predictions.wind), | |
| type: 'scatter', | |
| mode: 'lines+markers', | |
| name: 'Wind Speed', | |
| line: {color: '#ed8936', width: 3}, | |
| yaxis: 'y2' | |
| }; | |
| const layout = { | |
| title: 'Wave Direction & Wind Speed', | |
| xaxis: {title: 'Time'}, | |
| yaxis: {title: 'Direction (degrees)', side: 'left'}, | |
| yaxis2: { | |
| title: 'Wind Speed (m/s)', | |
| side: 'right', | |
| overlaying: 'y' | |
| }, | |
| plot_bgcolor: '#f8f9ff', | |
| paper_bgcolor: 'white' | |
| }; | |
| Plotly.newPlot('directionChart', [directionTrace, windTrace], layout); | |
| } | |
| function updateSummaryChart() { | |
| const variables = ['mwp', 'mwd', 'pp1d', 'wind']; | |
| const variableNames = { | |
| 'mwp': 'Mean Wave Period', | |
| 'mwd': 'Wave Direction', | |
| 'pp1d': 'Peak Wave Period', | |
| 'wind': 'Wind Speed' | |
| }; | |
| const currentValues = variables.map(v => | |
| currentPredictions[0].predictions[v] | |
| ); | |
| const trace = { | |
| x: variables.map(v => variableNames[v]), | |
| y: currentValues, | |
| type: 'bar', | |
| marker: { | |
| color: ['#667eea', '#48bb78', '#764ba2', '#ed8936'], | |
| opacity: 0.8 | |
| } | |
| }; | |
| const layout = { | |
| title: 'Current Conditions Summary', | |
| yaxis: {title: 'Value'}, | |
| plot_bgcolor: '#f8f9ff', | |
| paper_bgcolor: 'white' | |
| }; | |
| Plotly.newPlot('summaryChart', [trace], layout); | |
| } | |
| function showCurrentConditions(firstPrediction) { | |
| const conditions = firstPrediction.predictions; | |
| const html = ` | |
| <div class="condition-item"> | |
| <strong>Wave Period</strong><br> | |
| ${conditions.mwp} seconds | |
| </div> | |
| <div class="condition-item"> | |
| <strong>Wave Direction</strong><br> | |
| ${conditions.mwd}° | |
| </div> | |
| <div class="condition-item"> | |
| <strong>Peak Period</strong><br> | |
| ${conditions.pp1d} seconds | |
| </div> | |
| <div class="condition-item"> | |
| <strong>Wind Speed</strong><br> | |
| ${conditions.wind} m/s | |
| </div> | |
| `; | |
| $('#conditionsData').html(html); | |
| $('#currentConditions').show(); | |
| } | |