diff --git a/assets/src/scripts/d3-rendering/loading-indicator.js b/assets/src/scripts/d3-rendering/loading-indicator.js index caaf8d5e944c5572dd04e08f06207898ecfd89e2..e34095d8344dc506805ae3fa122a92c5d88db378 100644 --- a/assets/src/scripts/d3-rendering/loading-indicator.js +++ b/assets/src/scripts/d3-rendering/loading-indicator.js @@ -2,6 +2,6 @@ export const drawLoadingIndicator = function(elem, {showLoadingIndicator, sizeCl elem.select('.loading-indicator').remove(); if (showLoadingIndicator) { elem.append('i') - .attr('class', `loading-indicator fas ${sizeClass} fa-spinner`); + .attr('class', `loading-indicator fas ${sizeClass} fa-spin fa-spinner`); } }; \ No newline at end of file diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/data-loading-indicator.js b/assets/src/scripts/monitoring-location/components/hydrograph/data-loading-indicator.js index ebcf1e0d3c53c971d298c3064680e297aaa0af4e..b0a8b109231edd43d2e351354ed02b46e8e21003 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/data-loading-indicator.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/data-loading-indicator.js @@ -1,11 +1,16 @@ import {select} from 'd3-selection'; +import config from 'ui/config'; +import {mediaQuery} from 'ui/utils'; import {drawLoadingIndicator} from 'd3render/loading-indicator'; -export const showDataLoadingIndicator = function(isVisible) { - select('#hydrograph-loading-indicator-container') +export const showDataLoadingIndicator = function(isVisible, layoutHeight) { + const container = select('#hydrograph-loading-indicator-container') .call(drawLoadingIndicator, { showLoadingIndicator: isVisible, - sizeClass: 'fa-3x' + sizeClass: mediaQuery(config.USWDS_MEDIUM_SCREEN) ? 'fa-4x' : 'fa-2x' }); + if (isVisible && layoutHeight) { + container.style('transform', `translateY(${layoutHeight / 2}px`); + } }; \ No newline at end of file diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/date-controls.js b/assets/src/scripts/monitoring-location/components/hydrograph/date-controls.js index c4c58ef875d7c9f20e651042fc32b0083ae1978f..7f3b303481606e91713bb6f7a490f717422749c6 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/date-controls.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/date-controls.js @@ -10,6 +10,7 @@ import {getInputsForRetrieval} from 'ml/selectors/hydrograph-state-selector'; import {retrieveHydrographData} from 'ml/store/hydrograph-data'; import {clearGraphBrushOffset, setSelectedDateRange, setSelectedCustomDateRange} from 'ml/store/hydrograph-state'; +import {getMainLayout} from './selectors/layout'; import {showDataLoadingIndicator} from './data-loading-indicator'; const DATE_RANGE = [{ @@ -96,9 +97,11 @@ const drawSelectRadioButtons = function(elem, store, siteno, initialDateRange) { if (!isCustom) { store.dispatch(clearGraphBrushOffset()); store.dispatch(setSelectedDateRange(selectedValue)); - showDataLoadingIndicator(true); - store.dispatch(retrieveHydrographData(siteno, getInputsForRetrieval(store.getState()))); - //.then(showDataLoadingIndicator(false)); + showDataLoadingIndicator(true, getMainLayout(store.getState()).height); + store.dispatch(retrieveHydrographData(siteno, getInputsForRetrieval(store.getState()))) + .then(() => { + showDataLoadingIndicator(false); + }); } }); li.select('#custom-input').attr('aria-expanded', isCustomPeriod(initialDateRange)); @@ -229,7 +232,9 @@ const drawCustomDaysBeforeForm = function(container, store, siteno, initialDateR store.dispatch(setSelectedDateRange(`P${parseInt(daysBefore)}D`)); showDataLoadingIndicator(true); store.dispatch(retrieveHydrographData(siteno, getInputsForRetrieval(store.getState()))) - .then(() => showDataLoadingIndicator(false)); + .then(() => { + showDataLoadingIndicator(false) + }); } }); }; @@ -345,7 +350,9 @@ const drawCustomCalendarDaysForm = function(container, store, siteno, initialDat store.dispatch(setSelectedDateRange('custom')); showDataLoadingIndicator(true); store.dispatch(retrieveHydrographData(siteno, getInputsForRetrieval(store.getState()))) - .then(() => showDataLoadingIndicator(false)); + .then(() => { + showDataLoadingIndicator(false); + }); } } }); diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/date-controls.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/date-controls.test.js index 3dad7f46b36db69278d2839d32e3a8c0e6e54bce..9ca443242a3a7375147dfb18d42a5bacaba40bb4 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/date-controls.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/date-controls.test.js @@ -2,6 +2,7 @@ import {select} from 'd3-selection'; import sinon from 'sinon'; import config from 'ui/config'; +import * as utils from 'ui/utils'; import {getSelectedDateRange, getSelectedCustomDateRange} from 'ml/selectors/hydrograph-state-selector'; @@ -21,6 +22,8 @@ const TEST_STATE = { describe('monitoring-location/components/hydrograph/date-controls', () => { + utils.mediaQuery = jest.fn().mockReturnValue(true); + let div; let fakeServer; let store; diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/graph-controls.js b/assets/src/scripts/monitoring-location/components/hydrograph/graph-controls.js index faa01b36cbebd9cd5033ed7a55c42b55380fa6a5..9b414a299fd7465ce4d93484f32af911f71dfb9f 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/graph-controls.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/graph-controls.js @@ -45,7 +45,9 @@ export const drawGraphControls = function(elem, store, siteno) { startTime: currentTimeRange.start, endTime: currentTimeRange.end })) - .then(() => showDataLoadingIndicator(false)); + .then(() => { + showDataLoadingIndicator(false); + }); } }) // Sets the state of the toggle @@ -80,7 +82,9 @@ export const drawGraphControls = function(elem, store, siteno) { if (this.checked) { showDataLoadingIndicator(true); store.dispatch(retrieveMedianStatistics(siteno, getSelectedParameterCode(store.getState()))) - .then(() => showDataLoadingIndicator(false)); + .then(() => { + showDataLoadingIndicator(false); + }); } }) // Sets the state of the toggle diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/graph-controls.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/graph-controls.test.js index 5aa1851fea6efd6872e9d5ab2fb25e365dc06cdf..c4a5fb197a69dc6bdbd3cf6ced0700da32fc3ca8 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/graph-controls.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/graph-controls.test.js @@ -1,6 +1,8 @@ import {select} from 'd3-selection'; import sinon from 'sinon'; +import * as utils from 'ui/utils'; + import {configureStore} from 'ml/store'; import * as hydrographData from 'ml/store/hydrograph-data'; import {setSelectedDateRange} from 'ml/store/hydrograph-state'; @@ -10,6 +12,8 @@ import {TEST_CURRENT_TIME_RANGE} from './mock-hydrograph-state'; // Tests for the graph-controls module describe('monitoring-location/components/hydrograph/graph-controls', () => { + utils.mediaQuery = jest.fn().mockReturnValue(true); + describe('drawGraphControls', () => { let div; diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/index.js b/assets/src/scripts/monitoring-location/components/hydrograph/index.js index 4e2f74cc23a7cb83e70b4d754fc7d687cfc8b19e..366d07dedb65e70b3536df28c8cc164910badab4 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/index.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/index.js @@ -115,7 +115,7 @@ export const attachToNode = function(store, .call(drawTimeSeriesLegend, store); if (!showOnlyGraph) { - nodeElem.select('#hydrograph-date_controls-container') + nodeElem.select('#hydrograph-date-controls-container') .call(drawDateRangeControls, store, siteno, initialPeriod, { start: startDT, end: endDT diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js index d9a3a8aa4d7388a9f38e28b8078b1b9a52aad753..5e16f4269fdc7af2d503220a0adccc366f6d4c1a 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/index.test.js @@ -66,8 +66,13 @@ describe('monitoring-location/components/hydrograph module', () => { .attr('href', 'https://fakeserver/link'); let component = body.append('div') .attr('id', 'hydrograph'); - component.append('div').attr('class', 'loading-indicator-container'); - component.append('div').attr('class', 'graph-container'); + component.append('div').attr('id', 'hydrograph-date-controls-container'); + component.append('div').attr('id', 'hydrograph-method-picker-container'); + component.append('div').attr('class', 'graph-container') + .append('div') + .attr('id', 'hydrograph-loading-indicator-container') + .attr('class', 'loading-indicator-container'); + component.append('div').attr('class', 'select-time-series-container'); component.append('div').attr('id', 'iv-data-table-container'); diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/parameters.js b/assets/src/scripts/monitoring-location/components/hydrograph/parameters.js index b455ba9f3bf373586b6e1f43e9a2689fa2261fd9..a683565fae86916080e1d4ed06f95b2b360be0cc 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/parameters.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/parameters.js @@ -71,7 +71,9 @@ export const drawSelectionTable = function(container, store, siteno) { store.dispatch(setSelectedParameterCode(d.parameterCode)); showDataLoadingIndicator(true); store.dispatch(retrieveHydrographData(siteno, getInputsForRetrieval(store.getState()))) - .then(() => showDataLoadingIndicator(false)); + .then(() => { + showDataLoadingIndicator(false) + }); } }) .call(tr => { diff --git a/assets/src/scripts/monitoring-location/components/hydrograph/parameters.test.js b/assets/src/scripts/monitoring-location/components/hydrograph/parameters.test.js index deaf291f28a3255c51b3147a434da14ef2ff8b75..d19b164ada15cdff2cba44fa64b19025f7c92c97 100644 --- a/assets/src/scripts/monitoring-location/components/hydrograph/parameters.test.js +++ b/assets/src/scripts/monitoring-location/components/hydrograph/parameters.test.js @@ -1,7 +1,8 @@ -import {scaleLinear} from 'd3-scale'; import {select} from 'd3-selection'; import sinon from 'sinon'; +import * as utils from 'ui/utils'; + import {configureStore} from 'ml/store'; import * as hydrographData from 'ml/store/hydrograph-data'; @@ -9,6 +10,8 @@ import {TEST_HYDROGRAPH_PARAMETERS} from './mock-hydrograph-state'; import {drawSelectionTable} from './parameters'; describe('monitoring-location/components/hydrograph/parameters module', () => { + utils.mediaQuery = jest.fn().mockReturnValue(true); + const TEST_STATE = { hydrographParameters: TEST_HYDROGRAPH_PARAMETERS, hydrographState: { diff --git a/assets/src/scripts/monitoring-location/store/hydrograph-data.js b/assets/src/scripts/monitoring-location/store/hydrograph-data.js index 4f412a42e2f7005fc716dd3f559fbaad24cdf50a..2d230eda33a6c19a3ad994a4e72e44bf94a8321f 100644 --- a/assets/src/scripts/monitoring-location/store/hydrograph-data.js +++ b/assets/src/scripts/monitoring-location/store/hydrograph-data.js @@ -160,13 +160,11 @@ const retrieveIVData = function(siteno, dataKind, {parameterCode, period, startT */ export const retrievePriorYearIVData = function(siteno, {parameterCode, startTime, endTime}) { return function(dispatch, getState) { - const priorYearStartTime = DateTime.fromMillis(startTime).minus({days: 365}).toMillis(); - const priorYearEndTime = DateTime.fromMillis(endTime).minus({days: 365}).toMillis(); - const currentPriorYearTimeRange = getState().hydrographData.compareTimeRange || null; - if (currentPriorYearTimeRange && priorYearStartTime === currentPriorYearTimeRange.start && - priorYearEndTime === currentPriorYearTimeRange.end) { + if ('compareIVData' in getState().hydrographData) { return Promise.resolve(); } else { + const priorYearStartTime = DateTime.fromMillis(startTime).minus({days: 365}).toMillis(); + const priorYearEndTime = DateTime.fromMillis(endTime).minus({days: 365}).toMillis(); dispatch(setHydrographTimeRange({start: priorYearStartTime, end: priorYearEndTime}, 'prioryear')); return dispatch(retrieveIVData(siteno, 'compare', { parameterCode: parameterCode, @@ -185,7 +183,7 @@ export const retrievePriorYearIVData = function(siteno, {parameterCode, startTim */ export const retrieveMedianStatistics = function(siteno, parameterCode) { return function(dispatch, getState) { - if ('medianStatistics' in getState().hydrographData) { + if ('medianStatisticsData' in getState().hydrographData) { return Promise.resolve(); } else { const isCalculatedParameterCode = isCalculatedTemperature(parameterCode); diff --git a/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js b/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js index ba3944dbef3a85ee741e92b62ad7322f4aad22cd..03e1f12a151f7929c25549e2c5002d9d4f411784 100644 --- a/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js +++ b/assets/src/scripts/monitoring-location/store/hydrograph-data.test.js @@ -441,6 +441,25 @@ describe('monitoring-location/store/hydrograph-data', () => { expect(hydrographData.compareIVData).toBeDefined(); }); }); + + it('Expects a second call to retrievePriorYearIVData does not refetch the data', () => { + const currentTimeRange = store.getState().hydrographData.currentTimeRange; + const firstRetrieve = store.dispatch(retrievePriorYearIVData('11112222', { + parameterCode: '00060', + startTime: currentTimeRange.start, + endTime: currentTimeRange.end + })); + return firstRetrieve.then(() => { + return store.dispatch(retrievePriorYearIVData('11112222', { + parameterCode: '00060', + startTime: currentTimeRange.start, + endTime: currentTimeRange.end + })).then(() => { + const mockIVCalls = ivDataService.fetchTimeSeries.mock.calls; + expect(mockIVCalls).toHaveLength(2); + }); + }); + }); }); describe('retrieveMedianStatistics', () => { @@ -475,5 +494,16 @@ describe('monitoring-location/store/hydrograph-data', () => { expect(store.getState().hydrographData.medianStatisticsData).toBeDefined(); }); }); + + it('Expects a second call to median data does not fetch the data again', () => { + const firstRetrieve = store.dispatch(retrieveMedianStatistics('11112222', '00060')); + return firstRetrieve.then(() => { + store.dispatch(retrieveMedianStatistics('11112222', '00060')) + .then(() => { + const mockStatsCalls = statisticsDataService.fetchSiteStatistics.mock.calls; + expect(mockStatsCalls).toHaveLength(1); + }); + }); + }); }); }); \ No newline at end of file diff --git a/assets/src/scripts/schema.js b/assets/src/scripts/schema.js deleted file mode 100644 index 42f161462a9f032d05fc2f01b7e314b47aa1223f..0000000000000000000000000000000000000000 --- a/assets/src/scripts/schema.js +++ /dev/null @@ -1,165 +0,0 @@ -import memoize from 'fast-memoize'; -import {normalize as normalizr, schema} from 'normalizr'; -import {replaceHtmlEntities} from 'ui/utils'; - - -// sourceInfo schema -const siteCode = new schema.Entity('siteCodes', {}, {idAttribute: 'value'}); -const timeZone = new schema.Entity('timeZones', {}, {idAttribute: 'zoneAbbreviation'}); -const timeZoneInfo = new schema.Entity('timeZoneInfo', { - defaultTimeZone: timeZone, - daylightSavingsTimeZone: timeZone -}, {idAttribute: value => `${value.daylightSavingsTimeZone.zoneAbbreviation}:${value.defaultTimeZone.zoneAbbreviation}:${value.siteUsesDaylightSavingsTime}`}); -const sourceInfo = new schema.Entity('sourceInfo', { - siteCode: [siteCode], - timeZoneInfo: timeZoneInfo -}, {idAttribute: value => value.siteCode.map(s => s.value).join(':')}); - -// variable schema -const option = new schema.Entity('options', {}, {idAttribute: 'optionCode'}); -const variable = new schema.Entity('variables', { - options: [option] -}, { - idAttribute: 'oid', - processStrategy: (variable) => { - // Eliminate unnecessary nesting on options and variableCode attributes - return { - ...variable, - options: variable.options.option, - variableName: replaceHtmlEntities(variable.variableName), - variableCode: variable.variableCode[0] - }; - } -}); - -// timeSeries schema -const qualifier = new schema.Entity('qualifiers', {}, {idAttribute: 'qualifierCode'}); -const method = new schema.Entity('methods', {}, {idAttribute: 'methodID'}); -const timeSeries = memoize(tsKey => new schema.Entity('timeSeries', { - qualifier: [qualifier], - method: method, - variable: variable -}, { - idAttribute: value => `${value.method.map(m => m.methodID).join(':')}:${tsKey}`, - processStrategy: (ts, parent) => { - // Return processed data, with date strings converted to Date objects. - // the "value" attribute renamed to "points", and start and end times - // added. Also flatten to a single method. - if (ts.method.length !== 1) { - console.error('Single method assumption violated'); - } - const data = { - ...ts, - tsKey, - method: ts.method[0], - points: ts.value.map(v => { - const value = parseFloat(v.value); - return { - ...v, - dateTime: new Date(v.dateTime).getTime(), - value: value === parent.variable.noDataValue ? null : value - }; - }) - }; - delete data.value; - return data; - } -})); - -// timeSeriesCollection schema -const queryInfo = memoize(tsKey => new schema.Entity('queryInfo', {}, { - idAttribute: () => tsKey, - processStrategy: value => { - const queryInfo = { - ...value, - notes: value.note.reduce((notes, note) => { - notes[note.title] = note.value; - return notes; - }, {}) - }; - delete queryInfo.note; - - // Extract values out of filter:timeRange - // If this is a "period" query (eg, P7D) - if (queryInfo.notes['filter:timeRange'].indexOf('PERIOD') > -1) { - const regEx = /\[mode=(.+), period=P(.+)D, modifiedSince=(.+)\]/; - const parts = regEx.exec(queryInfo.notes['filter:timeRange']); - queryInfo.notes['filter:timeRange'] = { - mode: parts[1], - periodDays: parts[2], - modifiedSince: parts[3] === 'null' ? null : parts[3] - }; - - // If this is a "range" query (start and end times specified) - } else if (queryInfo.notes['filter:timeRange'].indexOf('RANGE') > -1) { - const regEx = /\[mode=(.+), modifiedSince=(.+)\] interval={INTERVAL\[(.+)\/(.+)\]}/; - const parts = regEx.exec(queryInfo.notes['filter:timeRange']); - queryInfo.notes['filter:timeRange'] = { - mode: parts[1], - modifiedSince: parts[2] === 'null' ? null : parts[3], - interval: { - start: new Date(parts[3]).getTime(), - end: new Date(parts[4]).getTime() - } - }; - } else { - console.error(`Can't make sense of time range string: ${queryInfo.notes['filter:timeRange']}`); - } - - // Store requestDT as a date object - queryInfo.notes.requestDT = new Date(queryInfo.notes.requestDT).getTime(); - - return queryInfo; - } -})); -const timeSeriesCollection = memoize(tsKey => new schema.Entity('timeSeriesCollections', { - sourceInfo: sourceInfo, - timeSeries: [timeSeries(tsKey)], - variable: variable -}, { - idAttribute: value => { - return `${value.name}:${tsKey}`; - }, - processStrategy: value => { - // Rename "values" attribute to "timeSeries", and - because it - // significantly simplifies selector logic - also store the variable ID - // on the timeSeries object. - const collection = { - ...value, - timeSeries: value.values.map(ts => { - return { - ...ts, - variable: value.variable - }; - }) - }; - delete collection['values']; - return collection; - } -})); - -// Top-level request schema -const request = memoize(tsKey => new schema.Entity('requests', { - queryInfo: queryInfo(tsKey), - timeSeriesCollections: [timeSeriesCollection(tsKey)] -}, { - idAttribute: () => tsKey, - processStrategy: root => { - // Flatten the response data - we only need the data in "value" - // Also, rename timeSeries to timeSeriesCollections. - return { - queryInfo: root.value.queryInfo, - timeSeriesCollections: root.value.timeSeries - }; - } -})); - -/** - * Flattens an IV service JSON response into a normalized entity mapping. - * @param {Object} ivData JSON version of WaterML data - * @param {String} tsKey Time series key. eg, "current" - * @return {Object} Normalized entities - */ -export const normalize = function(ivData, tsKey) { - return normalizr(ivData, request(tsKey)).entities; -}; diff --git a/assets/src/scripts/schema.test.js b/assets/src/scripts/schema.test.js deleted file mode 100644 index 506fee03cb82dee654bb9f5260e6221e5ff9b55f..0000000000000000000000000000000000000000 --- a/assets/src/scripts/schema.test.js +++ /dev/null @@ -1,342 +0,0 @@ -import {normalize} from './schema'; - - -describe('Normalizr schema', () => { - it('works', () => { - /* eslint no-use-before-define: 0 */ - const data = normalize(JSON.parse(MOCK_DATA), 'current'); - expect(data.queryInfo).toEqual({ - 'current': { - queryURL: 'http://waterservices.usgs.gov/nwis/iv/sites=05413500¶meterCd=00060&period=P7D&indent=on&siteStatus=all&format=json', - criteria: { - locationParam: '[ALL:05413500]', - variableParam: '[00060]', - parameter: [] - }, - notes: { - 'filter:sites': '[ALL:05413500]', - 'filter:timeRange': { - mode: 'PERIOD', - periodDays: '7', - modifiedSince: null - }, - 'filter:methodId': 'methodIds=[ALL]', - 'requestDT': new Date('2017-01-09T20:46:07.542Z').getTime(), - 'requestId': '1df59e50-f57e-11e7-8ba8-6cae8b663fb6', - 'disclaimer': 'Provisional data are subject to revision. Go to http://waterdata.usgs.gov/nwis/help/?provisional for more information.', - 'server': 'vaas01' - } - } - }); - expect(data.siteCodes).toEqual({ - '05413500': { - value: '05413500', - network: 'NWIS', - agencyCode: 'USGS' - } - }); - expect(data.timeZones).toEqual({ - 'CST': { - zoneOffset: '-06:00', - zoneAbbreviation: 'CST' - }, - CDT: { - zoneOffset: '-05:00', - zoneAbbreviation: 'CDT' - } - }); - expect(data.timeZoneInfo).toEqual({ - 'CDT:CST:true': { - defaultTimeZone: 'CST', - daylightSavingsTimeZone: 'CDT', - siteUsesDaylightSavingsTime: true - } - }); - expect(data.sourceInfo).toEqual({ - '05413500': { - siteName: 'GRANT RIVER AT BURTON, WI', - siteCode: ['05413500'], - timeZoneInfo: 'CDT:CST:true', - geoLocation: { - geogLocation: { - srs: 'EPSG:4326', - latitude: 42.72027778, - longitude: -90.8191667 - }, - localSiteXY: [ - - ] - }, - note: [], - siteType: [], - siteProperty: [{ - value: 'ST', - name: 'siteTypeCd' - }, { - value: '07060003', - name: 'hucCd' - }, { - value: '55', - name: 'stateCd' - }, { - value: '55043', - name: 'countyCd' - }] - } - }); - expect(data.qualifiers).toEqual({ - 'P': { - qualifierCode: 'P', - qualifierDescription: 'Provisional data subject to revision.', - qualifierID: 0, - network: 'NWIS', - vocabulary: 'uv_rmk_cd' - } - }); - expect(data.methods).toEqual({ - '158049': { - methodDescription: '', - methodID: 158049 - } - }); - expect(data.timeSeries).toEqual({ - '158049:current': { - qualifier: ['P'], - qualityControlLevel: [], - method: 158049, - source: [], - offset: [], - sample: [], - censorCode: [], - tsKey: 'current', - variable: '45807197', - points: [{ - value: 302, - qualifiers: ['P'], - dateTime: 1483390800000 - }, { - value: 301, - qualifiers: ['P'], - dateTime: 1483391700000 - }] - } - }); - expect(data.sourceInfo).toEqual({ - '05413500': { - siteName: 'GRANT RIVER AT BURTON, WI', - siteCode: [ - '05413500' - ], - timeZoneInfo: 'CDT:CST:true', - geoLocation: { - geogLocation: { - srs: 'EPSG:4326', - latitude:42.72027778, - longitude:-90.8191667 - }, - localSiteXY: [] - }, - note: [], - siteType: [], - siteProperty: [{ - value: 'ST', - name: 'siteTypeCd' - }, { - value: '07060003', - name: 'hucCd' - }, { - value: '55', - name: 'stateCd' - }, { - value: '55043', - name: 'countyCd' - }] - } - }); - expect(data.options).toEqual({ - '00000': { - name: 'Statistic', - optionCode: '00000' - } - }); - expect(data.variables).toEqual({ - '45807197': { - variableCode: { - value: '00060', - network: 'NWIS', - vocabulary: 'NWIS:UnitValues', - variableID: 45807197, - default: true - }, - variableName: 'Streamflow, ft³/s', - variableDescription: 'Discharge, cubic feet per second', - valueType: 'Derived Value', - unit: { - unitCode: 'ft3/s' - }, - options: ['00000'], - note: [], - noDataValue: -999999, - variableProperty: [], - oid: '45807197' - } - }); - expect(data.timeSeriesCollections).toEqual({ - 'USGS:05413500:00060:00000:current': { - sourceInfo: '05413500', - variable: '45807197', - name: 'USGS:05413500:00060:00000', - timeSeries: [ - '158049:current' - ] - } - }); - expect(data.requests).toEqual({ - current: { - queryInfo: 'current', - timeSeriesCollections: [ - 'USGS:05413500:00060:00000:current' - ] - } - }); - }); -}); - - -const MOCK_DATA = ` -{"name" : "ns1:timeSeriesResponseType", -"declaredType" : "org.cuahsi.waterml.TimeSeriesResponseType", -"scope" : "javax.xml.bind.JAXBElement$GlobalScope", -"value" : { - "queryInfo" : { - "queryURL" : "http://waterservices.usgs.gov/nwis/iv/sites=05413500¶meterCd=00060&period=P7D&indent=on&siteStatus=all&format=json", - "criteria" : { - "locationParam" : "[ALL:05413500]", - "variableParam" : "[00060]", - "parameter" : [ ] - }, - "note" : [ { - "value" : "[ALL:05413500]", - "title" : "filter:sites" - }, { - "value" : "[mode=PERIOD, period=P7D, modifiedSince=null]", - "title" : "filter:timeRange" - }, { - "value" : "methodIds=[ALL]", - "title" : "filter:methodId" - }, { - "value" : "2017-01-09T20:46:07.542Z", - "title" : "requestDT" - }, { - "value" : "1df59e50-f57e-11e7-8ba8-6cae8b663fb6", - "title" : "requestId" - }, { - "value" : "Provisional data are subject to revision. Go to http://waterdata.usgs.gov/nwis/help/?provisional for more information.", - "title" : "disclaimer" - }, { - "value" : "vaas01", - "title" : "server" - } ] - }, - "timeSeries" : [ { - "sourceInfo" : { - "siteName" : "GRANT RIVER AT BURTON, WI", - "siteCode" : [ { - "value" : "05413500", - "network" : "NWIS", - "agencyCode" : "USGS" - } ], - "timeZoneInfo" : { - "defaultTimeZone" : { - "zoneOffset" : "-06:00", - "zoneAbbreviation" : "CST" - }, - "daylightSavingsTimeZone" : { - "zoneOffset" : "-05:00", - "zoneAbbreviation" : "CDT" - }, - "siteUsesDaylightSavingsTime" : true - }, - "geoLocation" : { - "geogLocation" : { - "srs" : "EPSG:4326", - "latitude" : 42.72027778, - "longitude" : -90.8191667 - }, - "localSiteXY" : [ ] - }, - "note" : [ ], - "siteType" : [ ], - "siteProperty" : [ { - "value" : "ST", - "name" : "siteTypeCd" - }, { - "value" : "07060003", - "name" : "hucCd" - }, { - "value" : "55", - "name" : "stateCd" - }, { - "value" : "55043", - "name" : "countyCd" - } ] - }, - "variable" : { - "variableCode" : [ { - "value" : "00060", - "network" : "NWIS", - "vocabulary" : "NWIS:UnitValues", - "variableID" : 45807197, - "default" : true - } ], - "variableName" : "Streamflow, ft³/s", - "variableDescription" : "Discharge, cubic feet per second", - "valueType" : "Derived Value", - "unit" : { - "unitCode" : "ft3/s" - }, - "options" : { - "option" : [ { - "name" : "Statistic", - "optionCode" : "00000" - } ] - }, - "note" : [ ], - "noDataValue" : -999999.0, - "variableProperty" : [ ], - "oid" : "45807197" - }, - "values" : [ { - "value" : [ { - "value" : "302", - "qualifiers" : [ "P" ], - "dateTime" : "2017-01-02T15:00:00.000-06:00" - }, { - "value" : "301", - "qualifiers" : [ "P" ], - "dateTime" : "2017-01-02T15:15:00.000-06:00" - }], - "qualifier" : [ { - "qualifierCode" : "P", - "qualifierDescription" : "Provisional data subject to revision.", - "qualifierID" : 0, - "network" : "NWIS", - "vocabulary" : "uv_rmk_cd" - } ], - "qualityControlLevel" : [ ], - "method" : [ { - "methodDescription" : "", - "methodID" : 158049 - } ], - "source" : [ ], - "offset" : [ ], - "sample" : [ ], - "censorCode" : [ ] - } ], - "name" : "USGS:05413500:00060:00000" - } ] -}, -"nil" : false, -"globalScope" : true, -"typeSubstituted" : false -}`; diff --git a/assets/src/styles/components/hydrograph/_app.scss b/assets/src/styles/components/hydrograph/_app.scss index 5605e77d1e43409e71990675514a033699431a3e..d6f285e99a18803632c31ad14a49a3a7c474d4a7 100644 --- a/assets/src/styles/components/hydrograph/_app.scss +++ b/assets/src/styles/components/hydrograph/_app.scss @@ -116,7 +116,6 @@ #hydrograph-loading-indicator-container { position: absolute; top: 0; - bottom: 0; left: 0; right: 0; } diff --git a/wdfn-server/waterdata/templates/macros/components.html b/wdfn-server/waterdata/templates/macros/components.html index 8c63a5eb54373a0818a5b176f5a8905fb968d141..4f0965501d400396f3d3e6bba47e043badca3ee0 100644 --- a/wdfn-server/waterdata/templates/macros/components.html +++ b/wdfn-server/waterdata/templates/macros/components.html @@ -2,11 +2,11 @@ <div class="wdfn-component" data-component="hydrograph" data-siteno="{{ site_data.site_no }}" data-agency-cd="{{ site_data.agency_cd }}" data-sitename="{{ site_data.station_nm }}" data-parameter-code="{{ default_parameter_code }}"> - <div id="hydrograph-date_controls-container"></div> + <div id="hydrograph-date-controls-container"></div> <div id="hydrograph-method-picker-container"></div> <div style="position: relative;"> <div class="graph-container"></div> - <div id="hydrograph-loading-indicator-container" class="display-flex flex-row flex-align-center loading-indicator-container"></div> + <div id="hydrograph-loading-indicator-container" class="loading-indicator-container"></div> </div> <div class="provisional-data-statement"> <p>