From 58487e58b9e3538aebba6ad48d04e9b35034102c Mon Sep 17 00:00:00 2001 From: Indri Muska Date: Thu, 15 Oct 2015 11:59:56 +0200 Subject: [PATCH 1/2] Limit zoom bounds when `zoomOutRestrict=true` Based on @mhsmith solution: https://github.com/mbostock/d3/pull/2019 --- src/coordinate-grid-mixin.js | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/coordinate-grid-mixin.js b/src/coordinate-grid-mixin.js index 13e9f37b5..a9dba1afe 100644 --- a/src/coordinate-grid-mixin.js +++ b/src/coordinate-grid-mixin.js @@ -26,10 +26,7 @@ dc.coordinateGridMixin = function (_chart) { function zoomHandler () { _refocused = true; if (_zoomOutRestrict) { - _chart.x().domain(constrainRange(_chart.x().domain(), _xOriginalDomain)); - if (_rangeChart) { - _chart.x().domain(constrainRange(_chart.x().domain(), _rangeChart.x().domain())); - } + restrictZoom(_zoom, _xOriginalDomain); } var domain = _chart.x().domain(); @@ -1173,6 +1170,7 @@ dc.coordinateGridMixin = function (_chart) { _chart._enableMouseZoom = function () { _hasBeenMouseZoomable = true; + _zoom.x0 = _chart.x().copy(); _zoom.x(_chart.x()) .scaleExtent(_zoomScale) .size([_chart.width(), _chart.height()]) @@ -1184,11 +1182,30 @@ dc.coordinateGridMixin = function (_chart) { _chart.root().call(_nullZoom); }; - function constrainRange (range, constraint) { - var constrainedRange = []; - constrainedRange[0] = d3.max([range[0], constraint[0]]); - constrainedRange[1] = d3.min([range[1], constraint[1]]); - return constrainedRange; + function restrictZoom (zoom, extent) { + var ev = d3.event; + if (!ev) { + return; + } + + var translateX = ev.translate[0], + scale = ev.scale, + s0 = zoom.x0, + range0 = s0.range(), + getDomain = function () { return range0.map(function (r) { return (r - translateX) / scale; }).map(s0.invert); }, + domain; + + scale = Math.max(scale, Math.abs((range0[0] - range0[range0.length - 1]) / (s0(extent[0]) - s0(extent[1])))); + domain = getDomain(); + + if (domain[0] < extent[0]) { + translateX = range0[0] - (s0(extent[0]) * scale); + } else { + if (domain[domain.length - 1] > extent[1]) { + translateX = range0[range0.length - 1] - (s0(extent[1]) * scale); + } + } + zoom.x().domain(getDomain()); } /** From 74fc881f7ac5ea4e842831b0e536b9c68bdabe8b Mon Sep 17 00:00:00 2001 From: Indri Muska Date: Fri, 16 Oct 2015 09:34:36 +0200 Subject: [PATCH 2/2] Fixed `restrictZoom` fn to support zoom on `.focus()` --- src/coordinate-grid-mixin.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/coordinate-grid-mixin.js b/src/coordinate-grid-mixin.js index a9dba1afe..38a026e64 100644 --- a/src/coordinate-grid-mixin.js +++ b/src/coordinate-grid-mixin.js @@ -27,6 +27,9 @@ dc.coordinateGridMixin = function (_chart) { _refocused = true; if (_zoomOutRestrict) { restrictZoom(_zoom, _xOriginalDomain); + if (_rangeChart) { + restrictZoom(_zoom, _rangeChart.x().domain()); + } } var domain = _chart.x().domain(); @@ -1170,7 +1173,6 @@ dc.coordinateGridMixin = function (_chart) { _chart._enableMouseZoom = function () { _hasBeenMouseZoomable = true; - _zoom.x0 = _chart.x().copy(); _zoom.x(_chart.x()) .scaleExtent(_zoomScale) .size([_chart.width(), _chart.height()]) @@ -1183,26 +1185,21 @@ dc.coordinateGridMixin = function (_chart) { }; function restrictZoom (zoom, extent) { - var ev = d3.event; - if (!ev) { - return; - } - - var translateX = ev.translate[0], - scale = ev.scale, - s0 = zoom.x0, - range0 = s0.range(), - getDomain = function () { return range0.map(function (r) { return (r - translateX) / scale; }).map(s0.invert); }, + var translateX = zoom.translate()[0], + scale = zoom.scale(), + xScale = zoom.x(), + range = xScale.range(), + getDomain = function () { return range.map(function (r) { return (r - translateX) / scale; }).map(xScale.invert); }, domain; - scale = Math.max(scale, Math.abs((range0[0] - range0[range0.length - 1]) / (s0(extent[0]) - s0(extent[1])))); + scale = Math.max(scale, Math.abs((range[0] - range[range.length - 1]) / (xScale(extent[0]) - xScale(extent[1])))); domain = getDomain(); if (domain[0] < extent[0]) { - translateX = range0[0] - (s0(extent[0]) * scale); + translateX = range[0] - (xScale(extent[0]) * scale); } else { if (domain[domain.length - 1] > extent[1]) { - translateX = range0[range0.length - 1] - (s0(extent[1]) * scale); + translateX = range[range.length - 1] - (xScale(extent[1]) * scale); } } zoom.x().domain(getDomain());