diff --git a/assets/src/scripts/components/hydrograph/audible.js b/assets/src/scripts/components/hydrograph/audible.js
index 83c236e37a9fe7f17ba40663a636c70a52ea659d..f82351e8cc361f41edc50c2d4badc5cd7afb99a3 100644
--- a/assets/src/scripts/components/hydrograph/audible.js
+++ b/assets/src/scripts/components/hydrograph/audible.js
@@ -3,7 +3,7 @@ import { select } from 'd3-selection';
 import memoize from 'fast-memoize';
 import { createSelector, createStructuredSelector } from 'reselect';
 import { tsCursorPointsSelector } from './cursor';
-import { xScaleSelector, yScaleSelector } from './scales';
+import { xScaleSelector, getYScale } from './scales';
 import { allTimeSeriesSelector } from './time-series';
 import config from '../../config';
 import { dispatch, link } from '../../lib/redux';
@@ -73,7 +73,7 @@ export const updateSound = function ({enabled, points}) {
 const audibleInterfaceOnSelector = state => state.timeSeriesState.audiblePlayId !== null;
 
 const audibleScaleSelector = createSelector(
-    yScaleSelector,
+    getYScale(),
     (yScale) => {
         return scaleLinear()
             .domain(yScale.domain())
diff --git a/assets/src/scripts/components/hydrograph/axes.js b/assets/src/scripts/components/hydrograph/axes.js
index 3b9cf6c77b02a2e9ec2e740f601433dc4ddead82..b089eec367e310296528249f49127f1ecb6dc343 100644
--- a/assets/src/scripts/components/hydrograph/axes.js
+++ b/assets/src/scripts/components/hydrograph/axes.js
@@ -1,14 +1,16 @@
 import { axisBottom, axisLeft, axisRight } from 'd3-axis';
-import { createSelector } from 'reselect';
+import memoize from 'fast-memoize';
 import { DateTime } from 'luxon';
-import { wrap, deltaDays } from '../../utils';
-import { getYTickDetails } from './domain';
-import { layoutSelector } from './layout';
-import { xScaleSelector, yScaleSelector, secondaryYScaleSelector } from './scales';
-import { yLabelSelector, secondaryYLabelSelector, tsTimeZoneSelector, TEMPERATURE_PARAMETERS } from './time-series';
+import { createSelector } from 'reselect';
+
 import config from '../../config';
 import { getCurrentDateRange, getCurrentParmCd } from '../../selectors/time-series-selector';
-import { convertCelsiusToFahrenheit, convertFahrenheitToCelsius, mediaQuery } from '../../utils';
+import { convertCelsiusToFahrenheit, convertFahrenheitToCelsius, mediaQuery, wrap, deltaDays } from '../../utils';
+
+import { getYTickDetails } from './domain';
+import { getLayout } from './layout';
+import { xScaleSelector, getYScale, getSecondaryYScale } from './scales';
+import { yLabelSelector, secondaryYLabelSelector, tsTimeZoneSelector, TEMPERATURE_PARAMETERS } from './time-series';
 
 
 const FORMAT = {
@@ -104,7 +106,7 @@ export const generateDateTicks = function(startDate, endDate, period, ianaTimeZo
  * @param {String} parmCd - parameter code of time series to be shown on the graph.
  * @param {String} period - ISO duration for date range of the time series
  * @param {String} ianaTimeZone - Internet Assigned Numbers Authority designation for a time zone
- * @return {Object}             {xAxis, yAxis} - D3 Axis
+ * @return {Object} {xAxis, yAxis, secondardYaxis} - D3 Axis
  */
 export const createAxes = function({xScale, yScale, secondaryYScale}, yTickSize, parmCd, period, ianaTimeZone) {
     // Create x-axis
@@ -158,11 +160,11 @@ export const createAxes = function({xScale, yScale, secondaryYScale}, yTickSize,
  * Returns data necessary to render the graph axes.
  * @return {Object}
  */
-export const axesSelector = createSelector(
+export const getAxes = memoize(kind => createSelector(
     xScaleSelector('current'),
-    yScaleSelector,
-    secondaryYScaleSelector,
-    layoutSelector,
+    getYScale(kind),
+    getSecondaryYScale(kind),
+    getLayout(kind),
     yLabelSelector,
     tsTimeZoneSelector,
     getCurrentParmCd,
@@ -182,7 +184,7 @@ export const axesSelector = createSelector(
             secondaryYTitle: plotSecondaryYLabel
         };
     }
-);
+));
 
 
 /**
diff --git a/assets/src/scripts/components/hydrograph/cursor.js b/assets/src/scripts/components/hydrograph/cursor.js
index bb360edf8850d9ebf5245e2de9afdca59f7526a7..88c0137ffa8331b202e24fc70744b9e06aadbf7b 100644
--- a/assets/src/scripts/components/hydrograph/cursor.js
+++ b/assets/src/scripts/components/hydrograph/cursor.js
@@ -8,7 +8,7 @@ import { dispatch, link } from '../../lib/redux';
 import {getCurrentMethodID} from '../../selectors/time-series-selector';
 
 import { currentVariablePointsByTsIdSelector } from './drawing-data';
-import { layoutSelector } from './layout';
+import { getMainLayout } from './layout';
 import { xScaleSelector } from './scales';
 import { isVisibleSelector } from './time-series';
 
@@ -146,7 +146,7 @@ export const cursorSlider = function (elem) {
                     input.style('right', layout.margin.right - SLIDER_OFFSET_PX + 'px');
                     input.style('width', maxXScaleRange - (layout.margin.left + layout.margin.right) + SLIDER_OFFSET_PX * 2 + 'px');
                 }, createStructuredSelector( {
-                    layout: layoutSelector,
+                    layout: getMainLayout,
                     xScale: xScaleSelector('current')
                 })));
         });
diff --git a/assets/src/scripts/components/hydrograph/index.js b/assets/src/scripts/components/hydrograph/index.js
index 8954db1380b00ae884c31a34ca73ca4b932ffc18..3137a00613c8aee65d9babd8c4a304d96f829d31 100644
--- a/assets/src/scripts/components/hydrograph/index.js
+++ b/assets/src/scripts/components/hydrograph/index.js
@@ -15,7 +15,7 @@ import { cursorSlider } from './cursor';
 import { drawDateRangeControls } from './date-controls';
 import { lineSegmentsByParmCdSelector } from './drawing-data';
 import { drawGraphControls } from './graph-controls';
-import { SPARK_LINE_DIM, layoutSelector } from './layout';
+import { SPARK_LINE_DIM } from './layout';
 import { drawTimeSeriesLegend } from './legend';
 import { drawLoadingIndicator } from '../loading-indicator';
 import { drawMethodPicker } from './method-picker';
@@ -136,8 +136,7 @@ export const attachToNode = function (store,
                 siteno: () => siteno,
                 availableTimeSeries: availableTimeSeriesSelector,
                 lineSegmentsByParmCd: lineSegmentsByParmCdSelector('current', 'P7D'),
-                timeSeriesScalesByParmCd: timeSeriesScalesByParmCdSelector('current', 'P7D', SPARK_LINE_DIM),
-                layout: layoutSelector
+                timeSeriesScalesByParmCd: timeSeriesScalesByParmCdSelector('current', 'P7D', SPARK_LINE_DIM)
             })));
         nodeElem.select('.provisional-data-alert')
             .call(link(function(elem, allTimeSeries) {
diff --git a/assets/src/scripts/components/hydrograph/layout.js b/assets/src/scripts/components/hydrograph/layout.js
index b42b820fc32482d7e24b5e57ff0c25ea9b726043..28536ece57644b91dd67ff905fed645a7ccca4a3 100644
--- a/assets/src/scripts/components/hydrograph/layout.js
+++ b/assets/src/scripts/components/hydrograph/layout.js
@@ -1,5 +1,7 @@
 // Define constants for the time series graph's aspect ratio and margins as well as a
 // selector function which will return the width/height to use.
+
+import memoize from 'fast-memoize';
 import { createSelector } from 'reselect';
 
 import config from '../../config';
@@ -25,6 +27,9 @@ const MARGIN_SMALL_DEVICE = {
 export const CIRCLE_RADIUS = 4;
 export const CIRCLE_RADIUS_SINGLE_PT = 1;
 
+const BRUSH_ZOOM_HEIGHT = 40;
+
+
 export const SPARK_LINE_DIM = {
     width: 60,
     height: 30
@@ -35,17 +40,18 @@ export const SPARK_LINE_DIM = {
  * @param {Object} state - Redux store
  * @return {Object} containing width and height properties.
  */
-export const layoutSelector = createSelector(
+export const getLayout = memoize(kind => createSelector(
     (state) => state.ui.width,
     (state) => state.ui.windowWidth,
     tickSelector,
     (width, windowWidth, tickDetails) => {
+        const height = kind === 'ZOOM' ? BRUSH_ZOOM_HEIGHT : width * ASPECT_RATIO;
         const margin = mediaQuery(config.USWDS_SITE_MAX_WIDTH) ? MARGIN : MARGIN_SMALL_DEVICE;
         const tickLengths = tickDetails.tickValues.map(v => tickDetails.tickFormat(v).length);
         const approxLabelLength = Math.max(...tickLengths) * 10;
         return {
             width: width,
-            height: width * ASPECT_RATIO,
+            height: height,
             windowWidth: windowWidth,
             margin: {
                 ...margin,
@@ -54,4 +60,12 @@ export const layoutSelector = createSelector(
             }
         };
     }
-);
+));
+
+export const getMainLayout = getLayout();
+export const getZoomLayout = getLayout('ZOOM');
+
+export const layoutZoomSelector = createSelector(
+    (state) => state.ui.width,
+    (state) => state.ui.windowWidth,
+)
diff --git a/assets/src/scripts/components/hydrograph/legend.js b/assets/src/scripts/components/hydrograph/legend.js
index 3d7db8dc1b9e3d86fc8b1b8215f07ff569c88c4d..4e56dd40d41381bdb7d84b8b3e14cf6dbcf51c33 100644
--- a/assets/src/scripts/components/hydrograph/legend.js
+++ b/assets/src/scripts/components/hydrograph/legend.js
@@ -3,7 +3,7 @@ import { set } from 'd3-collection';
 import memoize from 'fast-memoize';
 import {createSelector, createStructuredSelector} from 'reselect';
 
-import {CIRCLE_RADIUS, layoutSelector} from './layout';
+import {CIRCLE_RADIUS, getMainLayout} from './layout';
 import { defineLineMarker, defineTextOnlyMarker, defineRectangleMarker } from './markers';
 import { currentVariableLineSegmentsSelector, HASH_ID, MASK_DESC } from './drawing-data';
 import config from '../../config';
@@ -228,7 +228,7 @@ export const drawTimeSeriesLegend = function(elem) {
         .classed('hydrograph-container', true)
         .call(link(drawSimpleLegend, createStructuredSelector({
             legendMarkerRows: legendMarkerRowsSelector,
-            layout: layoutSelector
+            layout: getMainLayout
         })));
 };
 
diff --git a/assets/src/scripts/components/hydrograph/scales.js b/assets/src/scripts/components/hydrograph/scales.js
index 6adb101bcbb88ee87d76fb22aa38f3e53348839a..bb7ecd5732d30b6d38981c9e4614358f55504699 100644
--- a/assets/src/scripts/components/hydrograph/scales.js
+++ b/assets/src/scripts/components/hydrograph/scales.js
@@ -2,7 +2,7 @@ import { scaleLinear, scaleSymlog } from 'd3-scale';
 import memoize from 'fast-memoize';
 import { createSelector } from 'reselect';
 import { getYDomain, SYMLOG_PARMS } from './domain';
-import { layoutSelector } from './layout';
+import { getLayout, getMainLayout } from './layout';
 import { timeSeriesSelector, TEMPERATURE_PARAMETERS } from './time-series';
 import { visiblePointsSelector, pointsByTsKeySelector } from './drawing-data';
 import { getVariables, getCurrentParmCd, getRequestTimeRange } from '../../selectors/time-series-selector';
@@ -65,7 +65,7 @@ export const createYScale = function (parmCd, extent, size) {
  * @return {Function}           D3 scale function
  */
 export const xScaleSelector = memoize(tsKey => createSelector(
-    layoutSelector,
+    getMainLayout,
     getRequestTimeRange(tsKey),
     (layout, requestTimeRange) => {
         return createXScale(requestTimeRange, layout.width - layout.margin.right);
@@ -78,18 +78,18 @@ export const xScaleSelector = memoize(tsKey => createSelector(
  * @param  {Object} state   Redux store
  * @return {Function}       D3 scale function
  */
-export const yScaleSelector = createSelector(
-    layoutSelector,
+export const getYScale = memoize(kind => createSelector(
+    getLayout(kind),
     visiblePointsSelector,
     getCurrentParmCd,
     (layout, pointArrays, currentVarParmCd) => {
         const yDomain = getYDomain(pointArrays, currentVarParmCd);
         return createYScale(currentVarParmCd, yDomain, layout.height - (layout.margin.top + layout.margin.bottom));
     }
-);
+));
 
-export const secondaryYScaleSelector = createSelector(
-    layoutSelector,
+export const getSecondaryYScale = memoize(kind => createSelector(
+    getLayout(kind),
     visiblePointsSelector,
     getCurrentParmCd,
     (layout, pointArrays, currentVarParmCd) => {
@@ -106,7 +106,7 @@ export const secondaryYScaleSelector = createSelector(
             currentVarParmCd, convertedYDomain, layout.height - (layout.margin.top + layout.margin.bottom)
         );
     }
-);
+));
 
 
 /**
diff --git a/assets/src/scripts/components/hydrograph/time-series-graph.js b/assets/src/scripts/components/hydrograph/time-series-graph.js
index 1255ee18f7e1f850049736bc297b4910e599a451..eed5677e7c9e212fd603608b918ba1f78b1c118f 100644
--- a/assets/src/scripts/components/hydrograph/time-series-graph.js
+++ b/assets/src/scripts/components/hydrograph/time-series-graph.js
@@ -4,7 +4,7 @@ import { line as d3Line, curveStepAfter } from 'd3-shape';
 import {link} from '../../lib/redux';
 
 import {addSVGAccessibility} from '../../accessibility';
-import {appendAxes, axesSelector} from './axes';
+import {appendAxes, getAxes} from './axes';
 import config from '../../config';
 import {
     currentVariableLineSegmentsSelector,
@@ -12,15 +12,14 @@ import {
     HASH_ID,
     MASK_DESC
 } from './drawing-data';
-import {CIRCLE_RADIUS_SINGLE_PT, layoutSelector} from './layout';
+import {CIRCLE_RADIUS_SINGLE_PT, getMainLayout, getZoomLayout} from './layout';
 import {createStructuredSelector} from 'reselect';
-import {xScaleSelector, yScaleSelector} from './scales';
+import {xScaleSelector, getYScale} from './scales';
 import {descriptionSelector, isVisibleSelector, titleSelector} from './time-series';
 import {getAgencyCode, getMonitoringLocationName} from '../../selectors/time-series-selector';
 import {createTooltipFocus, createTooltipText} from './tooltip';
 import {mediaQuery} from '../../utils';
 
-
 const plotDataLine = function(elem, {visible, lines, tsKey, xScale, yScale}) {
     if (!visible) {
         return;
@@ -229,54 +228,71 @@ const watermark = function (elem) {
             // for Safari browser
             elem.style('-webkit-transform', transform);
 
-        }, layoutSelector));
+        }, getMainLayout));
 };
 
-export const drawTimeSeriesGraph = function(elem, siteNo, showMLName) {
-    elem.append('div')
+export const drawTimeSeriesGraph = function(elem, brushZoomElem, siteNo, showMLName) {
+    const graphDiv = elem.append('div')
         .attr('class', 'hydrograph-container')
         .call(watermark)
         .call(createTitle, siteNo, showMLName)
-        .call(createTooltipText)
-        .append('svg')
-            .attr('xmlns', 'http://www.w3.org/2000/svg')
-            .classed('hydrograph-svg', true)
-            .call(link((elem, layout) => {
+        .call(createTooltipText);
+    graphDiv.append('svg')
+        .attr('xmlns', 'http://www.w3.org/2000/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}`);
+            elem.attr('width', layout.width);
+            elem.attr('height', layout.height);
+        }, getMainLayout))
+        .call(link(addSVGAccessibility, createStructuredSelector({
+            title: titleSelector,
+            description: descriptionSelector,
+            isInteractive: () => true,
+            idPrefix: () => 'hydrograph'
+        })))
+        .call(plotSvgDefs)
+        .call(svg => {
+            svg.append('g')
+                .call(link((elem, layout) => elem.attr('transform', `translate(${layout.margin.left},${layout.margin.top})`), getMainLayout))
+                .call(link(appendAxes, getAxes()))
+                .call(link(plotDataLines, createStructuredSelector({
+                    visible: isVisibleSelector('current'),
+                    tsLinesMap: currentVariableLineSegmentsSelector('current'),
+                    xScale: xScaleSelector('current'),
+                    yScale: getYScale(),
+                    tsKey: () => 'current'
+                })))
+                .call(link(plotDataLines, createStructuredSelector({
+                    visible: isVisibleSelector('compare'),
+                    tsLinesMap: currentVariableLineSegmentsSelector('compare'),
+                    xScale: xScaleSelector('compare'),
+                    yScale: getYScale(),
+                    tsKey: () => 'compare'
+                })))
+                .call(createTooltipFocus)
+                .call(link(plotAllMedianPoints, createStructuredSelector({
+                    visible: isVisibleSelector('median'),
+                    xscale: xScaleSelector('current'),
+                    yscale: getYScale(),
+                    seriesPoints: getCurrentVariableMedianStatPoints
+                })));
+        });
+
+    //Create brush/zoom context
+    graphDiv.append('svg')
+        .attr('xmlns', 'http://www.w3.org/2000/svg')
+        .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}`);
                 elem.attr('width', layout.width);
                 elem.attr('height', layout.height);
-            }, layoutSelector))
-            .call(link(addSVGAccessibility, createStructuredSelector({
-                title: titleSelector,
-                description: descriptionSelector,
-                isInteractive: () => true,
-                idPrefix: () => 'hydrograph'
-            })))
-            .call(plotSvgDefs)
-            .call(svg => {
-                svg.append('g')
-                    .call(link((elem, layout) => elem.attr('transform', `translate(${layout.margin.left},${layout.margin.top})`), layoutSelector))
-                    .call(link(appendAxes, axesSelector))
-                    .call(link(plotDataLines, createStructuredSelector({
-                        visible: isVisibleSelector('current'),
-                        tsLinesMap: currentVariableLineSegmentsSelector('current'),
-                        xScale: xScaleSelector('current'),
-                        yScale: yScaleSelector,
-                        tsKey: () => 'current'
-                    })))
-                    .call(link(plotDataLines, createStructuredSelector({
-                        visible: isVisibleSelector('compare'),
-                        tsLinesMap: currentVariableLineSegmentsSelector('compare'),
-                        xScale: xScaleSelector('compare'),
-                        yScale: yScaleSelector,
-                        tsKey: () => 'compare'
-                    })))
-                    .call(createTooltipFocus)
-                    .call(link(plotAllMedianPoints, createStructuredSelector({
-                        visible: isVisibleSelector('median'),
-                        xscale: xScaleSelector('current'),
-                        yscale: yScaleSelector,
-                        seriesPoints: getCurrentVariableMedianStatPoints
-                    })));
-            });
+            }, getZoomLayout
+            ))
+        .call(svg => {
+            svg.append('g')
+                .call(link((elem, layout) => elem.attr('transform', `translate(${layout.margin.left},${layout.margin.top})`),
+                                getZoomLayout
+                ))
+                .call(link(appendAxes, getAxes('ZOOM')));
+        });
 };
\ No newline at end of file
diff --git a/assets/src/scripts/components/hydrograph/tooltip.js b/assets/src/scripts/components/hydrograph/tooltip.js
index 5bfaa9cd71c984b5708a83a55363d06de92ee127..2cbcd69e47a8d6f56841e06a8052e5ff70806afb 100644
--- a/assets/src/scripts/components/hydrograph/tooltip.js
+++ b/assets/src/scripts/components/hydrograph/tooltip.js
@@ -9,8 +9,8 @@ import { dispatch, link, initAndUpdate } from '../../lib/redux';
 import { Actions } from '../../store';
 import { cursorTimeSelector, tsCursorPointsSelector } from './cursor';
 import { classesForPoint, MASK_DESC } from './drawing-data';
-import { layoutSelector } from './layout';
-import { xScaleSelector, yScaleSelector } from './scales';
+import { getMainLayout } from './layout';
+import { xScaleSelector, getYScale } from './scales';
 import { tsTimeZoneSelector, TEMPERATURE_PARAMETERS } from './time-series';
 import { getCurrentVariable, getCurrentParmCd } from '../../selectors/time-series-selector';
 import config from '../../config';
@@ -55,7 +55,7 @@ const updateFocusLine = function(elem, {cursorTime, yScale, xScale}) {
  */
 export const tooltipPointsSelector = memoize(tsKey => createSelector(
     xScaleSelector(tsKey),
-    yScaleSelector,
+    getYScale(),
     tsCursorPointsSelector(tsKey),
     (xScale, yScale, cursorPoints) => {
         return Object.keys(cursorPoints).reduce((tooltipPoints, tsID) => {
@@ -218,7 +218,7 @@ export const createTooltipText = function (elem) {
         comparePoints: tsCursorPointsSelector('compare'),
         qualifiers: qualifiersSelector,
         unitCode: unitCodeSelector,
-        layout: layoutSelector,
+        layout: getMainLayout,
         ianaTimeZone: tsTimeZoneSelector,
         currentParmCd: getCurrentParmCd
     })));
@@ -268,7 +268,7 @@ const createFocusCircles = function (elem, tooltipPoints, circleContainer) {
 export const createTooltipFocus = function(elem) {
     elem.call(link(initAndUpdate(createFocusLine, updateFocusLine), createStructuredSelector({
         xScale: xScaleSelector('current'),
-        yScale: yScaleSelector,
+        yScale: getYScale(),
         cursorTime: cursorTimeSelector('current')
     })));
 
@@ -303,6 +303,6 @@ export const createTooltipFocus = function(elem) {
             }));
     }, createStructuredSelector({
         xScale: xScaleSelector('current'),
-        layout: layoutSelector
+        layout: getMainLayout
     })));
 };