diff --git a/assets/src/scripts/components/hydrograph/index.js b/assets/src/scripts/components/hydrograph/index.js index d7bfc2153611fc4e360358912342663bc3965ca1..4de53869c0af8873a53d627f4c49be06e26e7594 100644 --- a/assets/src/scripts/components/hydrograph/index.js +++ b/assets/src/scripts/components/hydrograph/index.js @@ -22,7 +22,7 @@ const { CIRCLE_RADIUS, CIRCLE_RADIUS_SINGLE_PT, SPARK_LINE_DIM, layoutSelector } const { drawSimpleLegend, legendMarkerRowsSelector } = require('./legend'); const { plotSeriesSelectTable, availableTimeseriesSelector } = require('./parameters'); const { xScaleSelector, yScaleSelector, timeSeriesScalesByParmCdSelector } = require('./scales'); -const { currentVariableSelector, methodsSelector, isVisibleSelector, titleSelector, +const { allTimeSeriesSelector, currentVariableSelector, methodsSelector, isVisibleSelector, titleSelector, descriptionSelector, currentVariableTimeSeriesSelector, timeSeriesSelector } = require('./timeseries'); const { createTooltipFocus, createTooltipText } = require('./tooltip'); @@ -291,6 +291,7 @@ const timeSeriesGraph = function (elem) { .call(createTitle) .call(createTooltipText) .append('svg') + .classed('hydrograph-svg', true) .call(link((elem, layout) => elem.attr('viewBox', `0 0 ${layout.width + layout.margin.left + layout.margin.right} ${layout.height + layout.margin.top + layout.margin.bottom}`), layoutSelector)) .call(link(addSVGAccessibility, createStructuredSelector({ title: titleSelector, @@ -326,13 +327,6 @@ const timeSeriesGraph = function (elem) { showLabel: (state) => state.showMedianStatsLabel }))); }); - - elem.call(link(plotSeriesSelectTable, createStructuredSelector({ - availableTimeseries: availableTimeseriesSelector, - lineSegmentsByParmCd: lineSegmentsByParmCdSelector('current'), - timeSeriesScalesByParmCd: timeSeriesScalesByParmCdSelector('current')(SPARK_LINE_DIM), - layout: layoutSelector - }))); elem.append('div') .call(link(plotSROnlyTable, createStructuredSelector({ tsKey: () => 'current', @@ -435,14 +429,27 @@ const attachToNode = function (store, node, {siteno} = {}) { store.dispatch(Actions.resizeUI(window.innerWidth, node.offsetWidth)); select(node) - .call(provide(store)) + .call(provide(store)); + select(node).select('.graph-container') .call(link(controlGraphDisplay, timeSeriesSelector('current'))) .call(timeSeriesGraph) - .call(cursorSlider); - select(node).append('div') - .classed('ts-legend-controls-container', true) - .call(timeSeriesLegend) - .call(graphControls); + .call(cursorSlider) + .append('div') + .classed('ts-legend-controls-container', true) + .call(timeSeriesLegend) + .call(graphControls); + select(node).select('.select-timeseries-container') + .call(link(plotSeriesSelectTable, createStructuredSelector({ + availableTimeseries: availableTimeseriesSelector, + lineSegmentsByParmCd: lineSegmentsByParmCdSelector('current'), + timeSeriesScalesByParmCd: timeSeriesScalesByParmCdSelector('current')(SPARK_LINE_DIM), + layout: layoutSelector + }))); + select(node).select('.provisional-data-alert') + .call(link(function(elem, allTimeSeries) { + elem.attr('hidden', Object.keys(allTimeSeries).length ? null : true); + + }, allTimeSeriesSelector)); window.onresize = function() { diff --git a/assets/src/scripts/components/hydrograph/index.spec.js b/assets/src/scripts/components/hydrograph/index.spec.js index 66e540cebd791033f6a932da102a0b11ee1a5704..e0993eb2777ea0ec836a27ca5a8a239eb6fef929 100644 --- a/assets/src/scripts/components/hydrograph/index.spec.js +++ b/assets/src/scripts/components/hydrograph/index.spec.js @@ -135,8 +135,12 @@ describe('Hydrograph charting module', () => { beforeEach(() => { let body = select('body'); - body.append('div') + let component = body.append('div') .attr('id', 'hydrograph'); + component.append('div').attr('class', 'graph-container'); + component.append('div').attr('class', 'select-timeseries-container'); + component.append('div').attr('class', 'provisional-data-alert'); + graphNode = document.getElementById('hydrograph'); }); @@ -155,7 +159,7 @@ describe('Hydrograph charting module', () => { .call(provide(store)) .call(timeSeriesGraph); let svgNodes = graphNode.getElementsByTagName('svg'); - expect(svgNodes.length).toBe(3); + expect(svgNodes.length).toBe(1); expect(graphNode.innerHTML).toContain('hydrograph-container'); }); @@ -251,14 +255,13 @@ describe('Hydrograph charting module', () => { width: 400, currentVariableID: '45807197' }); - select(graphNode) - .call(provide(store)) - .call(timeSeriesGraph); + + attachToNode(store, graphNode, {siteno: '123456788'}); }); it('should render the correct number svg nodes', () => { - // one main hydrograph and two sparklines - expect(selectAll('svg').size()).toBe(3); + // one main hydrograph, legend and two sparklines + expect(selectAll('svg').size()).toBe(4); }); it('should have a title div', () => { @@ -276,21 +279,21 @@ describe('Hydrograph charting module', () => { it('should render timeseries data as a line', () => { // There should be one segment per time-series. Each is a single // point, so should be a circle. - expect(selectAll('svg .line-segment').size()).toBe(2); + expect(selectAll('.hydrograph-svg .line-segment').size()).toBe(2); }); it('should render a rectangle for masked data', () => { - expect(selectAll('g.current-mask-group').size()).toBe(1); + expect(selectAll('.hydrograph-svg g.current-mask-group').size()).toBe(1); }); it('should have a point for the median stat data with a label', () => { - expect(selectAll('svg #median-points circle.median-data-series').size()).toBe(1); - expect(selectAll('svg #median-points text').size()).toBe(0); + expect(selectAll('#median-points circle.median-data-series').size()).toBe(1); + expect(selectAll('#median-points text').size()).toBe(0); }); it('show the labels for the median stat data showMedianStatsLabel is true', () => { store.dispatch(Actions.showMedianStatsLabel(true)); - expect(selectAll('svg #median-points text').size()).toBe(1); + expect(selectAll('#median-points text').size()).toBe(1); }); it('should have tooltips for the select series table', () => { @@ -371,4 +374,24 @@ describe('Hydrograph charting module', () => { expect(selectAll('#ts-compare-group .line-segment').size()).toBe(0); }); }); + + describe('hiding/show provisional alert', () => { + it('Expects the provisional alert to be visible when time series data is provided', () => { + let store = configureStore(TEST_STATE); + attachToNode(store, graphNode, {siteno: '12345678'}); + + expect(select(graphNode).select('.provisional-data-alert').attr('hidden')).toBeNull(); + }); + + it('Expects the provisional alert to be hidden when no time series data is provided', () => { + let store = configureStore({ + ...TEST_STATE, + series: {}, + currentVariableID: '' + }); + attachToNode(store, graphNode, {siteno: '12345678'}); + + expect(select(graphNode).select('.provisional-data-alert').attr('hidden')).toBe('true'); + }); + }); }); diff --git a/assets/src/scripts/index.js b/assets/src/scripts/index.js index 41f0c1b40858c37efee01ddbc2ef91f8314295ea..ac23ea17aeff696b825b19fb8635f0123e59951d 100644 --- a/assets/src/scripts/index.js +++ b/assets/src/scripts/index.js @@ -27,6 +27,7 @@ function main() { for (let node of nodes) { COMPONENTS[node.dataset.component](store, node, node.dataset); } + } catch (err) { // Send exception to Google Analytics. window.ga('send', 'exception', { diff --git a/assets/src/styles/pages/_monitoring_location.scss b/assets/src/styles/pages/_monitoring_location.scss index 52e6fffa6e055d7067563875fe2186defc83c465..6b94874ef29971c84a5f2329362854962238872b 100644 --- a/assets/src/styles/pages/_monitoring_location.scss +++ b/assets/src/styles/pages/_monitoring_location.scss @@ -24,7 +24,7 @@ table#site-summary { word-wrap: break-word; } } -#provisional-data-alert { +.provisional-data-alert { p { height: 6em; overflow-y: scroll; diff --git a/waterdata/templates/macros/components.html b/waterdata/templates/macros/components.html index c1141415a7f913578d4c9791c1607448419ff838..f276cf344a0f13fb993a642d14dcc3af8a7e6d9e 100644 --- a/waterdata/templates/macros/components.html +++ b/waterdata/templates/macros/components.html @@ -1,5 +1,21 @@ {% macro TimeseriesComponent(site_no) -%} <div class="wdfn-component" data-component="hydrograph" data-siteno="{{ site_no }}"> + <div class="graph-container"></div> + <div class="select-timeseries-container"></div> + <div class="usa-alert usa-alert-info provisional-data-alert" role="alert" hidden> + <div class="usa-alert-body"><h3 class="usa-alert-heading">Provisional Data Statement</h3> + <p class="usa-alert-text"> + Data are provisional and subject to revision until they have been thoroughly reviewed and received final approval. + Current condition data relayed by satellite or other telemetry are automatically screened to not display improbable + values until they can be verified. Provisional data may be inaccurate due to instrument malfunctions or physical + changes at the measurement site. Subsequent review based on field inspections and measurements may result in + significant revisions to the data. Data users are cautioned to consider carefully the provisional nature of the + information before using it for decisions that concern personal or public safety or the conduct of business that + involves substantial monetary or operational consequences. Information concerning the accuracy and appropriate uses + of these data or concerning other hydrologic data may be obtained from the USGS. + </p> + </div> + </div> </div> {%- endmacro %} diff --git a/waterdata/templates/monitoring_location.html b/waterdata/templates/monitoring_location.html index 91f5529b0f417018904017164c8b29e6e5cde6ae..3c3dbe0ef2ae87154365ad98cb379df1a75c630b 100644 --- a/waterdata/templates/monitoring_location.html +++ b/waterdata/templates/monitoring_location.html @@ -58,20 +58,6 @@ <p id="site-description">{{ components.Description(stations[0].site_no, location_with_values, parm_grp_summary) }}</p> </div> {{ components.TimeseriesComponent(stations[0].site_no) }} - <div id="provisional-data-alert" class="usa-alert usa-alert-info" role="alert"> - <div class="usa-alert-body"><h3 class="usa-alert-heading">Provisional Data Statement</h3> - <p class="usa-alert-text"> - Data are provisional and subject to revision until they have been thoroughly reviewed and received final approval. - Current condition data relayed by satellite or other telemetry are automatically screened to not display improbable - values until they can be verified. Provisional data may be inaccurate due to instrument malfunctions or physical - changes at the measurement site. Subsequent review based on field inspections and measurements may result in - significant revisions to the data. Data users are cautioned to consider carefully the provisional nature of the - information before using it for decisions that concern personal or public safety or the conduct of business that - involves substantial monetary or operational consequences. Information concerning the accuracy and appropriate uses - of these data or concerning other hydrologic data may be obtained from the USGS. - </p> - </div> - </div> {% if stations[0].dec_lat_va and stations[0].dec_long_va %} {{ components.FloodSliderComponent() }} {{ components.MapComponent(stations[0].site_no, stations[0].dec_lat_va, stations[0].dec_long_va) }}