diff --git a/.eslintrc b/.eslintrc
index 600faec22baee1caac92d98f78687ce4407001b6..6ec43532e447eee88074ac3a73660ccfc95236ab 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -5,10 +5,7 @@
     "jasmine": true
   },
   "parserOptions": {
-    "ecmaVersion": 6,
-    "ecmaFeatures": {
-      "experimentalObjectRestSpread": true
-    },
+    "ecmaVersion": 2018,
     "sourceType": "module"
   },
   "plugins": [
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6c31e287bb5085160859995bc1d8d821e68875f..a5ad3220e6091ead4a5d29c4a7610787d80b568e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,8 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased](https://github.com/usgs/waterdataui/compare/waterdataui-0.22.0...master)
-### Changed
-- Assets generation and the graph-server now use npm 12.x.x
+### Added
+- Image server now accepts the period parameter which should be a ISO-8601 duration format. 
+However please note that NWIS only accepts periods using xxD.
 
 ## [0.22.0](https://github.com/usgs/waterdataui/compare/waterdataui-0.21.0...waterdataui-0.22.0) - 2019-12-12
 ### Changed
diff --git a/assets/package.json b/assets/package.json
index 8f5ea8e5f396c3818c3facec552cd20839b9ce36..a8164fc1b59909d8736d4c4da06731dbb2cc2cbf 100644
--- a/assets/package.json
+++ b/assets/package.json
@@ -28,7 +28,7 @@
     "watch:js": "mkdir -p dist/scripts && cp node_modules/date-time-format-timezone/build/browserified/date-time-format-timezone-complete-min.js dist/scripts && rollup -c --watch"
   },
   "engines": {
-    "node": "12.13.1"
+    "node": "10.18.0"
   },
   "repository": {
     "type": "git",
diff --git a/assets/src/scripts/components/hydrograph/index.js b/assets/src/scripts/components/hydrograph/index.js
index ccf2b3b764f5c2f21c214b45794dc981e64a3ddf..e2344c94e923e184f47604d80ce361d17630b66a 100644
--- a/assets/src/scripts/components/hydrograph/index.js
+++ b/assets/src/scripts/components/hydrograph/index.js
@@ -8,12 +8,14 @@ import { select } from 'd3-selection';
 import { DateTime } from 'luxon';
 import { createStructuredSelector } from 'reselect';
 
+import { dispatch, link, provide } from '../../lib/redux';
+
 import { addSVGAccessibility } from '../../accessibility';
 import config from '../../config';
-import { dispatch, link, provide } from '../../lib/redux';
-import { getTimeSeriesCollectionIds, isLoadingTS } from '../../selectors/time-series-selector';
+import { isLoadingTS, hasAnyTimeSeries } from '../../selectors/time-series-selector';
 import { Actions } from '../../store';
 import { callIf, mediaQuery } from '../../utils';
+
 import { appendAxes, axesSelector } from './axes';
 import { cursorSlider } from './cursor';
 import { lineSegmentsByParmCdSelector, currentVariableLineSegmentsSelector, MASK_DESC, HASH_ID,
@@ -24,8 +26,7 @@ import { drawSimpleLegend, legendMarkerRowsSelector } from './legend';
 import { drawMethodPicker } from './method-picker';
 import { plotSeriesSelectTable, availableTimeSeriesSelector } from './parameters';
 import { xScaleSelector, yScaleSelector, timeSeriesScalesByParmCdSelector } from './scales';
-import { allTimeSeriesSelector, isVisibleSelector, titleSelector, descriptionSelector,
-    hasTimeSeriesWithPoints } from './time-series';
+import { allTimeSeriesSelector, isVisibleSelector, titleSelector, descriptionSelector } from './time-series';
 import { createTooltipFocus, createTooltipText } from './tooltip';
 
 
@@ -52,6 +53,8 @@ const plotDataLine = function(elem, {visible, lines, tsKey, xScale, yScale}) {
         return;
     }
 
+    const tsKeyClass = `ts-${tsKey}`;
+
     for (let line of lines) {
         if (line.classes.dataMask === null) {
             // If this is a single point line, then represent it as a circle.
@@ -63,6 +66,7 @@ const plotDataLine = function(elem, {visible, lines, tsKey, xScale, yScale}) {
                     .classed('approved', line.classes.approved)
                     .classed('estimated', line.classes.estimated)
                     .classed('not-current-method', !line.classes.currentMethod)
+                    .classed(tsKeyClass, true)
                     .attr('r', CIRCLE_RADIUS_SINGLE_PT)
                     .attr('cx', d => xScale(d.dateTime))
                     .attr('cy', d => yScale(d.value));
@@ -94,7 +98,9 @@ const plotDataLine = function(elem, {visible, lines, tsKey, xScale, yScale}) {
                 .attr('y', yScale(yRangeEnd))
                 .attr('width', rectWidth)
                 .attr('height', Math.abs(yScale(yRangeEnd) - yScale(yRangeStart)))
-                .attr('class', `mask ${maskDisplayName}-mask`);
+                .attr('class', `mask ${maskDisplayName}-mask`)
+                .classed(`ts-${tsKey}`, true);
+
 
             const patternId = HASH_ID[tsKey] ? `url(#${HASH_ID[tsKey]})` : '';
 
@@ -349,7 +355,7 @@ const dateRangeControls = function(elem, siteno) {
         .attr('aria-label', 'Time interval select')
         .call(link(function(container, showControls) {
             container.attr('hidden', showControls ? null : true);
-        }, hasTimeSeriesWithPoints('current', 'P7D')));
+        }, hasAnyTimeSeries));
 
     const customDateContainer = elem.insert('div', ':nth-child(3)')
         .attr('id', 'ts-customdaterange-select-container')
@@ -430,7 +436,7 @@ const dateRangeControls = function(elem, siteno) {
                 customDateValidationContainer.attr('hidden', null);
             } else {
                 customDateValidationContainer.attr('hidden', true);
-                return Actions.getUserRequestedDataForDateRange(
+                return Actions.retrieveUserRequestedDataForDateRange(
                     siteno,
                     userSpecifiedStart,
                     userSpecifiedEnd
@@ -481,33 +487,31 @@ const dateRangeControls = function(elem, siteno) {
     li.select(`#${DATE_RANGE[0].label}`).attr('checked', true);
 };
 
-
-const noDataAlert = function(elem, tsCollectionIds) {
+const dataLoadingAlert = function(elem, message) {
     elem.select('#no-data-message').remove();
-    if (tsCollectionIds && tsCollectionIds.length === 0) {
+    if (message) {
         elem.append('div')
             .attr('id', 'no-data-message')
             .attr('class', 'usa-alert usa-alert-info')
             .append('div')
-                .attr('class', 'usa-alert-body')
-                .append('p')
-                    .attr('class', 'usa-alert-text')
-                    .text('No current time series data available for this site');
+            .attr('class', 'usa-alert-body')
+            .append('p')
+            .attr('class', 'usa-alert-text')
+            .text(message);
     }
 };
 
-export const attachToNode = function (store, node, {siteno, parameter, compare, cursorOffset, interactive = true} = {}) {
+export const attachToNode = function (store, node, {siteno, parameter, compare, period, cursorOffset, showOnlyGraph = false} = {}) {
+    const nodeElem = select(node);
     if (!siteno) {
         select(node).call(drawMessage, 'No data is available.');
         return;
     }
 
+    // Initialize hydrograph with the store and show the loading indicator
     store.dispatch(Actions.resizeUI(window.innerWidth, node.offsetWidth));
-    select(node)
+    nodeElem
         .call(provide(store))
-        .call(link(noDataAlert, getTimeSeriesCollectionIds('current', 'P7D')))
-        .call(callIf(interactive, drawMethodPicker))
-        .call(callIf(interactive, dateRangeControls), siteno)
         .select('.loading-indicator-container')
             .call(link(loadingIndicator, createStructuredSelector({
                 showLoadingIndicator: isLoadingTS('current', 'P7D'),
@@ -524,17 +528,35 @@ export const attachToNode = function (store, node, {siteno, parameter, compare,
         store.dispatch(Actions.setCursorOffset(cursorOffset));
     }
 
-    select(node).select('.graph-container')
-        .call(link(controlDisplay, hasTimeSeriesWithPoints('current', 'P7D')))
+    // Fetch the time series data
+    if (period) {
+        store.dispatch(Actions.retrieveCustomTimePeriodTimeSeries(siteno, '00060', period))
+            .catch((message) => dataLoadingAlert(select(node), message ? message : 'No data returned'));
+    } else {
+        store.dispatch(Actions.retrieveTimeSeries(siteno, parameter ? [parameter] : null))
+            .catch(() => dataLoadingAlert((select(node), 'No current time series data available for this site')));
+    }
+    store.dispatch(Actions.retrieveMedianStatistics(siteno));
+
+    // Set up rendering functions for the graph-container
+    nodeElem.select('.graph-container')
+        .call(link(controlDisplay, hasAnyTimeSeries))
         .call(timeSeriesGraph, siteno)
-        .call(callIf(interactive, cursorSlider))
+        .call(callIf(!showOnlyGraph, cursorSlider))
         .append('div')
             .classed('ts-legend-controls-container', true)
-            .call(timeSeriesLegend)
-            .call(callIf(interactive, drawGraphControls));
+            .call(timeSeriesLegend);
 
-    if (interactive) {
-        select(node).select('.select-time-series-container')
+    // Add UI interactive elements and the provisional data alert.
+    if (!showOnlyGraph) {
+        nodeElem
+            .call(drawMethodPicker)
+            .call(dateRangeControls, siteno);
+
+        nodeElem.select('.ts-legend-controls-container')
+            .call(drawGraphControls);
+
+        nodeElem.select('.select-time-series-container')
             .call(link(plotSeriesSelectTable, createStructuredSelector({
                 siteno: () => siteno,
                 availableTimeSeries: availableTimeSeriesSelector,
@@ -542,7 +564,7 @@ export const attachToNode = function (store, node, {siteno, parameter, compare,
                 timeSeriesScalesByParmCd: timeSeriesScalesByParmCdSelector('current', 'P7D', SPARK_LINE_DIM),
                 layout: layoutSelector
             })));
-        select(node).select('.provisional-data-alert')
+        nodeElem.select('.provisional-data-alert')
             .call(link(function(elem, allTimeSeries) {
                 elem.attr('hidden', Object.keys(allTimeSeries).length ? null : true);
             }, allTimeSeriesSelector));
@@ -551,6 +573,4 @@ export const attachToNode = function (store, node, {siteno, parameter, compare,
     window.onresize = function() {
         store.dispatch(Actions.resizeUI(window.innerWidth, node.offsetWidth));
     };
-    store.dispatch(Actions.retrieveTimeSeries(siteno, parameter ? [parameter] : null));
-    store.dispatch(Actions.retrieveMedianStatistics(siteno));
 };
diff --git a/assets/src/scripts/components/hydrograph/index.spec.js b/assets/src/scripts/components/hydrograph/index.spec.js
index da5e8a9d913e9325531eca9b5bd7f7278b4a4e70..a191478b1f2cffeaa2d3c9e79e6747add7d65c03 100644
--- a/assets/src/scripts/components/hydrograph/index.spec.js
+++ b/assets/src/scripts/components/hydrograph/index.spec.js
@@ -163,9 +163,12 @@ describe('Hydrograph charting module', () => {
         component.append('div').attr('class', 'provisional-data-alert');
 
         graphNode = document.getElementById('hydrograph');
+
+        jasmine.Ajax.install();
     });
 
     afterEach(() => {
+        jasmine.Ajax.uninstall();
         select('#hydrograph').remove();
     });
 
@@ -465,7 +468,7 @@ describe('Hydrograph charting module', () => {
         });
 
         it('Expects data to be retrieved if both custom start and end dates are provided', () => {
-            spyOn(Actions, 'getUserRequestedDataForDateRange');
+            spyOn(Actions, 'retrieveUserRequestedDataForDateRange');
 
             select(graphNode).select('#custom-start-date').property('value', '2063-04-03');
             select(graphNode).select('#custom-end-date').property('value', '2063-04-05');
@@ -475,7 +478,7 @@ describe('Hydrograph charting module', () => {
             let customDateAlertDiv = select(graphNode).select('#custom-date-alert-container');
             expect(customDateAlertDiv.attr('hidden')).toBe('true');
 
-            expect(Actions.getUserRequestedDataForDateRange).toHaveBeenCalledWith(
+            expect(Actions.retrieveUserRequestedDataForDateRange).toHaveBeenCalledWith(
                 '12345678', '2063-04-03', '2063-04-05'
             );
         });
@@ -493,16 +496,24 @@ describe('Hydrograph charting module', () => {
                 }
             };
             let store = configureStore(newTestState);
-            spyOn(store, 'dispatch');
+            spyOn(store, 'dispatch').and.callThrough();
             attachToNode(store, graphNode, {siteno: '12345678'});
 
             expect(select(graphNode).select('.loading-indicator-container').select('.loading-indicator').size()).toBe(1);
         });
 
         it('Expects the graph loading indicator to not be visible if the current 7 day data is not being loaded', () => {
-            let store = configureStore(TEST_STATE);
-            spyOn(store, 'dispatch');
+            const newTestState = {
+                ...TEST_STATE,
+                timeSeriesState: {
+                    ...TEST_STATE.timeSeriesState,
+                    currentDateRange: 'P7D'
+                }
+            };
+            let store = configureStore(newTestState);
+            spyOn(store, 'dispatch').and.callThrough();
             attachToNode(store, graphNode, {siteno: '12345678'});
+            store.dispatch(Actions.removeTimeSeriesLoading(['current:P7D']));
 
             expect(select(graphNode).select('.loading-indicator-container').select('.loading-indicator').size()).toBe(0);
         });
@@ -543,23 +554,5 @@ describe('Hydrograph charting module', () => {
 
             expect(select(graphNode).select('#no-data-message').size()).toBe(0);
         });
-
-        it('Expects the no data alert to be shown if there is no data', () => {
-            let newTestState = {
-                ...TEST_STATE,
-                series: {
-                    ...TEST_STATE.series,
-                    requests: {
-                        'current:P7D': {
-                            timeSeriesCollections: []
-                        }
-                    }
-                }
-            };
-            let store = configureStore(newTestState);
-            attachToNode(store, graphNode, {siteno: '12345678'});
-
-            expect(select(graphNode).select('#no-data-message').size()).toBe(1);
-        });
     });
 });
diff --git a/assets/src/scripts/components/hydrograph/time-series.js b/assets/src/scripts/components/hydrograph/time-series.js
index 014eff34fd21da410c686fd25885a242382e4d6a..3eb3a8ad2922df35119b420a12c0c9b392e6b524 100644
--- a/assets/src/scripts/components/hydrograph/time-series.js
+++ b/assets/src/scripts/components/hydrograph/time-series.js
@@ -4,8 +4,10 @@ import _includes from 'lodash/includes';
 import uniq from 'lodash/uniq';
 import { createSelector } from 'reselect';
 
-import { getRequestTimeRange, getCurrentVariable, getTsRequestKey, getIanaTimeZone, getCurrentParmCd, getCurrentMethodID,
-    getMethods } from '../../selectors/time-series-selector';
+import {
+    getRequestTimeRange, getCurrentVariable, getTsRequestKey, getIanaTimeZone, getCurrentParmCd, getCurrentMethodID,
+    getMethods
+} from '../../selectors/time-series-selector';
 
 
 export const TEMPERATURE_PARAMETERS = {
@@ -154,6 +156,7 @@ export const hasTimeSeriesWithPoints = memoize((tsKey, period) => createSelector
         return seriesWithPoints.length > 0;
 }));
 
+
 /**
  * Factory function creates a function that:
  * Returns the current show state of a time series.
diff --git a/assets/src/scripts/models.js b/assets/src/scripts/models.js
index 4de2ef38cf0b312d5edb5567d9532d0267881a6d..fcae28f8186b75dae268d8cca772003d1e86bf9e 100644
--- a/assets/src/scripts/models.js
+++ b/assets/src/scripts/models.js
@@ -31,13 +31,16 @@ function tsServiceRoot(date) {
  * @param  {Array}    params Optional array of parameter codes
  * @param {Date} startDate
  * @param {Date} endData
+ * @param {String} period
  * @return {Promise} resolves to an array of time series model object, rejects to an error
  */
-export const getTimeSeries = function ({sites, params=null, startDate=null, endDate=null}) {
+export const getTimeSeries = function ({sites, params=null, startDate=null, endDate=null, period=null}) {
     let timeParams;
     let serviceRoot;
+
     if (!startDate && !endDate) {
-        timeParams = 'period=P7D';
+        const timePeriod = period || 'P7D';
+        timeParams = `period=${timePeriod}`;
         serviceRoot = SERVICE_ROOT;
     } else {
         let startString = startDate ? isoFormatTime(startDate) : '';
diff --git a/assets/src/scripts/models.spec.js b/assets/src/scripts/models.spec.js
index 56b249013036836b8adff6d55c8056e190e17b33..6ba03b069b992a4396f00121a642c1a9eddceced 100644
--- a/assets/src/scripts/models.spec.js
+++ b/assets/src/scripts/models.spec.js
@@ -39,7 +39,7 @@ describe('Models module', () => {
             expect(request.url).toContain('parameterCd=' + paramCode + ',00080');
         });
 
-        it('Get url includes has the default time period if startDate and endDate are null', () => {
+        it('Get url includes has the default time period if startDate, endDate and period are null', () => {
             getTimeSeries({sites: [siteID], params: [paramCode]});
             const request = jasmine.Ajax.requests.mostRecent();
             expect(request.url).toContain('period=P7D');
@@ -47,7 +47,7 @@ describe('Models module', () => {
             expect(request.url).not.toContain('endDT');
         });
 
-        it('Get url includes startDT and endDT when startDate and endDate are non-null', () =>{
+        it('Get url includes startDT and endDT when startDate and endDate are non-null', () => {
             const startDate = new Date('2018-01-02T15:00:00.000-06:00');
             const endDate = new Date('2018-01-02T16:45:00.000-06:00');
             getTimeSeries({sites: [siteID], params: [paramCode], startDate: startDate, endDate: endDate});
@@ -57,6 +57,18 @@ describe('Models module', () => {
             expect(request.url).toContain('endDT=2018-01-02T22:45');
         });
 
+        it('Get url includes period when available and startDT and endDT are null', () => {
+            getTimeSeries({
+                sites: [siteID],
+                params: [paramCode],
+                period: 'P14D'
+            });
+            const request = jasmine.Ajax.requests.mostRecent();
+            expect(request.url).toContain('period=P14D');
+            expect(request.url).not.toContain('startDT');
+            expect(request.url).not.toContain('endDT');
+        });
+
         it('Uses current data service root if data requested is less than 120 days old', () => {
             getTimeSeries({sites: [siteID], params: [paramCode]});
             let request = jasmine.Ajax.requests.mostRecent();
@@ -155,169 +167,6 @@ describe('Models module', () => {
     });
 });
 
-const MOCK_LAST_YEAR_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&parameterCd=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"
-      }, {
-        "value" : "302",
-        "qualifiers" : [ "P" ],
-        "dateTime" : "2017-01-02T15:30:00.000-06:00"
-      }, {
-        "value" : "301",
-        "qualifiers" : [ "P" ],
-        "dateTime" : "2017-01-02T15:45:00.000-06:00"
-      }, {
-        "value" : "300",
-        "qualifiers" : [ "P" ],
-        "dateTime" : "2017-01-02T16:00:00.000-06:00"
-      }, {
-        "value" : "302",
-        "qualifiers" : [ "P" ],
-        "dateTime" : "2017-01-02T16:15:00.000-06:00"
-      }, {
-        "value" : "300",
-        "qualifiers" : [ "P" ],
-        "dateTime" : "2017-01-02T16:30:00.000-06:00"
-      }, {
-        "value" : "300",
-        "qualifiers" : [ "P" ],
-        "dateTime" : "2017-01-02T16:45: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
-}`
-;
-
 const MOCK_DATA = `
 {"name" : "ns1:timeSeriesResponseType",
 "declaredType" : "org.cuahsi.waterml.TimeSeriesResponseType",
@@ -3127,16 +2976,4 @@ const MOCK_DATA = `
 "globalScope" : true,
 "typeSubstituted" : false
 }
-`;
-
-const MOCK_MEDIAN_DATA = [
-    {agency_cd: 'USGS', site_no: '05370000', parameter_cd: '00060', ts_id: '153885', loc_web_ds: '', month_nu: '1', day_nu: '1', begin_yr: '1969', end_yr: '2017', count_nu: '49', p50_va: '16'},
-    {agency_cd: 'USGS', site_no: '05370000', parameter_cd: '00060', ts_id: '153885', loc_web_ds: '', month_nu: '1', day_nu: '13', begin_yr: '1969', end_yr: '2017', count_nu: '49', p50_va: '15'},
-    {agency_cd: 'USGS', site_no: '05370000', parameter_cd: '00060', ts_id: '153885', loc_web_ds: '', month_nu: '8', day_nu: '5', begin_yr: '1969', end_yr: '2017', count_nu: '49', p50_va: '15'},
-    {agency_cd: 'USGS', site_no: '05370000', parameter_cd: '00060', ts_id: '153885', loc_web_ds: '', month_nu: '2', day_nu: '29', begin_yr: '1969', end_yr: '2017', count_nu: '49', p50_va: '13'}
-];
-const MOCK_MEDIAN_VARIABLES = {
-    '00060': {
-        oid: 'varID'
-    }
-};
+`;
\ No newline at end of file
diff --git a/assets/src/scripts/selectors/time-series-selector.js b/assets/src/scripts/selectors/time-series-selector.js
index f53351a698e2fa72be3d3f98983727ec2d405bc0..3d140531de630d56979e27f61a3112994d264cc3 100644
--- a/assets/src/scripts/selectors/time-series-selector.js
+++ b/assets/src/scripts/selectors/time-series-selector.js
@@ -26,9 +26,9 @@ export const getIanaTimeZone = state => state.series.ianaTimeZone ? state.series
 
 export const getNwisTimeZone = state => state.series.timeZones || {};
 
-export const getRequestedTimeRange = state => state.timeSeriesState.requestedTimeRange;
-
+export const getCustomTimeRange = state => state.timeSeriesState.customTimeRange;
 
+export const hasAnyTimeSeries = state => state.series && state.series.timeSeries && state.series.timeSeries != {};
 /*
  * Selectors the return derived data from the state
  */
diff --git a/assets/src/scripts/store/index.js b/assets/src/scripts/store/index.js
index 377782011626cf403b399938100013e7dfc233b9..f8143ea781ac3eceb0fc034713976d5bd7073f39 100644
--- a/assets/src/scripts/store/index.js
+++ b/assets/src/scripts/store/index.js
@@ -1,16 +1,18 @@
 
+import find from 'lodash/find';
 import findKey from 'lodash/findKey';
 import last from 'lodash/last';
 import { DateTime } from 'luxon';
 import { applyMiddleware, createStore, combineReducers, compose } from 'redux';
 import { default as thunk } from 'redux-thunk';
+
 import { getPreviousYearTimeSeries, getTimeSeries, sortedParameters, queryWeatherService } from '../models';
 import { calcStartTime } from '../utils';
 import { normalize } from '../schema';
 import { fetchFloodFeatures, fetchFloodExtent } from '../flood-data';
 import { fetchSiteStatistics } from '../statistics-data';
 import { getCurrentParmCd, getCurrentDateRange, hasTimeSeries, getTsRequestKey, getRequestTimeRange,
-    getRequestedTimeRange, getIanaTimeZone, getTimeSeriesCollectionIds } from '../selectors/time-series-selector';
+    getCustomTimeRange, getIanaTimeZone } from '../selectors/time-series-selector';
 import { floodDataReducer as floodData } from './flood-data-reducer';
 import { floodStateReducer as floodState } from './flood-state-reducer';
 import { nldiDataReducer as nldiData } from './nldi-data-reducer';
@@ -81,7 +83,6 @@ export const Actions = {
                     const notes = collection.queryInfo[requestKey].notes;
                     const endTime = notes.requestDT;
                     const startTime = calcStartTime('P7D', endTime, 'local');
-                    dispatch(Actions.setCustomDateRange(startTime, endTime));
                     if (latitude !== null && longitude !== null) {
                         dispatch(Actions.retrieveLocationTimeZone(latitude, longitude));
                     }
@@ -134,24 +135,46 @@ export const Actions = {
             );
         };
     },
-    retrieveCustomTimeSeries(site) {
+
+    retrieveCustomTimePeriodTimeSeries(site, parameterCd, period) {
         return function(dispatch, getState) {
             const state = getState();
-            const parmCd = getCurrentParmCd(state);
-            const requestedTimeRange = getRequestedTimeRange(state);
+            const parmCd = parameterCd;
             const requestKey = getTsRequestKey('current', 'custom', parmCd)(state);
-            const currentTsIds = getTimeSeriesCollectionIds('current', 'custom', parmCd)(state) || [];
-            if (currentTsIds.length > 0) {
-                dispatch(Actions.resetTimeSeries(requestKey));
-            }
             dispatch(Actions.setCurrentDateRange('custom'));
             dispatch(Actions.addTimeSeriesLoading([requestKey]));
+            return getTimeSeries({sites: [site], params: [parmCd], period: period}).then(
+                series => {
+                    const collection = normalize(series, requestKey);
+                    const variables = Object.values(collection.variables);
+                    const variableToDraw = find(variables, v =>  v.variableCode.value === parameterCd);
+                    dispatch(Actions.setCurrentVariable(variableToDraw.variableCode.variableID));
+                    dispatch(Actions.addSeriesCollection(requestKey, collection));
+                    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]));
+                }
+            );
+        };
+    },
+
+    retrieveCustomTimeSeries(site, startTime, endTime) {
+        return function(dispatch, getState) {
+            const state = getState();
+            const parmCd = getCurrentParmCd(state);
+            const requestKey = getTsRequestKey('current', 'custom', parmCd)(state);
+
+            dispatch(Actions.setCustomDateRange(startTime, endTime));
+            dispatch(Actions.addTimeSeriesLoading([requestKey]));
             dispatch(Actions.toggleTimeSeries('median', false));
             return getTimeSeries({
                 sites: [site],
                 params: [parmCd],
-                startDate: requestedTimeRange.startDT,
-                endDate: requestedTimeRange.endDT
+                startDate: startTime,
+                endDate: endTime
             }).then(
                 series => {
                     const collection = normalize(series, requestKey);
@@ -159,7 +182,7 @@ export const Actions = {
                     dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                 },
                 () => {
-                    console.log(`Unable to fetch data for between ${requestedTimeRange.startDT} and ${requestedTimeRange.endDT} and parameter code ${parmCd}`);
+                    console.log(`Unable to fetch data for between ${startTime} and ${endTime} and parameter code ${parmCd}`);
                     dispatch(Actions.addSeriesCollection(requestKey, {}));
                     dispatch(Actions.removeTimeSeriesLoading([requestKey]));
                 }
@@ -187,7 +210,6 @@ export const Actions = {
                         dispatch(Actions.retrieveCompareTimeSeries(site, period, startTime, endTime));
                         dispatch(Actions.addSeriesCollection(requestKey, collection));
                         dispatch(Actions.removeTimeSeriesLoading([requestKey]));
-                        dispatch(Actions.setCustomDateRange(startTime, endTime));
                         dispatch(Actions.toggleTimeSeries('median', true));
                     },
                     () => {
@@ -230,9 +252,12 @@ export const Actions = {
     updateCurrentVariable(siteno, variableID) {
         return function(dispatch, getState) {
             dispatch(Actions.setCurrentVariable(variableID));
-            const currentDateRange = getCurrentDateRange(getState());
+            const state = getState();
+            const currentDateRange = getCurrentDateRange(state);
             if (currentDateRange === 'custom') {
-                dispatch(Actions.retrieveCustomTimeSeries(siteno));
+                const timeRange = getCustomTimeRange(state);
+                dispatch(
+                    Actions.retrieveCustomTimeSeries(siteno, timeRange.startDT, timeRange.endDT));
             } else {
                 dispatch(Actions.retrieveExtendedTimeSeries(siteno, currentDateRange));
             }
@@ -367,14 +392,13 @@ export const Actions = {
             endTime
         };
     },
-    getUserRequestedDataForDateRange(siteno, startTimeStr, endTimeStr) {
+    retrieveUserRequestedDataForDateRange(siteno, startTimeStr, endTimeStr) {
         return function(dispatch, getState) {
             const state = getState();
             const locationIanaTimeZone = getIanaTimeZone(state);
             const startTime = new DateTime.fromISO(startTimeStr,{zone: locationIanaTimeZone}).toMillis();
             const endTime = new DateTime.fromISO(endTimeStr, {zone: locationIanaTimeZone}).toMillis();
-            dispatch(Actions.setCustomDateRange(startTime, endTime));
-            dispatch(Actions.retrieveCustomTimeSeries(siteno));
+            dispatch(Actions.retrieveCustomTimeSeries(siteno, startTime, endTime));
         };
     },
     setGageHeightFromStageIndex(index) {
@@ -435,7 +459,7 @@ export const configureStore = function (initialState) {
                 median: false
             },
             currentDateRange: 'P7D',
-            requestedTimeRange: null,
+            customTimeRange: null,
             currentVariableID: null,
             cursorOffset: null,
             audiblePlayId: null,
diff --git a/assets/src/scripts/store/index.spec.js b/assets/src/scripts/store/index.spec.js
index 65fe00954a290605cd689ec81528001d494d3d27..96323f7d7757283f1aef7470ba0e9c6eb02d3588 100644
--- a/assets/src/scripts/store/index.spec.js
+++ b/assets/src/scripts/store/index.spec.js
@@ -55,7 +55,7 @@ describe('Redux store', () => {
             timeSeriesState: {
                 currentVariableID: '45807042',
                 currentDateRange: 'P7D',
-                requestedTimeRange: {startDT: 1488348000000, endDT: 1490936400000}
+                customTimeRange: {startDT: 1488348000000, endDT: 1490936400000}
             }
         };
 
@@ -120,11 +120,12 @@ describe('Redux store', () => {
                 jasmine.Ajax.requests.mostRecent().respondWith({
                     status: 500
                 });
-                p.then(() => {
-                    expect(Actions.setLocationIanaTimeZone.calls.count()).toBe(1);
-                    expect(Actions.setLocationIanaTimeZone).toHaveBeenCalledWith(null);
-                    done();
-                });
+                p.then(
+                    () => {
+                        expect(Actions.setLocationIanaTimeZone.calls.count()).toBe(1);
+                        expect(Actions.setLocationIanaTimeZone).toHaveBeenCalledWith(null);
+                        done();
+                    });
             });
         });
 
@@ -167,11 +168,10 @@ describe('Redux store', () => {
                 spyOn(Actions, 'retrieveCompareTimeSeries');
                 spyOn(Actions, 'toggleTimeSeries');
                 spyOn(Actions, 'setCurrentVariable');
-                spyOn(Actions, 'setCustomDateRange');
                 let p = Actions.retrieveTimeSeries(SITE_NO)(mockDispatch, mockGetState);
 
                 p.then(() => {
-                    expect(mockDispatch.calls.count()).toBe(9);
+                    expect(mockDispatch.calls.count()).toBe(8);
                     expect(Actions.addSeriesCollection.calls.count()).toBe(1);
                     expect(Actions.addSeriesCollection.calls.argsFor(0)[0]).toBe('current');
                     expect(Actions.retrieveLocationTimeZone.calls.count()).toBe(1);
@@ -184,7 +184,6 @@ describe('Redux store', () => {
                     expect(Actions.toggleTimeSeries.calls.argsFor(0)).toEqual(['current', true]);
                     expect(Actions.setCurrentVariable.calls.count()).toBe(1);
                     expect(Actions.setCurrentVariable.calls.argsFor(0)).toEqual(['45807197']);
-                    expect(Actions.setCustomDateRange.calls.count()).toBe(1);
 
                     done();
                 });
@@ -403,6 +402,72 @@ describe('Redux store', () => {
             });
         });
 
+        describe('retrieveCustomTimePeriodTimeSeries', () => {
+            let mockDispatch;
+            let mockGetState;
+
+            beforeEach(() => {
+                jasmine.Ajax.install();
+
+                mockDispatch = jasmine.createSpy('mockDispatch');
+                mockGetState = jasmine.createSpy('mockGetState').and.returnValue(TEST_STATE);
+                spyOn(Actions, 'setCurrentDateRange');
+                spyOn(Actions, 'addTimeSeriesLoading');
+                spyOn(Actions, 'setCurrentVariable');
+                spyOn(Actions, 'addSeriesCollection');
+                spyOn(Actions, 'removeTimeSeriesLoading');
+            });
+
+            afterEach(() => {
+                jasmine.Ajax.uninstall();
+            });
+
+            it('Should dispatch an action to set the current date range and set the time series loading key', () => {
+                Actions.retrieveCustomTimePeriodTimeSeries('12345678', '00060', 'P10D')(mockDispatch, mockGetState);
+                expect(Actions.addTimeSeriesLoading).toHaveBeenCalledWith(['current:custom:00060']);
+                expect(Actions.setCurrentDateRange).toHaveBeenCalledWith('custom');
+            });
+
+            it('Should make the service call with the correct parameters', () => {
+                Actions.retrieveCustomTimePeriodTimeSeries('12345678', '00060', 'P10D')(mockDispatch, mockGetState);
+                let request = jasmine.Ajax.requests.mostRecent();
+                expect(request.url).toContain('sites=1234567');
+                expect(request.url).toContain('parameterCd=00060');
+                expect(request.url).toContain('period=P10D');
+            });
+
+            it('Should set the current variable and add the time series open successful response', (done) => {
+                let p = Actions.retrieveCustomTimePeriodTimeSeries('12345678', '00060', 'P10D')(mockDispatch, mockGetState);
+                let request = jasmine.Ajax.requests.mostRecent();
+                request.respondWith({
+                    responseText: MOCK_DATA,
+                    status: 200
+                });
+                p.then(() => {
+                    expect(Actions.setCurrentVariable).toHaveBeenCalledWith(45807197);
+                    expect(Actions.addSeriesCollection).toHaveBeenCalled();
+                    expect(Actions.addSeriesCollection.calls.argsFor(0)[0]).toEqual('current:custom:00060');
+                    expect(Actions.removeTimeSeriesLoading).toHaveBeenCalledWith(['current:custom:00060']);
+                    done();
+                });
+            });
+
+            it('Should clear the data for and remove the time series loader for bad data', (done) => {
+                let p = Actions.retrieveCustomTimePeriodTimeSeries('12345678', '00060', 'P10D')(mockDispatch, mockGetState);
+                let request = jasmine.Ajax.requests.mostRecent();
+                request.respondWith({
+                    responseText: 'Bad data',
+                    status: 500
+                });
+                p.then(() => {
+                    expect(Actions.setCurrentVariable).not.toHaveBeenCalled();
+                    expect(Actions.addSeriesCollection).toHaveBeenCalledWith('current:custom:00060', {});
+                    expect(Actions.removeTimeSeriesLoading).toHaveBeenCalledWith(['current:custom:00060']);
+                    done();
+                });
+            });
+        });
+
         describe('retrieveCustomTimeSeries with good data', () => {
             let mockDispatch;
             let mockGetState;
@@ -422,16 +487,11 @@ describe('Redux store', () => {
             });
 
             it('Should dispatch an action to set the current date range', () => {
-                Actions.retrieveCustomTimeSeries('9876543')(mockDispatch, mockGetState);
+                Actions.retrieveCustomTimeSeries('9876543', 1488348000000, 1490936400000)(mockDispatch, mockGetState);
                 request = jasmine.Ajax.requests.mostRecent();
                 request.respondWith({
-                    responseText: MOCK_DATA,
                     status: 200
                 });
-                expect(mockDispatch).toHaveBeenCalledWith({
-                    type: 'SET_CURRENT_DATE_RANGE',
-                    period: 'custom'
-                });
                 expect(Actions.addTimeSeriesLoading).toHaveBeenCalledWith(['current:custom:00060']);
             });
 
@@ -439,10 +499,10 @@ describe('Redux store', () => {
                 mockGetState.and.returnValue(Object.assign({}, TEST_STATE, {
                     timeSeriesState: Object.assign({}, TEST_STATE.timeSeriesState, {
                         currentDateRange: 'custom',
-                        requestedTimeRange: {startDT: 2942805600000, endDT: 2942978400000}
+                        currentTimeRange: {startDT: 2942805600000, endDT: 2942978400000}
                     })
                 }));
-                Actions.retrieveCustomTimeSeries('490129388')(mockDispatch, mockGetState);
+                Actions.retrieveCustomTimeSeries('490129388', 2942805600000, 2942978400000)(mockDispatch, mockGetState);
                 request = jasmine.Ajax.requests.mostRecent();
                 request.respondWith({
                     responseText: MOCK_DATA,
@@ -455,12 +515,12 @@ describe('Redux store', () => {
                 expect(request.url).toContain('endDT=2063-04-05');
             });
 
-            it('Should dispatch add series collection and hide median series', (done) => {
+            it('Should dispatch add series collection and hide median series after good response', (done) => {
                 mockGetState.and.returnValue(TEST_STATE);
                 spyOn(Actions, 'addSeriesCollection');
                 spyOn(Actions, 'retrieveCompareTimeSeries');
                 spyOn(Actions, 'toggleTimeSeries');
-                let p = Actions.retrieveCustomTimeSeries('490129388')(mockDispatch, mockGetState);
+                let p = Actions.retrieveCustomTimeSeries('490129388', 1488348000000, 1490936400000)(mockDispatch, mockGetState);
                 request = jasmine.Ajax.requests.mostRecent();
                 request.respondWith({
                     responseText: MOCK_DATA,
@@ -476,28 +536,6 @@ describe('Redux store', () => {
                     done();
                 });
             });
-
-            it('Should reset the time series if it already exists', (done) => {
-                mockGetState.and.returnValue(Object.assign({}, TEST_STATE, {
-                    series: Object.assign({}, TEST_STATE.series, {
-                        requests: {'current:custom:00060': {
-                                timeSeriesCollections: [7, 8]
-                            }}
-                    })
-                }));
-                spyOn(Actions, 'resetTimeSeries');
-                let p = Actions.retrieveCustomTimeSeries('490129388')(mockDispatch, mockGetState);
-                request = jasmine.Ajax.requests.mostRecent();
-                request.respondWith({
-                    responseText: MOCK_DATA,
-                    status: 200
-                });
-                p.then(() => {
-                    expect(mockDispatch.calls.count()).toBe(6);
-                    expect(Actions.resetTimeSeries).toHaveBeenCalled();
-                    done();
-                });
-            });
         });
 
         describe('retrieveCustomTimeSeries with bad data', () => {
@@ -513,7 +551,7 @@ describe('Redux store', () => {
                 mockGetState.and.returnValue(Object.assign({}, TEST_STATE, {
                     timeSeriesState: Object.assign({}, TEST_STATE.timeSeriesState, {
                         currentDateRange: 'custom',
-                        requestedTimeRange: {startDT: 2942805600000, endDT: 2942978400000}
+                        currentTimeRange: {startDT: 2942805600000, endDT: 2942978400000}
                     })
                 }));
 
@@ -526,8 +564,9 @@ describe('Redux store', () => {
             });
 
             it('Should add a series with an empty collection when it is bad data', (done) => {
-                let p = Actions.retrieveCustomTimeSeries('9876543')(mockDispatch, mockGetState);
-                jasmine.Ajax.requests.mostRecent().respondWith({
+                let p = Actions.retrieveCustomTimeSeries('9876543', 1488348000000, 1490936400000)(mockDispatch, mockGetState);
+                let request = jasmine.Ajax.requests.mostRecent();
+                request.respondWith({
                     status: 500
                 });
                 expect(Actions.addTimeSeriesLoading).toHaveBeenCalledWith(['current:custom:00060']);
@@ -604,13 +643,12 @@ describe('Redux store', () => {
                     status: 200
                 });
                 p.then(() => {
-                    expect(mockDispatch.calls.count()).toBe(7);
+                    expect(mockDispatch.calls.count()).toBe(6);
                     expect(Actions.addSeriesCollection).toHaveBeenCalled();
                     expect(Actions.addSeriesCollection.calls.argsFor(0)[0]).toEqual('current:P30D:00060');
                     expect(Actions.retrieveCompareTimeSeries).toHaveBeenCalled();
                     expect(Actions.retrieveCompareTimeSeries.calls.argsFor(0)[1]).toEqual('P30D');
                     expect(Actions.removeTimeSeriesLoading).toHaveBeenCalledWith(['current:P30D:00060']);
-                    expect(Actions.setCustomDateRange).toHaveBeenCalled();
                     expect(Actions.toggleTimeSeries).toHaveBeenCalledWith('median', true);
                     done();
                 });
@@ -900,6 +938,35 @@ describe('Redux store', () => {
                 expect(Actions.timeSeriesPlayStop).toHaveBeenCalled();
             });
         });
+
+        describe('retrieveUserRequestedDataForDateRange', () => {
+            let mockDispatch;
+            let mockGetState;
+
+            beforeEach(() => {
+                mockDispatch = jasmine.createSpy('mockDispatch');
+                mockGetState = jasmine.createSpy('mockGetState').and.returnValue({
+                    series: {
+                        ianaTimeZone: 'America/Chicago'
+                    }
+                });
+
+                spyOn(Actions, 'retrieveCustomTimeSeries');
+                jasmine.Ajax.install();
+            });
+
+            afterEach(() => {
+                jasmine.Ajax.uninstall();
+            });
+
+            it('Converts time strings to javascript date/time objects correctly', () => {
+                Actions.retrieveUserRequestedDataForDateRange('12345678', '2010-01-01', '2010-03-01')(mockDispatch, mockGetState);
+                expect(Actions.retrieveCustomTimeSeries).toHaveBeenCalled();
+                expect(Actions.retrieveCustomTimeSeries.calls.argsFor(0)[0]).toEqual('12345678');
+                expect(Actions.retrieveCustomTimeSeries.calls.argsFor(0)[1]).toEqual(1262325600000);
+                expect(Actions.retrieveCustomTimeSeries.calls.argsFor(0)[2]).toEqual(1267423200000);
+            });
+        });
     });
 
     describe('synchronous actions', () => {
diff --git a/assets/src/scripts/store/time-series-state-reducer.js b/assets/src/scripts/store/time-series-state-reducer.js
index 4c383b300fe9d00cbc821765fc942ab81b21134c..f98fda6713ea30d0d5f1836bd0da88679a71d1af 100644
--- a/assets/src/scripts/store/time-series-state-reducer.js
+++ b/assets/src/scripts/store/time-series-state-reducer.js
@@ -69,10 +69,11 @@ const removeLoadingTimeSeries = function(timeSeriesState, action) {
     };
 };
 
-const requestedTimeRange = function(timeSeriesState, action) {
+const setCustomDateRange = function(timeSeriesState, action) {
     return {
         ...timeSeriesState,
-        requestedTimeRange: {startDT: action.startTime, endDT: action.endTime}
+        currentDateRange: 'custom',
+        customTimeRange: {startDT: action.startTime, endDT: action.endTime}
     };
 };
 
@@ -90,7 +91,7 @@ export const timeSeriesStateReducer = function(timeSeriesState={}, action) {
         case 'TIME_SERIES_PLAY_STOP': return timeSeriesPlayStop(timeSeriesState, action);
         case 'TIME_SERIES_LOADING_ADD': return addLoadingTimeSeries(timeSeriesState, action);
         case 'TIME_SERIES_LOADING_REMOVE': return removeLoadingTimeSeries(timeSeriesState, action);
-        case 'SET_CUSTOM_DATE_RANGE': return requestedTimeRange(timeSeriesState, action);
+        case 'SET_CUSTOM_DATE_RANGE': return setCustomDateRange(timeSeriesState, action);
         default: return timeSeriesState;
     }
 };
diff --git a/assets/src/scripts/store/time-series-state-reducer.spec.js b/assets/src/scripts/store/time-series-state-reducer.spec.js
index 8417dd1615223b24e7ca567d355d8ac37b018249..9203f92d04edb9a4bb2db451fe060c1de728eb96 100644
--- a/assets/src/scripts/store/time-series-state-reducer.spec.js
+++ b/assets/src/scripts/store/time-series-state-reducer.spec.js
@@ -88,13 +88,15 @@ describe('time-series-state-reducer', () => {
 
     it('should handle SET_CUSTOM_DATE_RANGE', () => {
         expect(timeSeriesStateReducer({
-            requestedTimeRange: null
+            customTimeRange: null,
+            currentDateRange: 'P7D'
         }, {
             type: 'SET_CUSTOM_DATE_RANGE',
             startTime: 1551420000000,
             endTime: 1552197600000
         })).toEqual({
-            requestedTimeRange: {startDT: 1551420000000, endDT: 1552197600000}
+            customTimeRange: {startDT: 1551420000000, endDT: 1552197600000},
+            currentDateRange: 'custom'
         });
     });
 });
diff --git a/graph-server/package.json b/graph-server/package.json
index 0d210fdb1756e4d181fa31a4b3a3b25534e294aa..80eabb278591f52bc306e5ca1149a1fa57046c5f 100644
--- a/graph-server/package.json
+++ b/graph-server/package.json
@@ -6,10 +6,10 @@
   "scripts": {
     "test": "nyc jasmine",
     "start": "DEBUG=express:* node src/index.js",
-    "watch": "STATIC_ROOT=http://localhost:9000 nodemon src"
+    "watch": "DEBUG=express:* STATIC_ROOT=http://localhost:9000 nodemon src"
   },
   "engines": {
-    "node": "12.13.1"
+    "node": "10.18.0"
   },
   "repository": {
     "type": "git",
diff --git a/graph-server/src/index.js b/graph-server/src/index.js
index cc887a6bc20a369c9e67d1a95a2265d07884b562..64d04b120591126bc13969f052ecfd4cbd18fdac 100644
--- a/graph-server/src/index.js
+++ b/graph-server/src/index.js
@@ -4,7 +4,7 @@ const cache = require('express-cache-headers');
 const { checkSchema, validationResult } = require('express-validator');
 
 const { version } = require('../package.json');
-const renderToRespone = require('./renderer');
+const renderToResponse = require('./renderer');
 
 
 const PORT = process.env.NODE_PORT || 2929;
@@ -57,10 +57,11 @@ app.get(`${PATH_CONTEXT}/monitoring-location/:siteID/`, cache({ttl: CACHE_TIMEOU
         return;
     }
 
-    renderToRespone(res, {
+    renderToResponse(res, {
         siteID: req.params.siteID,
         parameterCode: req.query.parameterCode,
-        compare: req.query.compare
+        compare: req.query.compare,
+        period: req.query.period
     });
 });
 
diff --git a/graph-server/src/renderer/index.js b/graph-server/src/renderer/index.js
index 799bd645302c6bc539b56cdb24c70ffd696f782d..22ea5b9212ea4c146b727b4dfe53e67b0bca3dd7 100644
--- a/graph-server/src/renderer/index.js
+++ b/graph-server/src/renderer/index.js
@@ -5,13 +5,15 @@ const PAST_SERVICE_ROOT = process.env.PAST_SERVICE_ROOT || 'https://nwis.waterse
 const STATIC_ROOT = process.env.STATIC_ROOT || 'https://waterdata.usgs.gov/nwisweb/wsgi/static';
 
 
-const renderToRespone = function (res, {siteID, parameterCode, compare}) {
+const renderToResponse = function (res, {siteID, parameterCode, compare, period}) {
+    console.log(`Using static root ${STATIC_ROOT}`);
     const componentOptions = {
         siteno: siteID,
         parameter: parameterCode,
         compare: compare,
+        period: period,
         cursorOffset: false,
-        interactive: false
+        showOnlyGraph : true
     };
     renderPNG({
         pageURL: 'http://wdfn-graph-server',
@@ -54,4 +56,4 @@ const renderToRespone = function (res, {siteID, parameterCode, compare}) {
 };
 
 
-module.exports = renderToRespone;
+module.exports = renderToResponse;