this.tearDown();
return true;
} catch (e) {
- console.log(e.stack);
+ console.log(e);
+ if (e.stack) {
+ console.log(e.stack);
+ }
return false;
}
};
<script type="text/javascript" src="../tests/multi_csv.js"></script>
<script type="text/javascript" src="../tests/to_dom_coords.js"></script>
<script type="text/javascript" src="../tests/interaction_model.js"></script>
+ <script type="text/javascript" src="../tests/scrolling_div.js"></script>
+ <script type="text/javascript">
+ var tc = null;
+ function processVariables() {
+ var splitVariables = function() { // http://www.idealog.us/2006/06/javascript_to_p.html
+ var query = window.location.search.substring(1);
+ var args = {};
+ var vars = query.split("&");
+ for (var i = 0;i < vars.length; i++) {
+ var pair = vars[i].split("=");
+ args[pair[0]] = pair[1];
+ }
+ return args;
+ }
+
+ var args = splitVariables();
+ var test = args.test;
+ var command = args.command;
+
+ if (args.testCase) {
+ eval("tc = new " + args.testCase + "()");
+ if (args.command) {
+ if (args.command == "runAllTests") {
+ console.log("Running all tests for " + args.testCase);
+ tc.runAllTests();
+ }
+ if (args.command == "runTest") {
+ console.log("Running test " + args.testCase + "." + args.test);
+ tc.runTest(args.test);
+ }
+ }
+ }
+ }
+ </script>
</head>
<body>
<div id='graph'></div>
instance,<br>
<code>tc = new SimpleDrawingTestCase() ;<br>
tc.runTest("testDrawSimpleRangePlusOne")</code>
+
+ <p>Alternatively you can use query args: <ul>
+ <li>testCase - for the name of the test case
+ <li>test - for the name of the test (use command=runTest)
+ <li>command - either runTest or runAllTests.
+ </ul>
+ Example: <code>local.html?testCase=ScrollingDivTestCase&test=testNestedDiv_Scrolled&command=runTest</code>
</body>
+<script>
+processVariables();
+</script>
</html>
relatedTarget : null
};
-DygraphOps.createEvent_ = function(command, custom) {
+/**
+ * Create an event. Sets default event values except for special ones
+ * overridden by the 'custom' parameter.
+ *
+ * @param command the command to create.
+ * @param custom an associative array of event attributes and their new values.
+ */
+DygraphOps.createEvent = function(command, custom) {
var copy = function(from, to) {
if (from != null) {
return event;
}
+/**
+ * Dispatch an event onto the graph's canvas.
+ */
+DygraphOps.dispatchCanvasEvent = function(g, event) {
+ g.canvas_.dispatchEvent(event);
+}
+
DygraphOps.dispatchDoubleClick = function(g, custom) {
var opts = {
type : 'dblclick',
detail : 2
};
- var event = DygraphOps.createEvent_(opts, custom);
- g.canvas_.dispatchEvent(event);
+ var event = DygraphOps.createEvent(opts, custom);
+ DygraphOps.dispatchCanvasEvent(g, event);
};
DygraphOps.dispatchMouseDown_Point = function(g, x, y, custom) {
clientY : pageY,
};
- var event = DygraphOps.createEvent_(opts, custom);
- g.canvas_.dispatchEvent(event);
+ var event = DygraphOps.createEvent(opts, custom);
+ DygraphOps.dispatchCanvasEvent(g, event);
}
DygraphOps.dispatchMouseMove_Point = function(g, x, y, custom) {
clientY : pageY,
};
- var event = DygraphOps.createEvent_(opts, custom);
- g.canvas_.dispatchEvent(event);
+ var event = DygraphOps.createEvent(opts, custom);
+ DygraphOps.dispatchCanvasEvent(g, event);
};
DygraphOps.dispatchMouseUp_Point = function(g, x, y, custom) {
clientY : pageY,
};
- var event = DygraphOps.createEvent_(opts, custom);
- g.canvas_.dispatchEvent(event);
+ var event = DygraphOps.createEvent(opts, custom);
+ DygraphOps.dispatchCanvasEvent(g, event);
};
/**
--- /dev/null
+/**
+ * @fileoverview Test cases for a graph contained in a scrolling div
+ *
+ * @author konigsberg@google.com (Robert Konigsbrg)
+ */
+var ScrollingDivTestCase = TestCase("scrolling-div");
+
+ScrollingDivTestCase.prototype.setUp = function() {
+
+var LOREM_IPSUM =
+ "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\n" +
+ "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\n" +
+ "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n" +
+ "consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\n" +
+ "cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat\n" +
+ "non proident, sunt in culpa qui officia deserunt mollit anim id est\n" +
+ "laborum.</p>";
+
+ document.body.innerHTML =
+ "<div style='overflow: scroll; height: 450px; width: 800px;'>" +
+ "<a name='TOP'></a><div id='graph'></div>" +
+ "<div style='height:100px; background-color:green;'>" + LOREM_IPSUM + " </div>" +
+ "<div style='height:100px; background-color:red;'>" + LOREM_IPSUM + "</div>" +
+ "<a name='BOTTOM'></a>" +
+ "</div>";
+
+ var data = [
+ [ 10, 1 ],
+ [ 20, 3 ],
+ [ 30, 2 ],
+ [ 40, 4 ],
+ [ 50, 3 ],
+ [ 60, 5 ],
+ [ 70, 4 ],
+ [ 80, 6 ] ];
+
+ var graph = document.getElementById("graph");
+
+ this.point = null;
+ var self = this;
+ this.g = new Dygraph(graph, data,
+ {
+ labels : ['a', 'b'],
+ drawPoints : true,
+ highlightCircleSize : 6,
+ pointClickCallback : function(evt, point) {
+ self.point = point;
+ }
+ }
+ );
+
+};
+
+ScrollingDivTestCase.prototype.tearDown = function() {
+};
+
+/**
+ * This tests that when the nested div is unscrolled, things work normally.
+ */
+ScrollingDivTestCase.prototype.testUnscrolledDiv = function() {
+
+ window.location.href="#TOP";
+
+ var clickOn4_40 = {
+ clientX: 244,
+ clientY: 131,
+ screenX: 416,
+ screenY: 320
+ };
+
+ DygraphOps.dispatchCanvasEvent(this.g, DygraphOps.createEvent(clickOn4_40, { type : 'mousemove' }));
+ DygraphOps.dispatchCanvasEvent(this.g, DygraphOps.createEvent(clickOn4_40, { type : 'mousedown' }));
+ DygraphOps.dispatchCanvasEvent(this.g, DygraphOps.createEvent(clickOn4_40, { type : 'mouseup' }));
+
+ assertEquals(40, this.point.xval);
+ assertEquals(4, this.point.yval);
+};
+
+/**
+ * This tests that when the nested div is scrolled, things work normally.
+ */
+ScrollingDivTestCase.prototype.testScrolledDiv = function() {
+ window.location.href="#BOTTOM";
+
+ var clickOn4_40 = {
+ clientX: 244,
+ clientY: 20,
+ screenX: 416,
+ screenY: 160
+ };
+
+ DygraphOps.dispatchCanvasEvent(this.g, DygraphOps.createEvent(clickOn4_40, { type : 'mousemove' }));
+ DygraphOps.dispatchCanvasEvent(this.g, DygraphOps.createEvent(clickOn4_40, { type : 'mousedown' }));
+ DygraphOps.dispatchCanvasEvent(this.g, DygraphOps.createEvent(clickOn4_40, { type : 'mouseup' }));
+
+ assertEquals(40, this.point.xval);
+ assertEquals(4, this.point.yval);
+};
// The following functions are from quirksmode.org with a modification for Safari from
// http://blog.firetree.net/2005/07/04/javascript-find-position/
// http://www.quirksmode.org/js/findpos.html
+// ... and modifications to support scrolling divs.
-/** @private */
+/**
+ * Find the x-coordinate of the supplied object relative to the left side
+ * of the page.
+ * @private
+ */
Dygraph.findPosX = function(obj) {
var curleft = 0;
- if(obj.offsetParent)
- while(1)
- {
- curleft += obj.offsetLeft;
- if(!obj.offsetParent)
+ if(obj.offsetParent) {
+ var copyObj = obj;
+ while(1) {
+ curleft += copyObj.offsetLeft;
+ if(!copyObj.offsetParent) {
break;
- obj = obj.offsetParent;
+ }
+ copyObj = copyObj.offsetParent;
}
- else if(obj.x)
+ } else if(obj.x) {
curleft += obj.x;
+ }
+ // This handles the case where the object is inside a scrolled div.
+ while(obj && obj != document.body) {
+ curleft -= obj.scrollLeft;
+ obj = obj.parentNode;
+ }
return curleft;
};
-/** @private */
+/**
+ * Find the y-coordinate of the supplied object relative to the top of the
+ * page.
+ * @private
+ */
Dygraph.findPosY = function(obj) {
var curtop = 0;
- if(obj.offsetParent)
- while(1)
- {
- curtop += obj.offsetTop;
- if(!obj.offsetParent)
+ if(obj.offsetParent) {
+ var copyObj = obj;
+ while(1) {
+ curtop += copyObj.offsetTop;
+ if(!copyObj.offsetParent) {
break;
- obj = obj.offsetParent;
+ }
+ copyObj = copyObj.offsetParent;
}
- else if(obj.y)
+ } else if(obj.y) {
curtop += obj.y;
+ }
+ // This handles the case where the object is inside a scrolled div.
+ while(obj && obj != document.body) {
+ curtop -= obj.scrollTop;
+ obj = obj.parentNode;
+ }
return curtop;
};
isZooming: false,
isPanning: false, // is this drag part of a pan?
is2DPan: false, // if so, is that pan 1- or 2-dimensional?
- dragStartX: null,
- dragStartY: null,
- dragEndX: null,
- dragEndY: null,
+ dragStartX: null, // pixel coordinates
+ dragStartY: null, // pixel coordinates
+ dragEndX: null, // pixel coordinates
+ dragEndY: null, // pixel coordinates
dragDirection: null,
- prevEndX: null,
- prevEndY: null,
+ prevEndX: null, // pixel coordinates
+ prevEndY: null, // pixel coordinates
prevDragDirection: null,
// The value on the left side of the graph when a pan operation starts.
// panning operation.
dateRange: null,
- // Utility function to convert page-wide coordinates to canvas coords
+ // Top-left corner of the canvas, in DOM coords
+ // TODO(konigsberg): Rename topLeftCanvasX, topLeftCanvasY.
px: 0,
py: 0,