diff --git a/assets/src/scripts/components/hydrograph/index.js b/assets/src/scripts/components/hydrograph/index.js
index ebaa25b14b684187845c4ecfca2257a073529dd8..190b649069c8fd67b8c2c96a9149b650fdc71603 100644
--- a/assets/src/scripts/components/hydrograph/index.js
+++ b/assets/src/scripts/components/hydrograph/index.js
@@ -8,7 +8,7 @@ const { select } = require('d3-selection');
 const { createStructuredSelector } = require('reselect');
 
 const { addSVGAccessibility } = require('../../accessibility');
-const { USWDS_MEDIUM_SCREEN, USWDS_SMALL_SCREEN, STATIC_URL } = require('../../config');
+const { USWDS_SMALL_SCREEN, STATIC_URL } = require('../../config');
 const { dispatch, link, provide } = require('../../lib/redux');
 const { Actions } = require('../../store');
 const { mediaQuery } = require('../../utils');
@@ -27,7 +27,7 @@ const { allTimeSeriesSelector,  isVisibleSelector, titleSelector,
 const { createTooltipFocus, createTooltipText } = require('./tooltip');
 const { coerceStatisticalSeries } = require('./statistics');
 
-const { getCurrentDateRange } = require('../../selectors/timeSeriesSelector');
+const { getCurrentDateRange, isLoadingTS } = require('../../selectors/timeSeriesSelector');
 
 
 const drawMessage = function (elem, message) {
@@ -407,7 +407,16 @@ const attachToNode = function (store, node, {siteno} = {}) {
 
     store.dispatch(Actions.resizeUI(window.innerWidth, node.offsetWidth));
     select(node)
-        .call(provide(store))
+        .call(provide(store));
+    select(node)
+        .call(link(function(elem, isLoadingCurrentTS) {
+            elem.select('.loading-indicator').remove();
+            if (isLoadingCurrentTS) {
+                select(elem).append('i')
+                    .attr('class', 'fas fa-spinner fa-spin');
+            }
+        }, isLoadingTS('current:P7D')));
+    select(node)
         .call(link(createDaterangeControls, createStructuredSelector({
             siteno: () => siteno,
             showControls: hasTimeSeriesWithPoints('current', 'P7D')
diff --git a/assets/src/scripts/components/map/index.spec.js b/assets/src/scripts/components/map/index.spec.js
index b71f7376c036a9a57bbd79495abc4094eae532d7..cc6b46a56729780b9dbdd3bf54edb6aadc63e308 100644
--- a/assets/src/scripts/components/map/index.spec.js
+++ b/assets/src/scripts/components/map/index.spec.js
@@ -4,7 +4,7 @@ const proxyquire = require('proxyquireify')(require);
 const { attachToNode } = require('./index');
 const { configureStore } = require('../../store');
 
-fdescribe('map module', () => {
+describe('map module', () => {
     let mapNode;
     let store;
     let floodDataMock;
diff --git a/assets/src/scripts/selectors/timeSeriesSelector.js b/assets/src/scripts/selectors/timeSeriesSelector.js
index 9bc234e44dd256c7aee533c6c314f15240df326f..f5ded6053a3d1e786d2b5d98d9e38079a9c1356e 100644
--- a/assets/src/scripts/selectors/timeSeriesSelector.js
+++ b/assets/src/scripts/selectors/timeSeriesSelector.js
@@ -6,13 +6,17 @@ const { createSelector } = require('reselect');
  */
 export const getVariables = state => state.series.variables ? state.series.variables : null;
 
+export const getMethods = state => state.series.methods ? state.series.methods : null;
+
+export const getQueryInfo = state => state.series.queryInfo || {};
+
+
 export const getCurrentVariableID = state => state.timeSeriesState.currentVariableID;
 
 export const getCurrentDateRange = state => state.timeSeriesState.currentDateRange;
 
-export const getMethods = state => state.series.methods ? state.series.methods : null;
+export const getLoadingTsKeys = state => state.timeSeriesState.loadingTSKeys;
 
-export const getQueryInfo = state => state.series.queryInfo || {};
 
 /*
  * Selectors the return derived data from the state
@@ -111,3 +115,7 @@ export const getRequestTimeRange = memoize((tsKey, period, parmCd) => createSele
     }
 ));
 
+export const isLoadingTS = memoize(tsKey => createSelector(
+    getLoadingTsKeys,
+    (loadingTSKeys) => loadingTSKeys.includes(tsKey)
+));
diff --git a/assets/src/scripts/store/index.js b/assets/src/scripts/store/index.js
index 66eebd5d4c15b693867b64b5a1e3a6bdb9a6b922..defa7856fdbf4f34ba103404fe5fb6781e3b22b3 100644
--- a/assets/src/scripts/store/index.js
+++ b/assets/src/scripts/store/index.js
@@ -50,9 +50,12 @@ export const Actions = {
     retrieveTimeSeries(siteno, params=null) {
         return function (dispatch, getState) {
             const currentState = getState();
+            const requestKey = getTsRequestKey('current', 'P7D')(currentState);
+            dispatch(Actions.addTimeSeriesLoading([requestKey]));
+
             const timeSeries = getTimeSeries({sites: [siteno], params}).then(
                 series => {
-                    const requestKey = getTsRequestKey('current', 'P7D')(currentState);
+                    dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                     const collection = normalize(series, requestKey);
 
                     // Get the start/end times of this request's range.
@@ -77,6 +80,7 @@ export const Actions = {
                     return {collection, startTime, endTime};
                 },
                 () => {
+                    dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                     dispatch(Actions.resetTimeSeries(getTsRequestKey('current', 'P7D')(currentState)));
                     dispatch(Actions.toggleTimeSeries('current', false));
                     return {
@@ -193,6 +197,18 @@ export const Actions = {
             type: 'TIMESERIES_PLAY_STOP'
         };
     },
+    addTimeSeriesLoading(tsKeys) {
+        return {
+            type: 'TIMESERIES_LOADING_ADD',
+            tsKeys
+        };
+    },
+    removeTimeSeriesLoading(tsKeys) {
+        return {
+            type: 'TIMESERIES_LOADING_REMOVE',
+            tsKeys
+        };
+    },
     setFloodFeatures(stages, extent) {
         return {
             type: 'SET_FLOOD_FEATURES',
@@ -289,7 +305,8 @@ export const configureStore = function (initialState) {
             currentDateRange: 'P7D',
             currentVariableID: null,
             cursorOffset: null,
-            audiblePlayId: null
+            audiblePlayId: null,
+            loadingTSKeys: []
         },
         floodState: {
             gageHeight: null
diff --git a/assets/src/scripts/store/timeSeriesStateReducer.js b/assets/src/scripts/store/timeSeriesStateReducer.js
index f3222f341295714ae98ecef5d192bc035251aef9..46529150e8925f9a73e057296a254a4fe6ab1863 100644
--- a/assets/src/scripts/store/timeSeriesStateReducer.js
+++ b/assets/src/scripts/store/timeSeriesStateReducer.js
@@ -48,6 +48,20 @@ const timeSeriesPlayStop = function(timeSeriesState) {
     };
 };
 
+const addLoadingTimeSeries = function(timeSeriesState, action) {
+    return {
+        ...timeSeriesState,
+        loadingTSKeys: timeSeriesState.loadingTSKeys.concat([action.tsKeys])
+    };
+};
+
+const removeLoadingTimeSeries = function(timeSeriesState, action) {
+    return {
+        ...timeSeriesState,
+        loadingTSKeys: timeSeriesState.loadingTSKeys.filter((tsKey) => action.tsKeys.includes(tsKey))
+    };
+};
+
 /*
  * Slice reducer
  */
@@ -59,6 +73,8 @@ export const timeSeriesStateReducer = function(timeSeriesState={}, action) {
         case 'SET_CURSOR_OFFSET': return setCursorOffset(timeSeriesState, action);
         case 'TIMESERIES_PLAY_ON': return timeSeriesPlayOn(timeSeriesState, action);
         case 'TIMESERIES_PLAY_STOP': return timeSeriesPlayStop(timeSeriesState, action);
+        case 'TIMESERIES_LOADING_ADD': return addLoadingTimeSeries(timeSeriesState, action);
+        case 'TIMESERIES_LOADING_REMOVE': return removeLoadingTimeSeries(timeSeriesState, action);
         default: return timeSeriesState;
     }
 };