diff --git a/assets/src/scripts/components/hydrograph/index.js b/assets/src/scripts/components/hydrograph/index.js
index 190b649069c8fd67b8c2c96a9149b650fdc71603..3c3cf715c9cb1e673ec97f6f59c2450e903274f7 100644
--- a/assets/src/scripts/components/hydrograph/index.js
+++ b/assets/src/scripts/components/hydrograph/index.js
@@ -355,6 +355,13 @@ const controlDisplay = function (elem, showElem) {
     elem.attr('hidden', showElem ? null : true);
 };
 
+const loadingIndicator = function(elem, {showLoadingIndicator, sizeClass}) {
+    elem.select('.loading-indicator').remove();
+    if (showLoadingIndicator) {
+        elem.append('i')
+            .attr('class', `loading-indicator fas ${sizeClass} fa-spin fa-spinner`);
+    }
+};
 
 const createDaterangeControls = function(elem, {siteno, showControls}) {
     const DATE_RANGE = [{
@@ -372,10 +379,17 @@ const createDaterangeControls = function(elem, {siteno, showControls}) {
     }];
     elem.select('#ts-daterange-select-container').remove();
     if (showControls) {
-        const container = elem.insert('ul', ':first-child')
-            .attr('id', 'ts-daterange-select-container')
+        const container = elem.insert('div', ':nth-child(2)')
+            .attr('id', 'ts-daterange-select-container');
+        const listContainer = container.append('ul')
             .attr('class', 'usa-fieldset-inputs usa-unstyled-list');
-        const li = container.selectAll('li')
+        container.append('div')
+            .attr('class', 'loading-indicator-container')
+            .call(link(loadingIndicator, createStructuredSelector({
+                showLoadingIndicator: isLoadingTS('current'),
+                sizeClass:() => 'fa-lg'
+            })));
+        const li = listContainer.selectAll('li')
             .data(DATE_RANGE)
             .enter().append('li');
         li.append('input')
@@ -408,14 +422,11 @@ const attachToNode = function (store, node, {siteno} = {}) {
     store.dispatch(Actions.resizeUI(window.innerWidth, node.offsetWidth));
     select(node)
         .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).select('.loading-indicator-container')
+        .call(link(loadingIndicator, createStructuredSelector({
+            showLoadingIndicator: isLoadingTS('current', 'P7D'),
+            sizeClass: () =>'fa-3x'
+        })));
     select(node)
         .call(link(createDaterangeControls, createStructuredSelector({
             siteno: () => siteno,
diff --git a/assets/src/scripts/selectors/timeSeriesSelector.js b/assets/src/scripts/selectors/timeSeriesSelector.js
index f5ded6053a3d1e786d2b5d98d9e38079a9c1356e..30e642027ff95ed8b9343dbbf53042a75c5d539d 100644
--- a/assets/src/scripts/selectors/timeSeriesSelector.js
+++ b/assets/src/scripts/selectors/timeSeriesSelector.js
@@ -115,7 +115,8 @@ export const getRequestTimeRange = memoize((tsKey, period, parmCd) => createSele
     }
 ));
 
-export const isLoadingTS = memoize(tsKey => createSelector(
+export const isLoadingTS = memoize((tsKey, period, parmCd) => createSelector(
     getLoadingTsKeys,
-    (loadingTSKeys) => loadingTSKeys.includes(tsKey)
+    getTsRequestKey(tsKey, period, parmCd),
+    (loadingTSKeys, tsRequestKey) => loadingTSKeys.includes(tsRequestKey)
 ));
diff --git a/assets/src/scripts/store/index.js b/assets/src/scripts/store/index.js
index defa7856fdbf4f34ba103404fe5fb6781e3b22b3..f36eb3c6229e5dc354fe4b7710e792977a178536 100644
--- a/assets/src/scripts/store/index.js
+++ b/assets/src/scripts/store/index.js
@@ -55,7 +55,6 @@ export const Actions = {
 
             const timeSeries = getTimeSeries({sites: [siteno], params}).then(
                 series => {
-                    dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                     const collection = normalize(series, requestKey);
 
                     // Get the start/end times of this request's range.
@@ -69,6 +68,8 @@ export const Actions = {
 
                     // Update the series data for the 'current' series
                     dispatch(Actions.addSeriesCollection('current', collection));
+                    dispatch(Actions.removeTimeSeriesLoading([requestKey]));
+
 
                     // Update the application state
                     dispatch(Actions.toggleTimeSeries('current', true));
@@ -80,8 +81,9 @@ export const Actions = {
                     return {collection, startTime, endTime};
                 },
                 () => {
-                    dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                     dispatch(Actions.resetTimeSeries(getTsRequestKey('current', 'P7D')(currentState)));
+                    dispatch(Actions.removeTimeSeriesLoading([requestKey]));
+
                     dispatch(Actions.toggleTimeSeries('current', false));
                     return {
                         collection: null,
@@ -90,7 +92,14 @@ export const Actions = {
                     };
                 }
             );
+
+            const medianRequestKey = getTsRequestKey('median')(currentState);
+            dispatch(Actions.addTimeSeriesLoading([medianRequestKey]));
             const medianStatistics = getMedianStatistics({sites: [siteno]});
+            medianStatistics.finally(() => {
+                dispatch(Actions.removeTimeSeriesLoading([medianRequestKey]));
+            });
+
             return Promise.all([timeSeries, medianStatistics]).then(([{collection, endTime}, stats]) => {
                 if (endTime) {
                     let medianCollection = parseMedianData(stats, endTime, collection && collection.variables ? collection.variables : {});
@@ -102,13 +111,18 @@ export const Actions = {
     },
     retrieveCompareTimeSeries(site, period, startTime, endTime) {
         return function (dispatch, getState) {
+            const requestKey = getTsRequestKey('compare', period)(getState());
+            dispatch(Actions.addTimeSeriesLoading([requestKey]));
             return getPreviousYearTimeSeries({site, startTime, endTime}).then(
                 series => {
-                    const requestKey = getTsRequestKey('compare', period)(getState());
                     const collection = normalize(series, requestKey);
                     dispatch(Actions.addSeriesCollection(requestKey, collection));
+                    dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                 },
-                () => dispatch(Actions.resetTimeSeries(getTsRequestKey('compare', period)(getState())))
+                () => {
+                    dispatch(Actions.resetTimeSeries(getTsRequestKey('compare', period)(getState())));
+                    dispatch(Actions.removeTimeSeriesLoading([requestKey]));
+                }
             );
         };
     },
@@ -122,7 +136,8 @@ export const Actions = {
                 const endTime = new Date(getRequestTimeRange('current', 'P7D')(state).end);
                 let startTime = calcStartTime(period, endTime);
 
-                return getTimeSeries({
+                dispatch(Actions.addTimeSeriesLoading([requestKey]));
+                const currentTimeSeries = getTimeSeries({
                     sites: [site],
                     params: [parmCd],
                     startDate: startTime,
@@ -131,13 +146,16 @@ export const Actions = {
                     series => {
                         const collection = normalize(series, requestKey);
                         dispatch(Actions.addSeriesCollection(requestKey, collection));
-                        dispatch(Actions.retrieveCompareTimeSeries(site, period, startTime, endTime));
+                        dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                     },
                     () => {
                         console.log(`Unable to fetch data for period ${period} and parameter code ${parmCd}`);
                         dispatch(Actions.addSeriesCollection(requestKey, {}));
+                        dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                     }
                 );
+                dispatch(Actions.retrieveCompareTimeSeries(site, period, startTime, endTime));
+                return currentTimeSeries;
             }
         };
     },
diff --git a/assets/src/scripts/store/timeSeriesStateReducer.js b/assets/src/scripts/store/timeSeriesStateReducer.js
index 46529150e8925f9a73e057296a254a4fe6ab1863..ab76dd176e63b0bc5b77bab93ed03bae1efa0837 100644
--- a/assets/src/scripts/store/timeSeriesStateReducer.js
+++ b/assets/src/scripts/store/timeSeriesStateReducer.js
@@ -51,14 +51,14 @@ const timeSeriesPlayStop = function(timeSeriesState) {
 const addLoadingTimeSeries = function(timeSeriesState, action) {
     return {
         ...timeSeriesState,
-        loadingTSKeys: timeSeriesState.loadingTSKeys.concat([action.tsKeys])
+        loadingTSKeys: timeSeriesState.loadingTSKeys.concat(action.tsKeys)
     };
 };
 
 const removeLoadingTimeSeries = function(timeSeriesState, action) {
     return {
         ...timeSeriesState,
-        loadingTSKeys: timeSeriesState.loadingTSKeys.filter((tsKey) => action.tsKeys.includes(tsKey))
+        loadingTSKeys: timeSeriesState.loadingTSKeys.filter((tsKey) => !action.tsKeys.includes(tsKey))
     };
 };
 
diff --git a/assets/src/styles/components/hydrograph/_app.scss b/assets/src/styles/components/hydrograph/_app.scss
index 835bd9eda07744dc6ad5ea68c9656fa962073aa4..d0d5fbcaadb038b2bb614cdbe29064c8b34a62b9 100644
--- a/assets/src/styles/components/hydrograph/_app.scss
+++ b/assets/src/styles/components/hydrograph/_app.scss
@@ -4,10 +4,16 @@
 @import './variables';
 
 #ts-daterange-select-container {
-    li {
+    .loading-indicator-container {
         display: inline-block;
-        label {
-            width: 110px;
+    }
+    ul {
+        display: inline-block;
+        li {
+            display: inline-block;
+            label {
+                width: 110px;
+            }
         }
     }
 }
@@ -136,6 +142,14 @@
     }
 }
 
+.loading-indicator-container {
+    i {
+        text-align: center;
+        vertical: middle;
+        width: 100%;
+    }
+}
+
 .watermark {
     position: absolute;
     opacity: .08;
@@ -167,7 +181,6 @@
     button {
         font-size: 1em;
     }
-
     .graph-controls-container {
         display: inline-block;
         @include media($medium-screen) {
diff --git a/wdfn-server/waterdata/templates/macros/components.html b/wdfn-server/waterdata/templates/macros/components.html
index a4d33be14e391ac3f726786a15b15c704c30c4f9..a1cb753367e18d725832fc82c3ba58343fde6552 100644
--- a/wdfn-server/waterdata/templates/macros/components.html
+++ b/wdfn-server/waterdata/templates/macros/components.html
@@ -1,5 +1,6 @@
 {% macro TimeSeriesComponent(site_no) -%}
     <div class="wdfn-component" data-component="hydrograph" data-siteno="{{ site_no }}">
+        <div class="loading-indicator-container"></div>
         <div class="graph-container"></div>
         <div class="select-time-series-container"></div>
         <div class="usa-alert usa-alert-info provisional-data-alert" role="alert" hidden>