var isPanning = false;
var dynamic = !this.isMobileDevice_ && !this.isUsingExcanvas_;
+ // We cover iframes during mouse interactions. See comments in
+ // dygraph-utils.js for more info on why this is a good idea.
+ var tarp = new Dygraph.IFrameTarp();
+
// functions, defined below. Defining them this way (rather than with
// "function foo() {...}" makes JSHint happy.
var toXDataWindow, onZoomStart, onZoom, onZoomEnd, doZoom, isMouseInPanZone,
self.dygraph_.addEvent(topElem, 'mousemove', onZoom);
self.dygraph_.addEvent(topElem, 'mouseup', onZoomEnd);
self.fgcanvas_.style.cursor = 'col-resize';
+ tarp.cover();
return true;
};
return false;
}
isZooming = false;
+ tarp.uncover();
Dygraph.removeEvent(topElem, 'mousemove', onZoom);
Dygraph.removeEvent(topElem, 'mouseup', onZoomEnd);
self.fgcanvas_.style.cursor = 'default';
ctx.stroke();
}
};
+
+/**
+ * To create a "drag" interaction, you typically register a mousedown event
+ * handler on the element where the drag begins. In that handler, you register a
+ * mouseup handler on the window to determine when the mouse is released,
+ * wherever that release happens. This works well, except when the user releases
+ * the mouse over an off-domain iframe. In that case, the mouseup event is
+ * handled by the iframe and never bubbles up to the window handler.
+ *
+ * To deal with this issue, we cover iframes with high z-index divs to make sure
+ * they don't capture mouseup.
+ *
+ * Usage:
+ * element.addEventListener('mousedown', function() {
+ * var tarper = new Dygraph.IFrameTarp();
+ * tarper.cover();
+ * var mouseUpHandler = function() {
+ * ...
+ * window.removeEventListener(mouseUpHandler);
+ * tarper.uncover();
+ * };
+ * window.addEventListener('mouseup', mouseUpHandler);
+ * };
+ *
+ *
+ * @constructor
+ */
+Dygraph.IFrameTarp = function() {
+ this.tarps = [];
+};
+
+/**
+ * Find all the iframes in the document and cover them with high z-index
+ * transparent divs.
+ */
+Dygraph.IFrameTarp.prototype.cover = function() {
+ var iframes = document.getElementsByTagName("iframe");
+ for (var i = 0; i < iframes.length; i++) {
+ var iframe = iframes[i];
+ var x = Dygraph.findPosX(iframe),
+ y = Dygraph.findPosY(iframe),
+ width = iframe.offsetWidth,
+ height = iframe.offsetHeight;
+
+ var div = document.createElement("div");
+ div.style.position = "absolute";
+ div.style.left = x + 'px';
+ div.style.top = y + 'px';
+ div.style.width = width + 'px';
+ div.style.height = height + 'px';
+ div.style.zIndex = 999;
+ document.body.appendChild(div);
+ this.tarps.push(div);
+ }
+};
+
+/**
+ * Remove all the iframe covers. You should call this in a mouseup handler.
+ */
+Dygraph.IFrameTarp.prototype.uncover = function() {
+ for (var i = 0; i < this.tarps.length; i++) {
+ this.tarps[i].parentNode.removeChild(this.tarps[i]);
+ }
+ this.tarps = [];
+};
boundedDates: null, // [minDate, maxDate]
boundedValues: null, // [[minValue, maxValue] ...]
+ // We cover iframes during mouse interactions. See comments in
+ // dygraph-utils.js for more info on why this is a good idea.
+ tarp: new Dygraph.IFrameTarp(),
+
// contextB is the same thing as this context object but renamed.
initializeMouseDown: function(event, g, contextB) {
// prevents mouse drags from selecting page text.
contextB.dragStartX = g.dragGetX_(event, contextB);
contextB.dragStartY = g.dragGetY_(event, contextB);
contextB.cancelNextDblclick = false;
+ contextB.tarp.cover();
}
};
delete self.axes_[i].dragValueRange;
}
}
+
+ context.tarp.uncover();
};
this.addEvent(window, 'mouseup', this.mouseUpHandler_);
--- /dev/null
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
+ <title>demo</title>
+ <!--[if IE]>
+ <script type="text/javascript" src="../excanvas.js"></script>
+ <![endif]-->
+ <script type="text/javascript" src="../dygraph-dev.js"></script>
+
+ <style type="text/css">
+ .chart {
+ position: absolute;
+ left: 10px;
+ width: 500px;
+ height: 250px;
+ border: 1px solid black;
+ }
+ #chart1 {
+ top: 10px;
+ }
+ #chart2 {
+ top: 270px;
+ }
+ #iframe {
+ border: 1px solid black;
+ position: absolute;
+ left: 520px;
+ }
+ p {
+ position: absolute;
+ top: 550px;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="chart" id="chart1"></div>
+ <div class="chart" id="chart2"></div>
+ <iframe id="iframe" width=400 height=520 src="http://en.wikipedia.org/">iframe here</iframe>
+
+ <p>Click on various places in the chart, then drag the mouse over the iframe
+ and release it. When you mouse back over the charts, strange things will
+ happen.</p>
+
+ <script type="text/javascript">
+ var data = function() {
+ var zp = function(x) { if (x < 10) return "0"+x; else return x; };
+ var r = "date,parabola,line,another line,sine wave\n";
+ for (var i=1; i<=31; i++) {
+ r += "200610" + zp(i);
+ r += "," + 10*(i*(31-i));
+ r += "," + 10*(8*i);
+ r += "," + 10*(250 - 8*i);
+ r += "," + 10*(125 + 125 * Math.sin(0.3*i));
+ r += "\n";
+ }
+ return r;
+ };
+
+ g1 = new Dygraph(
+ document.getElementById("chart1"), data,
+ { }
+ );
+ g2 = new Dygraph(
+ document.getElementById("chart2"), data,
+ {
+ showRangeSelector: true
+ }
+ );
+ </script>
+</body>
+</html>