X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=dygraph-utils.js;h=63fc1e0a433a36d0a6845647d9282c9e76c14aee;hb=2909d9ae3cf695f2375a328497b934df85cf53a9;hp=04a5d3a54c53cdd78ab86b2afc03632ede625990;hpb=b7a1dc2288585edbeff4591e81e6a0efd2893932;p=dygraphs.git diff --git a/dygraph-utils.js b/dygraph-utils.js index 04a5d3a..63fc1e0 100644 --- a/dygraph-utils.js +++ b/dygraph-utils.js @@ -158,9 +158,9 @@ Dygraph.getContext = function(canvas) { /** * Add an event handler. This smooths a difference between IE and the rest of * the world. - * @param { !Element } elem The element to add the event to. - * @param { string } type The type of the event, e.g. 'click' or 'mousemove'. - * @param { function(Event):(boolean|undefined) } fn The function to call + * @param {!Node} elem The element to add the event to. + * @param {string} type The type of the event, e.g. 'click' or 'mousemove'. + * @param {function(Event):(boolean|undefined)} fn The function to call * on the event. The function takes one parameter: the event object. * @private */ @@ -177,9 +177,9 @@ Dygraph.addEvent = function addEvent(elem, type, fn) { * Add an event handler. This event handler is kept until the graph is * destroyed with a call to graph.destroy(). * - * @param { !Element } elem The element to add the event to. - * @param { string } type The type of the event, e.g. 'click' or 'mousemove'. - * @param { function(Event):(boolean|undefined) } fn The function to call + * @param {!Node} elem The element to add the event to. + * @param {string} type The type of the event, e.g. 'click' or 'mousemove'. + * @param {function(Event):(boolean|undefined)} fn The function to call * on the event. The function takes one parameter: the event object. * @private */ @@ -191,7 +191,7 @@ Dygraph.prototype.addAndTrackEvent = function(elem, type, fn) { /** * Remove an event handler. This smooths a difference between IE and the rest * of the world. - * @param {!Element} elem The element to add the event to. + * @param {!Node} elem The element to remove the event from. * @param {string} type The type of the event, e.g. 'click' or 'mousemove'. * @param {function(Event):(boolean|undefined)} fn The function to call * on the event. The function takes one parameter: the event object. @@ -227,7 +227,7 @@ Dygraph.prototype.removeTrackedEvents_ = function() { * browser actions, e.g. highlighting text on a double-click. * Based on the article at * http://www.switchonthecode.com/tutorials/javascript-tutorial-the-scroll-wheel - * @param { !Event } e The event whose normal behavior should be canceled. + * @param {!Event} e The event whose normal behavior should be canceled. * @private */ Dygraph.cancelEvent = function(e) { @@ -374,6 +374,28 @@ Dygraph.pageY = function(e) { }; /** + * Converts page the x-coordinate of the event to pixel x-coordinates on the + * canvas (i.e. DOM Coords). + * @param {!Event} e Drag event. + * @param {!DygraphInteractionContext} context Interaction context object. + * @return {number} The amount by which the drag has moved to the right. + */ +Dygraph.dragGetX_ = function(e, context) { + return Dygraph.pageX(e) - context.px; +}; + +/** + * Converts page the y-coordinate of the event to pixel y-coordinates on the + * canvas (i.e. DOM Coords). + * @param {!Event} e Drag event. + * @param {!DygraphInteractionContext} context Interaction context object. + * @return {number} The amount by which the drag has moved down. + */ +Dygraph.dragGetY_ = function(e, context) { + return Dygraph.pageY(e) - context.py; +}; + +/** * This returns true unless the parameter is 0, null, undefined or NaN. * TODO(danvk): rename this function to something like 'isNonZeroNan'. * @@ -386,18 +408,18 @@ Dygraph.isOK = function(x) { }; /** - * @param { {x:?number,y:?number,yval:?number} } p The point to consider, valid + * @param {{x:?number,y:?number,yval:?number}} p The point to consider, valid * points are {x, y} objects - * @param { boolean } allowNaNY Treat point with y=NaN as valid - * @return { boolean } Whether the point has numeric x and y. + * @param {boolean=} opt_allowNaNY Treat point with y=NaN as valid + * @return {boolean} Whether the point has numeric x and y. * @private */ -Dygraph.isValidPoint = function(p, allowNaNY) { +Dygraph.isValidPoint = function(p, opt_allowNaNY) { if (!p) return false; // null or undefined object if (p.yval === null) return false; // missing point if (p.x === null || p.x === undefined) return false; if (p.y === null || p.y === undefined) return false; - if (isNaN(p.x) || (!allowNaNY && isNaN(p.y))) return false; + if (isNaN(p.x) || (!opt_allowNaNY && isNaN(p.y))) return false; return true; }; @@ -684,7 +706,7 @@ Dygraph.updateDeep = function (self, o) { }; /** - * @param {Object} o + * @param {*} o * @return {boolean} * @private */ @@ -754,6 +776,30 @@ Dygraph.createCanvas = function() { }; /** + * Returns the context's pixel ratio, which is the ratio between the device + * pixel ratio and the backing store ratio. Typically this is 1 for conventional + * displays, and > 1 for HiDPI displays (such as the Retina MBP). + * See http://www.html5rocks.com/en/tutorials/canvas/hidpi/ for more details. + * + * @param {!CanvasRenderingContext2D} context The canvas's 2d context. + * @return {number} The ratio of the device pixel ratio and the backing store + * ratio for the specified context. + */ +Dygraph.getContextPixelRatio = function(context) { + try { + var devicePixelRatio = window.devicePixelRatio || 1, + backingStoreRatio = context.webkitBackingStorePixelRatio || + context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || + context.oBackingStorePixelRatio || + context.backingStorePixelRatio || 1; + return devicePixelRatio / backingStoreRatio; + } catch (e) { + return 1; + } +}; + +/** * Checks whether the user is on an Android browser. * Android does not fully support the tag, e.g. w/r/t/ clipping. * @return {boolean} @@ -1053,8 +1099,9 @@ 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), + var pos = Dygraph.findPos(iframe), + x = pos.x, + y = pos.y, width = iframe.offsetWidth, height = iframe.offsetHeight; @@ -1180,7 +1227,7 @@ Dygraph.toRGB_ = function(colorStr) { div.style.backgroundColor = colorStr; div.style.visibility = 'hidden'; document.body.appendChild(div); - var rgbStr = window.getComputedStyle(div).backgroundColor; + var rgbStr = window.getComputedStyle(div, null).backgroundColor; document.body.removeChild(div); var bits = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(rgbStr); return { @@ -1189,3 +1236,56 @@ Dygraph.toRGB_ = function(colorStr) { b: parseInt(bits[3], 10) }; }; + +/** + * Checks whether the browser supports the <canvas> tag. + * @param {HTMLCanvasElement=} opt_canvasElement Pass a canvas element as an + * optimization if you have one. + * @return {boolean} Whether the browser supports canvas. + */ +Dygraph.isCanvasSupported = function(opt_canvasElement) { + var canvas; + try { + canvas = opt_canvasElement || document.createElement("canvas"); + canvas.getContext("2d"); + } + catch (e) { + var ie = navigator.appVersion.match(/MSIE (\d\.\d)/); + var opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1); + if ((!ie) || (ie[1] < 6) || (opera)) + return false; + return true; + } + return true; +}; + +/** + * Parses the value as a floating point number. This is like the parseFloat() + * built-in, but with a few differences: + * - the empty string is parsed as null, rather than NaN. + * - if the string cannot be parsed at all, an error is logged. + * If the string can't be parsed, this method returns null. + * @param {string} x The string to be parsed + * @param {number=} opt_line_no The line number from which the string comes. + * @param {string=} opt_line The text of the line from which the string comes. + */ +Dygraph.parseFloat_ = function(x, opt_line_no, opt_line) { + var val = parseFloat(x); + if (!isNaN(val)) return val; + + // Try to figure out what happeend. + // If the value is the empty string, parse it as null. + if (/^ *$/.test(x)) return null; + + // If it was actually "NaN", return it as NaN. + if (/^ *nan *$/i.test(x)) return NaN; + + // Looks like a parsing error. + var msg = "Unable to parse '" + x + "' as a number"; + if (opt_line !== undefined && opt_line_no !== undefined) { + msg += " on line " + (1+(opt_line_no||0)) + " ('" + opt_line + "') of CSV."; + } + Dygraph.error(msg); + + return null; +};