From 2871344a34358f8c02b909c3d795d4c47db09e0a Mon Sep 17 00:00:00 2001 From: Paul Felix Date: Tue, 26 Feb 2013 17:01:03 -0500 Subject: [PATCH] Fix for issue #439 --- auto_tests/tests/range_selector.js | 118 +++++++++++++++++++++++++++++++++++++ plugins/range-selector.js | 34 ++++------- 2 files changed, 128 insertions(+), 24 deletions(-) diff --git a/auto_tests/tests/range_selector.js b/auto_tests/tests/range_selector.js index 4ced4f2..a27cad7 100644 --- a/auto_tests/tests/range_selector.js +++ b/auto_tests/tests/range_selector.js @@ -200,6 +200,124 @@ RangeSelectorTestCase.prototype.testRangeSelectorWithAnimatedZoomsOption2 = func assertFalse(g.getOption('animatedZooms')); }; +RangeSelectorTestCase.prototype.testRangeSelectorInteraction = function() { + var opts = { + width: 480, + height: 320, + showRangeSelector: true + }; + var data = [ + [1, 10], + [2, 15], + [3, 10], + [4, 15], + [5, 10], + [6, 15], + [7, 10], + [8, 15], + [9, 10] + ]; + var graph = document.getElementById("graph"); + var g = new Dygraph(graph, data, opts); + this.assertGraphExistence(g, graph); + var zoomhandles = graph.getElementsByClassName('dygraph-rangesel-zoomhandle'); + + // Move left zoomhandle in + var xRange = g.xAxisRange().slice(); + + var mouseDownEvent = DygraphOps.createEvent({ + type : 'dragstart', + detail: 1, + clientX : 0, + clientY : 0 + }); + zoomhandles[0].dispatchEvent(mouseDownEvent); + + var mouseMoveEvent = DygraphOps.createEvent({ + type : 'mousemove', + clientX : 20, + clientY : 20 + }); + zoomhandles[0].dispatchEvent(mouseMoveEvent); + + var mouseUpEvent = DygraphOps.createEvent({ + type : 'mouseup', + detail: 1, + clientX : 20, + clientY : 20 + }); + zoomhandles[0].dispatchEvent(mouseUpEvent); + + var newXRange = g.xAxisRange().slice(); + assert('left zoomhandle should have moved: '+newXRange[0]+'>'+xRange[0], newXRange[0] > xRange[0]); + assertEquals('right zoomhandle should not have moved', xRange[1], newXRange[1]); + + // Move right zoomhandle in + xRange = newXRange; + + mouseDownEvent = DygraphOps.createEvent({ + type : 'dragstart', + detail: 1, + clientX : 100, + clientY : 100 + }); + zoomhandles[1].dispatchEvent(mouseDownEvent); + + mouseMoveEvent = DygraphOps.createEvent({ + type : 'mousemove', + clientX : 80, + clientY : 80 + }); + zoomhandles[1].dispatchEvent(mouseMoveEvent); + + mouseUpEvent = DygraphOps.createEvent({ + type : 'mouseup', + detail: 1, + clientX : 80, + clientY : 80 + }); + zoomhandles[1].dispatchEvent(mouseUpEvent); + + var newXRange = g.xAxisRange().slice(); + assert('right zoomhandle should have moved: '+newXRange[1]+'<'+xRange[1], newXRange[1] < xRange[1]); + assertEquals('left zoomhandle should not have moved', xRange[0], newXRange[0]); + + // Pan left + xRange = newXRange; + var fgcanvas = graph.getElementsByClassName('dygraph-rangesel-fgcanvas')[0]; + var x = parseInt(zoomhandles[0].style.left) + 20; + var y = parseInt(zoomhandles[0].style.top); + + mouseDownEvent = DygraphOps.createEvent({ + type : 'mousedown', + detail: 1, + clientX : x, + clientY : y + }); + fgcanvas.dispatchEvent(mouseDownEvent); + + x -= 10; + + mouseMoveEvent = DygraphOps.createEvent({ + type : 'mousemove', + clientX : x, + clientY : y + }); + fgcanvas.dispatchEvent(mouseMoveEvent); + + mouseUpEvent = DygraphOps.createEvent({ + type : 'mouseup', + detail: 1, + clientX : x, + clientY : y + }); + fgcanvas.dispatchEvent(mouseUpEvent); + + var newXRange = g.xAxisRange().slice(); + assert(newXRange[0]+'<'+xRange[0], newXRange[0] < xRange[0]); + assert(newXRange[1]+'<'+xRange[1], newXRange[1] < xRange[1]); +}; + RangeSelectorTestCase.prototype.assertGraphExistence = function(g, graph) { assertNotNull(g); var zoomhandles = graph.getElementsByClassName('dygraph-rangesel-zoomhandle'); diff --git a/plugins/range-selector.js b/plugins/range-selector.js index c2158d3..df8f867 100644 --- a/plugins/range-selector.js +++ b/plugins/range-selector.js @@ -265,7 +265,7 @@ rangeSelector.prototype.createZoomHandles_ = function() { rangeSelector.prototype.initInteraction_ = function() { var self = this; var topElem = this.isIE_ ? document : window; - var pageXLast = 0; + var clientXLast = 0; var handle = null; var isZooming = false; var isPanning = false; @@ -278,7 +278,7 @@ rangeSelector.prototype.initInteraction_ = function() { // functions, defined below. Defining them this way (rather than with // "function foo() {...}" makes JSHint happy. var toXDataWindow, onZoomStart, onZoom, onZoomEnd, doZoom, isMouseInPanZone, - onPanStart, onPan, onPanEnd, doPan, onCanvasHover, getCursorPageX; + onPanStart, onPan, onPanEnd, doPan, onCanvasHover; // Touch event functions var onZoomHandleTouchEvent, onCanvasTouchEvent, addTouchEvents; @@ -291,22 +291,10 @@ rangeSelector.prototype.initInteraction_ = function() { return [xDataMin, xDataMax]; }; - getCursorPageX = function(e) { - if (e.pageX !== null) { - return e.pageX; - } else { - // Taken from jQuery. - var target = e.target || e.srcElement || document; - var eventDoc = target.ownerDocument || target.document || document; - var doc = eventDoc.documentElement, body = eventDoc.body; - return e.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); - } - }; - onZoomStart = function(e) { Dygraph.cancelEvent(e); isZooming = true; - pageXLast = getCursorPageX(e); + clientXLast = e.clientX; handle = e.target ? e.target : e.srcElement; if (e.type === 'mousedown' || e.type === 'dragstart') { // These events are removed manually. @@ -324,22 +312,21 @@ rangeSelector.prototype.initInteraction_ = function() { } Dygraph.cancelEvent(e); - var pageX = getCursorPageX(e); - var delX = pageX - pageXLast; + var delX = e.clientX - clientXLast; if (Math.abs(delX) < 4) { return true; } - pageXLast = pageX; + clientXLast = e.clientX; // Move handle. var zoomHandleStatus = self.getZoomHandleStatus_(); var newPos; if (handle == self.leftZoomHandle_) { - newPos = pageX; + newPos = zoomHandleStatus.leftHandlePos + delX; newPos = Math.min(newPos, zoomHandleStatus.rightHandlePos - handle.width - 3); newPos = Math.max(newPos, self.canvasRect_.x); } else { - newPos = pageX; + newPos = zoomHandleStatus.rightHandlePos + delX; newPos = Math.min(newPos, self.canvasRect_.x + self.canvasRect_.w); newPos = Math.max(newPos, zoomHandleStatus.leftHandlePos + handle.width + 3); } @@ -402,7 +389,7 @@ rangeSelector.prototype.initInteraction_ = function() { if (!isPanning && isMouseInPanZone(e) && self.getZoomHandleStatus_().isZoomed) { Dygraph.cancelEvent(e); isPanning = true; - pageXLast = getCursorPageX(e); + clientXLast = e.clientX; if (e.type === 'mousedown') { // These events are removed manually. Dygraph.addEvent(topElem, 'mousemove', onPan); @@ -419,12 +406,11 @@ rangeSelector.prototype.initInteraction_ = function() { } Dygraph.cancelEvent(e); - var pageX = getCursorPageX(e); - var delX = pageX - pageXLast; + var delX = e.clientX - clientXLast; if (Math.abs(delX) < 4) { return true; } - pageXLast = pageX; + clientXLast = e.clientX; // Move range view var zoomHandleStatus = self.getZoomHandleStatus_(); -- 2.7.4