Skip to content
Snippets Groups Projects
index.js 7.05 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
     * Hydrograph charting module.
     */
    
    import {createStructuredSelector} from 'reselect';
    
    import config from '../../config';
    
    import {drawWarningAlert, drawInfoAlert} from '../../d3-rendering/alerts';
    
    import {hasAnyTimeSeries, getCurrentParmCd, getVariables} from '../../selectors/time-series-selector';
    
    import {renderTimeSeriesUrlParams} from '../../url-params';
    
    import {cursorSlider} from './cursor';
    import {drawDateRangeControls} from './date-controls';
    import {lineSegmentsByParmCdSelector} from './drawing-data';
    import {drawGraphBrush} from './graph-brush';
    import {drawGraphControls} from './graph-controls';
    import {SPARK_LINE_DIM}  from './layout';
    import {drawTimeSeriesLegend} from './legend';
    
    import {drawLoadingIndicator} from '../../d3-rendering/loading-indicator';
    
    import {drawMethodPicker} from './method-picker';
    import {plotSeriesSelectTable, availableTimeSeriesSelector} from './parameters';
    import {timeSeriesScalesByParmCdSelector} from './scales';
    import {drawTimeSeriesGraph} from './time-series-graph';
    
    Bucknell, Mary S.'s avatar
    Bucknell, Mary S. committed
    const controlDisplay = function(elem, showElem) {
    
        elem.attr('hidden', showElem ? null : true);
    
    export const attachToNode = function (store,
                                          node,
                                          {
                                              siteno,
    
                                              showOnlyGraph = false,
                                              showMLName = false
                                          } = {}) {
    
            select(node).call(drawWarningAlert, {title: 'Hydrograph Alert', body: 'No data is available.'});
    
        // Initialize hydrograph with the store and show the loading indicator
    
        store.dispatch(Actions.resizeUI(window.innerWidth, node.offsetWidth));
    
            .select('.loading-indicator-container')
    
            .call(drawLoadingIndicator, {showLoadingIndicator: true, sizeClass: 'fa-3x'});
    
        const fetchTimeZonePromise = store.dispatch(Actions.retrieveLocationTimeZone(config.siteLocation.latitude, config.siteLocation.longitude));
    
        if (showOnlyGraph) {
            // Only fetch what is needed
            if (parameterCode && period) {
    
                fetchDataPromise = store.dispatch(Actions.retrieveCustomTimePeriodTimeSeries(siteno, parameterCode, period, true));
    
            } else if (parameterCode && startDT && endDT) {
    
                // Don't fetch until time zone is available
                fetchDataPromise = fetchTimeZonePromise.then(() => {
                    store.dispatch(Actions.retrieveDataForDateRange(siteno, startDT, endDT, parameterCode));
                });
    
                fetchDataPromise = store.dispatch(Actions.retrieveTimeSeries(siteno, parameterCode ? [parameterCode] : null, true));
    
            // Retrieve all parameter codes for 7 days and median statistics
    
            fetchDataPromise = store.dispatch(Actions.retrieveTimeSeries(siteno))
    
                .then(() => {
                    // Fetch any extended data needed to set initial state
                    const currentParamCode = parameterCode ? parameterCode : getCurrentParmCd(store.getState());
                    if (period === 'P30D' || period === 'P1Y') {
                        store.dispatch(Actions.retrieveExtendedTimeSeries(siteno, period, currentParamCode));
                    } else if (startDT && endDT) {
    
                        fetchTimeZonePromise.then(() => {
                            store.dispatch(Actions.retrieveDataForDateRange(siteno, startDT, endDT, currentParamCode));
                        });
    
                    }
                });
            store.dispatch(Actions.retrieveMedianStatistics(siteno));
        }
    
            // Hide the loading indocatr
            nodeElem
                .select('.loading-indicator-container')
                .call(drawLoadingIndicator, {showLoadingIndicator: false, sizeClass: 'fa-3x'});
    
            if (!hasAnyTimeSeries(store.getState())) {
                drawInfoAlert(nodeElem, {body: 'No time series data available for this site'});
            } else {
                //Update time series state
                if (parameterCode) {
    
                    const isThisParamCode = function (variable) {
    
                        return variable.variableCode.value === parameterCode;
                    };
                    const thisVariable = Object.values(getVariables(store.getState())).find(isThisParamCode);
                    store.dispatch(Actions.setCurrentVariable(thisVariable.oid));
                }
                if (compare) {
                    store.dispatch(Actions.toggleTimeSeries('compare', true));
                }
    
                if (timeSeriesId) {
                    store.dispatch(Actions.setCurrentMethodID(timeSeriesId));
                }
    
                // Initial data has been fetched and initial state set. We can render the hydrograph elements
                // Set up rendering functions for the graph-container
                let graphContainer = nodeElem.select('.graph-container')
                    .call(link(store, controlDisplay, hasAnyTimeSeries))
                    .call(drawTimeSeriesGraph, store, siteno, showMLName);
                if (!showOnlyGraph) {
                    graphContainer.call(cursorSlider, store);
                    graphContainer.call(drawGraphBrush, store);
                }
                graphContainer.append('div')
                    .classed('ts-legend-controls-container', true)
                    .call(drawTimeSeriesLegend, store);
    
                // Add UI interactive elements and the provisional data alert.
                if (!showOnlyGraph) {
                    nodeElem
                        .call(drawMethodPicker, store)
                        .call(drawDateRangeControls, store, siteno);
    
                    nodeElem.select('.ts-legend-controls-container')
                        .call(drawGraphControls, store);
    
                    nodeElem.select('.select-time-series-container')
                        .call(link(store, plotSeriesSelectTable, createStructuredSelector({
                            siteno: () => siteno,
                            availableTimeSeries: availableTimeSeriesSelector,
                            lineSegmentsByParmCd: lineSegmentsByParmCdSelector('current', 'P7D'),
                            timeSeriesScalesByParmCd: timeSeriesScalesByParmCdSelector('current', 'P7D', SPARK_LINE_DIM)
                        }), store));
                    nodeElem.select('.provisional-data-alert')
    
    
                    renderTimeSeriesUrlParams(store);
    
    Yan, Andrew N.'s avatar
    Yan, Andrew N. committed
            store.dispatch(Actions.resizeUI(window.innerWidth, node.offsetWidth));