Skip to content

Commit 8fbe474

Browse files
authored
Merge pull request #39 from NOAA-CEFI-Portal/develop
Visualization Page Refactor
2 parents f155f7a + 0fecdde commit 8fbe474

File tree

46 files changed

+161271
-12351
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+161271
-12351
lines changed

cefi.css

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
.news-log {
2+
width: 95%;
3+
height: 150px; /* Adjust height as needed */
4+
overflow-y: scroll;
5+
border: 8px solid #3F72AF;
6+
padding: 10px;
7+
box-sizing: border-box;
8+
border-radius: 10px; /* Rounded edges */
9+
background-color: #DBE2EF; /* Background color */
10+
margin-left: 2.5%;
11+
margin-right: 2.5%;
12+
}
13+
114
.google-form{
215
width: 100%;
316
height: 1000px;

data_access.html

+6
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ <h3>Variable Lists</h3>
298298
<a href="data_index/cefi_data_indexing.Projects.CEFI.regional_mom6.cefi_portal.northwest_atlantic.full_domain.seasonal_reforecast.json" target="_blank">JSON view</a>,
299299
<a href="data_index/cefi_data_indexing.Projects.CEFI.regional_mom6.cefi_portal.northwest_atlantic.full_domain.seasonal_reforecast.xml" target="_blank">XML view</a>
300300
</li>
301+
<li>
302+
Forecast:
303+
<a href="data_index/cefi_data_indexing.Projects.CEFI.regional_mom6.cefi_portal.northwest_atlantic.full_domain.seasonal_forecast.html" target="_blank">HTML view</a>,
304+
<a href="data_index/cefi_data_indexing.Projects.CEFI.regional_mom6.cefi_portal.northwest_atlantic.full_domain.seasonal_forecast.json" target="_blank">JSON view</a>,
305+
<a href="data_index/cefi_data_indexing.Projects.CEFI.regional_mom6.cefi_portal.northwest_atlantic.full_domain.seasonal_forecast.xml" target="_blank">XML view</a>
306+
</li>
301307
</ul>
302308
<ul class="nepTableOpt hidden">
303309
<li>

data_access.js

+95-113
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { optionList } from './hindcast.js';
2+
13
// setup local global variable (data structure and filenaming structure)
24
var region;
35
var subdomain;
@@ -88,7 +90,7 @@ async function createDataAccessExpType(reg,subDom){
8890
let elm = document.getElementById('expTypeDataQuery');
8991
let varJson = await fetchExperimentTypeOption(reg,subDom);
9092
let expTypeOptions = varJson.experiment_type;
91-
let df = window.optionList(expTypeOptions,expTypeOptions);
93+
let df = optionList(expTypeOptions,expTypeOptions);
9294
elm.appendChild(df);
9395

9496
}
@@ -123,26 +125,26 @@ async function createDataAccessOthers(reg,subDom,expType){
123125
// Output Frequency :
124126
let elm = document.getElementById('outFreqDataQuery');
125127
let avaiOptions = dataAccessJson.output_frequency;
126-
let df = window.optionList(avaiOptions,avaiOptions); //hindcast.js
128+
let df = optionList(avaiOptions,avaiOptions); //hindcast.js
127129
elm.appendChild(df);
128130

129131
// Grid Type :
130132
elm = document.getElementById('gridTypeDataQuery');
131133
avaiOptions = dataAccessJson.grid_type;
132-
df = window.optionList(avaiOptions,avaiOptions);
134+
df = optionList(avaiOptions,avaiOptions);
133135
elm.appendChild(df);
134136

135137
// Release :
136138
elm = document.getElementById('releaseDataQuery');
137139
avaiOptions = dataAccessJson.release;
138-
df = window.optionList(avaiOptions,avaiOptions);
140+
df = optionList(avaiOptions,avaiOptions);
139141
elm.appendChild(df);
140142

141143
// Variables :
142144
elm = document.getElementById('variableDataQuery');
143145
let valueOptions = variableJson.var_values;
144146
let nameOptions = variableJson.var_options;
145-
df = window.optionList(nameOptions,valueOptions);
147+
df = optionList(nameOptions,valueOptions);
146148
// Create the default empty option for variable that force user choose that related to a event listener
147149
// need this dynamically to be recreated when empty the dropdown
148150
// by other user actions
@@ -157,7 +159,7 @@ async function createDataAccessOthers(reg,subDom,expType){
157159
}
158160

159161
// async fetching the data_access_json cefi_data_option
160-
async function fetchDataOption(reg,subDom,expType) {
162+
export async function fetchDataOption(reg,subDom,expType) {
161163
try {
162164
const response = await fetch(
163165
'data_option_json/cefi_data_options.Projects.CEFI.regional_mom6.cefi_portal.'+
@@ -178,9 +180,11 @@ async function fetchDataOption(reg,subDom,expType) {
178180
console.error('There was a problem when async fetchDataOption:', error);
179181
}
180182
}
183+
// Attach the function to the window object
184+
// window.fetchDataOption = fetchDataOption;
181185

182186
// async fetching the data_access_json cefi_var_option
183-
async function fetchVarOption(reg,subDom,expType) {
187+
export async function fetchVarOption(reg,subDom,expType) {
184188
try {
185189
const response = await fetch(
186190
'data_option_json/cefi_var_options.Projects.CEFI.regional_mom6.cefi_portal.'+
@@ -201,6 +205,8 @@ async function fetchVarOption(reg,subDom,expType) {
201205
console.error('There was a problem when async fetchVarOption:', error);
202206
}
203207
}
208+
// Attach the function to the window object
209+
// window.fetchVarOption = fetchVarOption;
204210

205211
// function to clear all option below experiement type
206212
function data_access_all_clear(){
@@ -251,118 +257,94 @@ $('#variableDataQuery').on('change', function() {
251257
// (needed to avoid stacking more options)
252258
variable_below_all_clear();
253259

254-
// recreate options below experiment type due to changes
255-
var ens_options_fcast;
256-
var init_date_fcast;
257-
var ens_options_proj;
258-
var scenario_proj;
259-
createVariableSpecOptions() // the function return a promise obj from fetch
260-
.then((jsonData)=>{
261-
// Check if an attribute exists
262-
if ('ens_options_fcast' in jsonData) {
263-
ens_options_fcast = jsonData.ens_options_fcast;
264-
// ens_options_fcast :
265-
let elm = document.getElementById('ensOptionFcastDataQuery');
266-
let valueOptions = ens_options_fcast;
267-
let nameOptions = ens_options_fcast;
268-
df = window.optionList(nameOptions,valueOptions);
269-
// // Create the default empty option for variable that force user choose that related to a event listener
270-
// // need this dynamically to be recreated when empty the dropdown
271-
// // by other user actions
272-
// let defaultOption = document.createElement('option');
273-
// defaultOption.selected = true; // Make it selected
274-
// defaultOption.disabled = true; // Make it disabled
275-
// defaultOption.appendChild(document.createTextNode('Select an ensemble option')); // Set the text
276-
// df.insertBefore(defaultOption, df.firstChild)
277-
// // df.appendChild(defaultOption); // Append the default option to the fragment
278-
elm.appendChild(df);
279-
};
280-
if ('init_date_fcast' in jsonData) {
281-
init_date_fcast = jsonData.init_date_fcast;
282-
// init_date_fcast :
283-
let elm = document.getElementById('initialDateFcastDataQuery');
284-
let valueOptions = init_date_fcast;
285-
let nameOptions = init_date_fcast;
286-
df = window.optionList(nameOptions,valueOptions);
287-
// // Create the default empty option for variable that force user choose that related to a event listener
288-
// // need this dynamically to be recreated when empty the dropdown
289-
// // by other user actions
290-
// let defaultOption = document.createElement('option');
291-
// defaultOption.selected = true; // Make it selected
292-
// defaultOption.disabled = true; // Make it disabled
293-
// defaultOption.appendChild(document.createTextNode('Select an initial date')); // Set the text
294-
// df.insertBefore(defaultOption, df.firstChild)
295-
// // df.appendChild(defaultOption); // Append the default option to the fragment
296-
elm.appendChild(df);
297-
};
298-
if ('ens_options_proj' in jsonData) {
299-
ens_options_proj = jsonData.ens_options_proj;
300-
// ens_options_proj :
301-
let elm = document.getElementById('ensOptionProjDataQuery');
302-
let valueOptions = ens_options_proj;
303-
let nameOptions = ens_options_proj;
304-
df = window.optionList(nameOptions,valueOptions);
305-
// // Create the default empty option for variable that force user choose that related to a event listener
306-
// // need this dynamically to be recreated when empty the dropdown
307-
// // by other user actions
308-
// let defaultOption = document.createElement('option');
309-
// defaultOption.selected = true; // Make it selected
310-
// defaultOption.disabled = true; // Make it disabled
311-
// defaultOption.appendChild(document.createTextNode('Select an ensemble option')); // Set the text
312-
// df.insertBefore(defaultOption, df.firstChild)
313-
// // df.appendChild(defaultOption); // Append the default option to the fragment
314-
elm.appendChild(df);
315-
};
316-
if ('scenario_proj' in jsonData) {
317-
scenario_proj = jsonData.scenario_proj;
318-
// scenario_proj :
319-
let elm = document.getElementById('scenarioProjDataQuery');
320-
let valueOptions = scenario_proj;
321-
let nameOptions = scenario_proj;
322-
df = window.optionList(nameOptions,valueOptions);
323-
// // Create the default empty option for variable that force user choose that related to a event listener
324-
// // need this dynamically to be recreated when empty the dropdown
325-
// // by other user actions
326-
// let defaultOption = document.createElement('option');
327-
// defaultOption.selected = true; // Make it selected
328-
// defaultOption.disabled = true; // Make it disabled
329-
// defaultOption.appendChild(document.createTextNode('Select a scenario')); // Set the text
330-
// df.insertBefore(defaultOption, df.firstChild)
331-
// // df.appendChild(defaultOption); // Append the default option to the fragment
332-
elm.appendChild(df);
333-
};
334-
});
260+
// create options specific to variables
261+
createVariableSpecOptions();
262+
263+
});
264+
265+
// event listener for release changes that can also fire the fetch
266+
// in createVariableSpecOptions
267+
$('#releaseDataQuery').on('change', function() {
268+
// update variable
269+
release = $(this).val();
270+
271+
// clear all options below experiement type
272+
// (needed to avoid stacking more options)
273+
variable_below_all_clear();
274+
275+
// create options specific to variables
276+
createVariableSpecOptions();
335277

336278
});
337279

280+
281+
338282
// async functions for fetching variable and experiment specific option from backend
339283
async function createVariableSpecOptions() {
340-
var ajaxGet = "/cgi-bin/cefi_portal/create_variable_spec_options.py"
341-
+"?region="+region
342-
+"&subdomain="+subdomain
343-
+"&experiment_type="+$('#expTypeDataQuery').val()
344-
+"&output_frequency="+$('#outFreqDataQuery').val()
345-
+"&grid_type="+$('#gridTypeDataQuery').val()
346-
+"&release="+$('#releaseDataQuery').val()
347-
+"&variable="+$('#variableDataQuery').val();
348-
349-
350-
console.log('https://webtest.psd.esrl.noaa.gov/'+ajaxGet)
351-
352-
return fetch(ajaxGet)
353-
.then(response => {
354-
if (!response.ok) {
355-
throw new Error('Network response was not ok');
356-
}
357-
return response.json();
358-
})
359-
.catch(error => {
360-
// Handle errors here
361-
console.error('Fetch json failed when creating variable specific options:', error);
362-
});
363-
}
284+
var ajaxGet = "/cgi-bin/cefi_portal/datatab_create_variable_spec_options.py"
285+
+ "?region=" + region
286+
+ "&subdomain=" + subdomain
287+
+ "&experiment_type=" + $('#expTypeDataQuery').val()
288+
+ "&output_frequency=" + $('#outFreqDataQuery').val()
289+
+ "&grid_type=" + $('#gridTypeDataQuery').val()
290+
+ "&release=" + $('#releaseDataQuery').val()
291+
+ "&variable=" + $('#variableDataQuery').val();
292+
293+
console.log('https://webtest.psd.esrl.noaa.gov/' + ajaxGet);
364294

295+
try {
296+
const response = await fetch(ajaxGet);
297+
if (!response.ok) {
298+
throw new Error('Network response was not ok');
299+
}
300+
const jsonData = await response.json();
301+
302+
// recreate options below experiment type due to changes
303+
var ens_options_fcast;
304+
var init_date_fcast;
305+
var ens_options_proj;
306+
var scenario_proj;
307+
308+
if ('ens_options_fcast' in jsonData) {
309+
ens_options_fcast = jsonData.ens_options_fcast;
310+
let elm = document.getElementById('ensOptionFcastDataQuery');
311+
let valueOptions = ens_options_fcast;
312+
let nameOptions = ens_options_fcast;
313+
let df = optionList(nameOptions, valueOptions);
314+
elm.appendChild(df);
315+
}
316+
317+
if ('init_date_fcast' in jsonData) {
318+
init_date_fcast = jsonData.init_date_fcast;
319+
let elm = document.getElementById('initialDateFcastDataQuery');
320+
let valueOptions = init_date_fcast;
321+
let nameOptions = init_date_fcast;
322+
let df = optionList(nameOptions, valueOptions);
323+
elm.appendChild(df);
324+
}
325+
326+
if ('ens_options_proj' in jsonData) {
327+
ens_options_proj = jsonData.ens_options_proj;
328+
let elm = document.getElementById('ensOptionProjDataQuery');
329+
let valueOptions = ens_options_proj;
330+
let nameOptions = ens_options_proj;
331+
let df = optionList(nameOptions, valueOptions);
332+
elm.appendChild(df);
333+
}
334+
335+
if ('scenario_proj' in jsonData) {
336+
scenario_proj = jsonData.scenario_proj;
337+
let elm = document.getElementById('scenarioProjDataQuery');
338+
let valueOptions = scenario_proj;
339+
let nameOptions = scenario_proj;
340+
let df = optionList(nameOptions, valueOptions);
341+
elm.appendChild(df);
342+
}
365343

344+
} catch (error) {
345+
console.error('Fetch json failed when creating variable specific options:', error);
346+
}
347+
}
366348

367349
// event listener for data query button click
368350
$('#genQueryButton').on('click', function() {
@@ -401,7 +383,7 @@ async function generateDataQuery() {
401383
ens_opt = $('#ensOptionProjDataQuery').val();
402384
};
403385

404-
var ajaxGet = "/cgi-bin/cefi_portal/generate_data_query.py"
386+
var ajaxGet = "/cgi-bin/cefi_portal/datatab_generate_data_query.py"
405387
+"?region="+region
406388
+"&subdomain="+subdomain
407389
+"&experiment_type="+experiment_type

0 commit comments

Comments
 (0)