Newer
Older
* Hydrograph charting module.
*/
Bucknell, Mary S.
committed
import {bindActionCreators} from 'redux';
import ReduxConnectVue from 'redux-connect-vue';
import {createStructuredSelector} from 'reselect';
Bucknell, Mary S.
committed
import {createApp, ref} from 'vue';
Bucknell, Mary S.
committed
Bucknell, Mary S.
committed
import {drawInfoAlert} from 'd3render/alerts';
import {renderTimeSeriesUrlParams} from 'ml/url-params';
import {getInputsForRetrieval} from 'ml/selectors/hydrograph-state-selector';
Bucknell, Mary S.
committed
import {retrieveGroundwaterLevelData} from 'ml/store/groundwater-level-field-visits';
import {retrieveHydrographData} from 'ml/store/hydrograph-data';
Bucknell, Mary S.
committed
import {retrieveHydrographParameters} from 'ml/store/hydrograph-parameters';
Bucknell, Mary S.
committed
import {setSelectedParameterCode, setCompareDataVisibility, setSelectedTimeSpan,
} from 'ml/store/hydrograph-state';
Bucknell, Mary S.
committed
Bucknell, Mary S.
committed
import {Actions as floodDataActions} from 'ml/store/flood-data';
import {getPreferredIVMethodID} from './selectors/time-series-data';
Bucknell, Mary S.
committed
import {showDataIndicators} from './data-indicator';
Williams, Darius Shamar
committed
Bucknell, Mary S.
committed
import {initializeTimeSeriesGraph, drawTimeSeriesGraphData} from './time-series-graph';
import DataTablesApp from './DataTablesApp.vue';
Bucknell, Mary S.
committed
import GraphControlsApp from './GraphControlsApp.vue';
import HydrographApp from './HydrographApp.vue';
import ParameterSelectionApp from './ParameterSelectionApp.vue';
import TimeDownloadGraphControlsApp from './TimeDownloadGraphControlsApp.vue';
Bucknell, Mary S.
committed
/* eslint-disable vue/one-component-per-file */
Bucknell, Mary S.
committed
Bucknell, Mary S.
committed
/*
* Renders the hydrograph on the node element using the Redux store for state information. The siteno, latitude, and
* longitude are required parameters. All others are optional and are used to set the initial state of the hydrograph.
Bucknell, Mary S.
committed
* @param {Redux store} store
* @param {DOM node} node
* @param {Object} - string properties to set initial state information. The property siteno is required
* @param {Promise} loadPromise - will resolve when any data needed by this module
* that is fetched by the caller has been fetched
* */
Bucknell, Mary S.
committed
sitename,
parameterCode,
compare,
period,
startDT,
endDT,
showOnlyGraph = false,
showMLName = false
Bucknell, Mary S.
committed
const nodeElem = select(node);
Bucknell, Mary S.
committed
const addTimeDownloadGraphControlsApp = function() {
const timeDownloadGraphControlsApp = createApp(TimeDownloadGraphControlsApp, {});
timeDownloadGraphControlsApp.use(ReduxConnectVue, {
store,
mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
mapStateToPropsFactory: createStructuredSelector
});
timeDownloadGraphControlsApp.provide('store', store);
timeDownloadGraphControlsApp.provide('siteno', siteno);
timeDownloadGraphControlsApp.provide('agencyCd', agencyCd);
timeDownloadGraphControlsApp.mount('#time-download-graph-controls-anchor');
};
if (!config.ivPeriodOfRecord && !config.gwPeriodOfRecord) {
Bucknell, Mary S.
committed
select(node).select('.graph-container').call(drawInfoAlert, {title: 'Hydrograph Alert', body: 'No IV or field visit data is available.'});
Bucknell, Mary S.
committed
}
Bucknell, Mary S.
committed
const initialLoadCompare = compare === 'true' || compare === true ? true : false;
const thisShowOnlyGraph = showOnlyGraph === 'true' || showOnlyGraph === true ? true : false;
const thisShowMLName = showMLName === 'true' || showMLName === true ? true : false;
Bucknell, Mary S.
committed
// Initialize all hydrograph state variables
store.dispatch(setSelectedParameterCode(parameterCode));
store.dispatch(setCompareDataVisibility(initialLoadCompare));
if (period) {
Bucknell, Mary S.
committed
store.dispatch(setSelectedTimeSpan(period));
} else if (startDT && endDT) {
Bucknell, Mary S.
committed
store.dispatch(setSelectedTimeSpan({
start: startDT,
end: endDT
}));
} else {
store.dispatch(setSelectedTimeSpan(config.ivPeriodOfRecord && config.ivPeriodOfRecord[parameterCode] ?
'P7D' : 'P1Y'));
Bucknell, Mary S.
committed
}
Bucknell, Mary S.
committed
Bucknell, Mary S.
committed
const initialLoadingComplete = ref(false);
Bucknell, Mary S.
committed
// Fetch all data needed to render the hydrograph
Bucknell, Mary S.
committed
const fetchHydrographDataPromise = store.dispatch(retrieveHydrographData(siteno, agencyCd,
getInputsForRetrieval(store.getState()), true));
Bucknell, Mary S.
committed
let fetchDataPromises = [fetchHydrographDataPromise];
Bucknell, Mary S.
committed
// if showing only graph make a call to retrieve all of the groundwater level data. Otherwise,
Bucknell, Mary S.
committed
// this is done when retrieving all hydrograph parameter meta data.
if (thisShowOnlyGraph) {
if (config.gwPeriodOfRecord) {
fetchDataPromises.push(store.dispatch(retrieveGroundwaterLevelData(siteno, agencyCd)));
}
} else {
fetchDataPromises.push(store.dispatch(retrieveHydrographParameters(siteno, agencyCd)));
}
Bucknell, Mary S.
committed
Bucknell, Mary S.
committed
// Fetch flood levels
Bucknell, Mary S.
committed
if (config.ivPeriodOfRecord && config.GAGE_HEIGHT_PARAMETER_CODE in config.ivPeriodOfRecord) {
Bucknell, Mary S.
committed
const fetchFloodLevelsPromise = store.dispatch(floodDataActions.retrieveFloodLevels(siteno));
Bucknell, Mary S.
committed
// If flood levels are to be shown then wait to render the hydrograph until those have been fetched.
if (parameterCode === config.GAGE_HEIGHT_PARAMETER_CODE) {
fetchDataPromises.push(fetchFloodLevelsPromise);
}
Bucknell, Mary S.
committed
}
Bucknell, Mary S.
committed
Bucknell, Mary S.
committed
// Render initial UI elements prior to completion of data fetching
if (!showOnlyGraph) {
Bucknell, Mary S.
committed
}
Bucknell, Mary S.
committed
const graphContainer = nodeElem.select('.graph-container');
graphContainer.call(initializeTimeSeriesGraph, store, siteno, agencyCd, sitename, thisShowMLName, !thisShowOnlyGraph);
showDataIndicators(true, store);
if (!showOnlyGraph) {
//TODO: The tooltips, legend and the main hydrograph can be added to the HydrographApp.
// The main hydrograph should be converted to a Vue component last. As part of that task we
// will figure out how to handle the loading indicator and the no data overlay
// The addition of the hydrograph-brush-container is merely to create the brush in the correct location
// This will change as we add things and eventually we won't need to do this.
graphContainer.append('div').attr('id', 'hydrograph-brush-container');
const hydrographApp = createApp(HydrographApp, {});
hydrographApp.use(ReduxConnectVue, {
store,
mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
mapStateToPropsFactory: createStructuredSelector
});
hydrographApp.provide('store', store);
hydrographApp.provide('siteno', siteno);
Bucknell, Mary S.
committed
hydrographApp.provide('initialLoadingComplete', initialLoadingComplete);
hydrographApp.mount('#hydrograph-brush-container');
Bucknell, Mary S.
committed
}
Bucknell, Mary S.
committed
if (!showOnlyGraph) {
// const graphControlsApp = createApp(GraphControlsApp, {});
// graphControlsApp.use(ReduxConnectVue, {
// store,
// mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
// mapStateToPropsFactory: createStructuredSelector
// });
// graphControlsApp.provide('store', store);
// graphControlsApp.provide('siteno', siteno);
// graphControlsApp.mount('.ts-legend-controls-container');
const parameterSelectionApp = createApp(ParameterSelectionApp, {});
parameterSelectionApp.use(ReduxConnectVue, {
store,
mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
mapStateToPropsFactory: createStructuredSelector
});
parameterSelectionApp.provide('store', store);
parameterSelectionApp.provide('siteno', siteno);
parameterSelectionApp.provide('agencyCode', agencyCd);
parameterSelectionApp.mount('.select-time-series-container');
Bucknell, Mary S.
committed
}
// Once hydrograph data has been fetched, render the time series data.
Bucknell, Mary S.
committed
Promise.all(fetchDataPromises).then(() => {
Bucknell, Mary S.
committed
initialLoadingComplete.value = true;
Bucknell, Mary S.
committed
// selectedIVMethodID should be set regardless of whether we are showing only the graph but the preferred method ID
// can not be determined until the data is fetched so that is done here.
const initialIVMethodID = timeSeriesId || getPreferredIVMethodID('primary')(store.getState());
store.dispatch(setSelectedIVMethodID(initialIVMethodID));
Bucknell, Mary S.
committed
showDataIndicators(false, store);
Bucknell, Mary S.
committed
graphContainer.call(drawTimeSeriesGraphData, store, !thisShowOnlyGraph);
Bucknell, Mary S.
committed
if (!thisShowOnlyGraph) {
// eslint-disable-next-line vue/one-component-per-file
const dataTablesApp = createApp(DataTablesApp, {});
dataTablesApp.use(ReduxConnectVue, {
store,
mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
mapStateToPropsFactory: createStructuredSelector
});
dataTablesApp.provide('store', store);
// data for DownLoadData component
dataTablesApp.provide('siteno', siteno);
dataTablesApp.provide('agencyCd', agencyCd);
dataTablesApp.mount('#iv-data-table-container');
Bucknell, Mary S.
committed
renderTimeSeriesUrlParams(store);
const statisticsTableApp = createApp(StatisticsTableApp, {});
statisticsTableApp.use(ReduxConnectVue, {
store,
mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
mapStateToPropsFactory: createStructuredSelector
});
statisticsTableApp.mount('.daily-statistical-data');
Bucknell, Mary S.
committed
}
Bucknell, Mary S.
committed
})
.catch(reason => {
console.error(reason);
throw reason;
Bucknell, Mary S.
committed
});