[perf-web] Add click-and-drag scrolling



commit efb356ac3c8c9e185c5109e8b6d9af4dc4596604
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Wed Jul 23 21:45:02 2014 -0400

    Add click-and-drag scrolling
    
    On tablets and mobile or even on a desktop having the only way to
    scroll the graphs is scroll-wheel is annoying. Add click-and-drag
    scrolling for both the graphs and for simple scrolling of the left
    and right divs.

 static/main.js |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 111 insertions(+), 8 deletions(-)
---
diff --git a/static/main.js b/static/main.js
index 6580653..58b80ea 100644
--- a/static/main.js
+++ b/static/main.js
@@ -511,6 +511,88 @@ TableColumn.prototype.prepareRange = function(min, max, units) {
 
 ////////////////////////////////////////////////////////////////////////
 
+function ScrollHandler(params)
+{
+    this.exclusive = params.exclusive;
+    this.source = params.element;
+    this.target = params.target;
+    if (params.startFunction)
+        this.startFunction = params.startFunction;
+    if (params.scrollFunctionX)
+        this.scrollFunctionX = params.scrollFunctionX;
+    if (params.scrollFunctionY)
+        this.scrollFunctionY = params.scrollFunctionY;
+
+    params.source.addEventListener("mousedown", function(event) {
+        if (event.buttons == 1) {
+            var node = event.target;
+            while (node) {
+                if (node.tagName == "a")
+                    return;
+                node = node.parentNode;
+            }
+
+            this.startDrag(event.clientX, event.clientY);
+            event.preventDefault();
+            event.stopPropagation();
+        }
+    }.bind(this));
+    document.body.addEventListener("mousemove", function(event) {
+        if (this.dragStartX != null) {
+            if ((event.buttons & 1) == 0) {
+                this.dragStartX = null;
+                return;
+            }
+            this.updateDrag(event.clientX, event.clientY);
+            event.preventDefault();
+            event.stopPropagation();
+        }
+    }.bind(this), true);
+    document.body.addEventListener("mouseup", function(event) {
+        if (this.dragStartX != null) {
+            this.updateDrag(event.clientX, event.clientY);
+            this.dragStartX = null;
+            event.preventDefault();
+            event.stopPropagation();
+        }
+    }.bind(this), true);
+}
+
+ScrollHandler.prototype.startDrag = function(x, y) {
+    this.dragStartX = x;
+    this.dragStartY = y;
+    if (this.target) {
+        this.dragStartScrollTop = this.target.scrollTop;
+        this.dragStartScrollLeft = this.target.scrollLeft;
+    }
+    if (this.startFunction)
+        this.startFunction();
+}
+
+ScrollHandler.prototype.updateDrag = function(x, y) {
+    var deltaX = x - this.dragStartX;
+    var deltaY = y - this.dragStartY;
+
+    if (this.exclusive) {
+        if (Math.abs(deltaX) > Math.abs(deltaY))
+            deltaY = 0;
+        else
+            deltaX = 0;
+    }
+
+    if (this.scrollFunctionX)
+        this.scrollFunctionX(deltaX);
+    else if (this.target)
+        this.target.scrollLeft = this.dragStartScrollLeft - deltaX;
+
+    if (this.scrollFunctionY)
+        this.scrollFunctionY(y - this.dragStartY);
+    else if (this.target)
+        this.target.scrollTop = this.dragStartScrollTop - deltaY;
+}
+
+////////////////////////////////////////////////////////////////////////
+
 function Table(element) {
     if (element == null) // prototype
         return;
@@ -527,6 +609,11 @@ function Table(element) {
         $( "#columnLabelTable" ).css("left", - $( this ).scrollLeft() + "px");
         $( "#rowLabelTable" ).css("top", - $( this ).scrollTop() + "px");
     });
+
+    this.scrollHandler = new ScrollHandler({
+        source: $( "#mainRight" ).get(0),
+        target: $( "#dataTableDiv" ).get(0),
+    });
 }
 
 Table.prototype.refresh = function() {
@@ -1094,6 +1181,17 @@ PerfDisplay.prototype.updateElementsForRange = function() {
     $( "#" + rangeType + "Link" ).addClass('range-active');
 }
 
+PerfDisplay.prototype.scrollByDeltaX = function(startTime, deltaX) {
+    var chart = $( ".chart" ).first().get(0);
+    var chartBodyWidth = chart.parentNode.clientWidth - (MARGIN_LEFT + MARGIN_RIGHT + 2);
+    var newPos = startTime + deltaX * this.rangeSeconds / chartBodyWidth;
+    if (newPos == this.centerTime)
+        return;
+
+    this.setPositionAndRange(newPos,
+                             this.rangeType,
+                             true);
+}
 
 PerfDisplay.prototype.onWindowLoaded = function() {
     this.updateElementsForRange();
@@ -1127,16 +1225,21 @@ PerfDisplay.prototype.onWindowLoaded = function() {
 
     var mainLeft = $( "#mainLeft" ).get(0);
     mainLeft.addEventListener("wheel", function(event) {
-        if (event.deltaX == 0)
-            return;
-
-        var chart = $( ".chart" ).first().get(0);
-        var chartBodyWidth = chart.parentNode.clientWidth - (MARGIN_LEFT + MARGIN_RIGHT + 2);
-        this.setPositionAndRange(this.centerTime + 10 * event.deltaX * this.rangeSeconds / chartBodyWidth,
-                                 this.rangeType,
-                                 true);
+        this.scrollByDeltaX(this.centerTime, 10 * event.deltaX);
     }.bind(this));
 
+    this.scrollHandler = new ScrollHandler({
+        exclusive: true,
+        source: mainLeft,
+        target: mainLeft,
+        startFunction: function() {
+            this.dragStartTime = theDisplay.centerTime;
+        },
+        scrollFunctionX: function(deltaX) {
+            theDisplay.scrollByDeltaX(this.dragStartTime, -deltaX);
+        }
+    });
+
     $( window ).resize(function() {
         this.refresh();
     }.bind(this));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]