From 73c5deffc154f6726d11296e49f5a12c04df8592 Mon Sep 17 00:00:00 2001 From: Paul Felix Date: Thu, 29 Mar 2012 17:24:03 -0400 Subject: [PATCH] Misc range selector cleanup. --- dygraph-range-selector.js | 95 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/dygraph-range-selector.js b/dygraph-range-selector.js index 9ae04d0..6cc184e 100644 --- a/dygraph-range-selector.js +++ b/dygraph-range-selector.js @@ -19,6 +19,8 @@ var DygraphRangeSelector = function(dygraph) { this.isIE_ = /MSIE/.test(navigator.userAgent) && !window.opera; this.isUsingExcanvas_ = dygraph.isUsingExcanvas_; this.dygraph_ = dygraph; + this.hasTouchInterface_ = typeof(TouchEvent) != 'undefined'; + this.isMobileDevice_ = Math.min(screen.width, screen.height) < 480; this.createCanvases_(); if (this.isUsingExcanvas_) { this.createIEPanOverlay_(); @@ -135,15 +137,16 @@ DygraphRangeSelector.prototype.createZoomHandles_ = function() { img.style.zIndex = 10; img.style.visibility = 'hidden'; // Initially hidden so they don't show up in the wrong place. img.style.cursor = 'col-resize'; + if (/MSIE 7/.test(navigator.userAgent)) { // IE7 doesn't support embedded src data. - img.width = 7; - img.height = 14; - img.style.backgroundColor = 'white'; - img.style.border = '1px solid #333333'; // Just show box in IE7. + img.width = 7; + img.height = 14; + img.style.backgroundColor = 'white'; + img.style.border = '1px solid #333333'; // Just show box in IE7. } else { - img.width = 9; - img.height = 16; - img.src = 'data:image/png;base64,' + + img.width = 9; + img.height = 16; + img.src = 'data:image/png;base64,' + 'iVBORw0KGgoAAAANSUhEUgAAAAkAAAAQCAYAAADESFVDAAAAAXNSR0IArs4c6QAAAAZiS0dEANAA' + 'zwDP4Z7KegAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9sHGw0cMqdt1UwAAAAZdEVYdENv' + 'bW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAaElEQVQoz+3SsRFAQBCF4Z9WJM8KCDVwownl' + @@ -151,6 +154,15 @@ DygraphRangeSelector.prototype.createZoomHandles_ = function() { 'qSTDH32I1pQA2Pb9sZecAxc5r3IAb21d6878xsAAAAAASUVORK5CYII='; } + var minScreenDim = Math.min(screen.width, screen.height); + if (minScreenDim < 480) { + img.width *= 3; + img.height *= 3; + } else if (minScreenDim < 768) { + img.width *= 2; + img.height *= 2; + } + this.leftZoomHandle_ = img; this.rightZoomHandle_ = img.cloneNode(false); }; @@ -166,12 +178,16 @@ DygraphRangeSelector.prototype.initInteraction_ = function() { var handle = null; var isZooming = false; var isPanning = false; + var dynamic = !this.isMobileDevice_ && !this.isUsingExcanvas_; // 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, onCanvasMouseMove; + // Touch event functions + var onZoomHandleTouchEvent, onCanvasTouchEvent, addTouchEvents; + toXDataWindow = function(zoomHandleStatus) { var xDataLimits = self.dygraph_.xAxisExtremes(); var fact = (xDataLimits[1] - xDataLimits[0])/self.canvasRect_.w; @@ -215,7 +231,7 @@ DygraphRangeSelector.prototype.initInteraction_ = function() { self.drawInteractiveLayer_(); // Zoom on the fly (if not using excanvas). - if (!self.isUsingExcanvas_) { + if (dynamic) { doZoom(); } }; @@ -230,7 +246,7 @@ DygraphRangeSelector.prototype.initInteraction_ = function() { self.fgcanvas_.style.cursor = 'default'; // If using excanvas, Zoom now. - if (self.isUsingExcanvas_) { + if (!dynamic) { doZoom(); } }; @@ -254,15 +270,11 @@ DygraphRangeSelector.prototype.initInteraction_ = function() { if (self.isUsingExcanvas_) { return e.srcElement == self.iePanOverlay_; } else { - // Getting clientX directly from the event is not accurate enough :( - var clientX; - if (e.offsetX != undefined) { - clientX = self.canvasRect_.x + e.offsetX; - } else { - clientX = e.clientX; - } - var zoomHandleStatus = self.getZoomHandleStatus_(); - return (clientX > zoomHandleStatus.leftHandlePos && clientX < zoomHandleStatus.rightHandlePos); + var rect = self.leftZoomHandle_.getBoundingClientRect(); + var leftHandleClientX = rect.left + rect.width/2; + rect = self.rightZoomHandle_.getBoundingClientRect(); + var rightHandleClientX = rect.left + rect.width/2; + return (e.clientX > leftHandleClientX && e.clientX < rightHandleClientX); } }; @@ -309,7 +321,7 @@ DygraphRangeSelector.prototype.initInteraction_ = function() { self.drawInteractiveLayer_(); // Do pan on the fly (if not using excanvas). - if (!self.isUsingExcanvas_) { + if (dynamic) { doPan(); } }; @@ -322,7 +334,7 @@ DygraphRangeSelector.prototype.initInteraction_ = function() { Dygraph.removeEvent(topElem, 'mousemove', onPan); Dygraph.removeEvent(topElem, 'mouseup', onPanEnd); // If using excanvas, do pan now. - if (self.isUsingExcanvas_) { + if (!dynamic) { doPan(); } }; @@ -347,6 +359,35 @@ DygraphRangeSelector.prototype.initInteraction_ = function() { } }; + onZoomHandleTouchEvent = function(e) { + e.preventDefault(); + if (e.type == 'touchstart') { + onZoomStart(e.targetTouches[0]); + } else if (e.type == 'touchmove') { + onZoom(e.targetTouches[0]); + } else { + onZoomEnd(e); + } + }; + + onCanvasTouchEvent = function(e) { + e.preventDefault(); + if (e.type == 'touchstart') { + onPanStart(e.targetTouches[0]); + } else if (e.type == 'touchmove') { + onPan(e.targetTouches[0]); + } else { + onPanEnd(e); + } + }; + + addTouchEvents = function(elem, fn) { + var types = ['touchstart', 'touchend', 'touchmove', 'touchcancel']; + for (var i = 0; i < types.length; i++) { + Dygraph.addEvent(elem, types[i], fn); + } + }; + this.dygraph_.attrs_.interactionModel = Dygraph.Interaction.dragIsPanInteractionModel; this.dygraph_.attrs_.panEdgeFraction = 0.0001; @@ -361,6 +402,13 @@ DygraphRangeSelector.prototype.initInteraction_ = function() { Dygraph.addEvent(this.fgcanvas_, 'mousedown', onPanStart); Dygraph.addEvent(this.fgcanvas_, 'mousemove', onCanvasMouseMove); } + + // Touch events + if (this.hasTouchInterface_) { + addTouchEvents(this.leftZoomHandle_, onZoomHandleTouchEvent); + addTouchEvents(this.rightZoomHandle_, onZoomHandleTouchEvent); + addTouchEvents(this.fgcanvas_, onCanvasTouchEvent); + } }; /** @@ -454,14 +502,14 @@ DygraphRangeSelector.prototype.computeCombinedSeriesAndLimits_ = function() { var combinedSeries = []; var sum; var count; - var yVal, y; var mutipleValues; var i, j, k; + var xVal, yVal; // Find out if data has multiple values per datapoint. // Go to first data point that actually has values (see http://code.google.com/p/dygraphs/issues/detail?id=246) for (i = 0; i < data.length; i++) { - if (data[i].length > 1 && data[i][1] != null) { + if (data[i].length > 1 && data[i][1] !== null) { mutipleValues = typeof data[i][1] != 'number'; if (mutipleValues) { sum = []; @@ -477,7 +525,7 @@ DygraphRangeSelector.prototype.computeCombinedSeriesAndLimits_ = function() { for (i = 0; i < data.length; i++) { var dataPoint = data[i]; - var xVal = dataPoint[0]; + xVal = dataPoint[0]; if (mutipleValues) { for (k = 0; k < sum.length; k++) { @@ -489,6 +537,7 @@ DygraphRangeSelector.prototype.computeCombinedSeriesAndLimits_ = function() { for (j = 1; j < dataPoint.length; j++) { if (this.dygraph_.visibility()[j-1]) { + var y; if (mutipleValues) { for (k = 0; k < sum.length; k++) { y = dataPoint[j][k]; -- 2.7.4