diff options
author | Zachary Sloan | 2013-01-11 23:59:41 +0000 |
---|---|---|
committer | Zachary Sloan | 2013-01-11 23:59:41 +0000 |
commit | 2b2970d167c5b555e0e0ad0b34b72f817c1fac91 (patch) | |
tree | 36fa8c708138fff03593e0f50cc933bcb62b5592 /wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js | |
parent | 1db9237a05fd27c80dc963db9916072594156198 (diff) | |
parent | d39b691994a395c45fa242de6d64d12a5470af10 (diff) | |
download | genenetwork2-2b2970d167c5b555e0e0ad0b34b72f817c1fac91.tar.gz |
Merge branch 'flask' of http://github.com/zsloan/genenetwork
Diffstat (limited to 'wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js')
-rw-r--r-- | wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js | 865 |
1 files changed, 865 insertions, 0 deletions
diff --git a/wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js b/wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js new file mode 100644 index 00000000..03766206 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js @@ -0,0 +1,865 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.4 + * Revision: 1121 + * + * Copyright (c) 2009-2012 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + var objCounter = 0; + // class: $.jqplot.CanvasOverlay + $.jqplot.CanvasOverlay = function(opts){ + var options = opts || {}; + this.options = { + show: $.jqplot.config.enablePlugins, + deferDraw: false + }; + // prop: objects + this.objects = []; + this.objectNames = []; + this.canvas = null; + this.markerRenderer = new $.jqplot.MarkerRenderer({style:'line'}); + this.markerRenderer.init(); + this.highlightObjectIndex = null; + if (options.objects) { + var objs = options.objects, + obj; + for (var i=0; i<objs.length; i++) { + obj = objs[i]; + for (var n in obj) { + switch (n) { + case 'line': + this.addLine(obj[n]); + break; + case 'horizontalLine': + this.addHorizontalLine(obj[n]); + break; + case 'dashedHorizontalLine': + this.addDashedHorizontalLine(obj[n]); + break; + case 'verticalLine': + this.addVerticalLine(obj[n]); + break; + case 'dashedVerticalLine': + this.addDashedVerticalLine(obj[n]); + break; + default: + break; + } + } + } + } + $.extend(true, this.options, options); + }; + + // called with scope of a plot object + $.jqplot.CanvasOverlay.postPlotInit = function (target, data, opts) { + var options = opts || {}; + // add a canvasOverlay attribute to the plot + this.plugins.canvasOverlay = new $.jqplot.CanvasOverlay(options.canvasOverlay); + }; + + + function LineBase() { + this.uid = null; + this.type = null; + this.gridStart = null; + this.gridStop = null; + this.tooltipWidthFactor = 0; + this.options = { + // prop: name + // Optional name for the overlay object. + // Can be later used to retrieve the object by name. + name: null, + // prop: show + // true to show (draw), false to not draw. + show: true, + // prop: lineWidth + // Width of the line. + lineWidth: 2, + // prop: lineCap + // Type of ending placed on the line ['round', 'butt', 'square'] + lineCap: 'round', + // prop: color + // color of the line + color: '#666666', + // prop: shadow + // wether or not to draw a shadow on the line + shadow: true, + // prop: shadowAngle + // Shadow angle in degrees + shadowAngle: 45, + // prop: shadowOffset + // Shadow offset from line in pixels + shadowOffset: 1, + // prop: shadowDepth + // Number of times shadow is stroked, each stroke offset shadowOffset from the last. + shadowDepth: 3, + // prop: shadowAlpha + // Alpha channel transparency of shadow. 0 = transparent. + shadowAlpha: '0.07', + // prop: xaxis + // X axis to use for positioning/scaling the line. + xaxis: 'xaxis', + // prop: yaxis + // Y axis to use for positioning/scaling the line. + yaxis: 'yaxis', + // prop: showTooltip + // Show a tooltip with data point values. + showTooltip: false, + // prop: showTooltipPrecision + // Controls how close to line cursor must be to show tooltip. + // Higher number = closer to line, lower number = farther from line. + // 1.0 = cursor must be over line. + showTooltipPrecision: 0.6, + // prop: tooltipLocation + // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' + tooltipLocation: 'nw', + // prop: fadeTooltip + // true = fade in/out tooltip, flase = show/hide tooltip + fadeTooltip: true, + // prop: tooltipFadeSpeed + // 'slow', 'def', 'fast', or number of milliseconds. + tooltipFadeSpeed: "fast", + // prop: tooltipOffset + // Pixel offset of tooltip from the highlight. + tooltipOffset: 4, + // prop: tooltipFormatString + // Format string passed the x and y values of the cursor on the line. + // e.g., 'Dogs: %.2f, Cats: %d'. + tooltipFormatString: '%d, %d' + }; + } + + /** + * Class: Line + * A straight line. + */ + function Line(options) { + LineBase.call(this); + this.type = 'line'; + var opts = { + // prop: start + // [x, y] coordinates for the start of the line. + start: [], + // prop: stop + // [x, y] coordinates for the end of the line. + stop: [] + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + Line.prototype = new LineBase(); + Line.prototype.constructor = Line; + + + /** + * Class: HorizontalLine + * A straight horizontal line. + */ + function HorizontalLine(options) { + LineBase.call(this); + this.type = 'horizontalLine'; + var opts = { + // prop: y + // y value to position the line + y: null, + // prop: xmin + // x value for the start of the line, null to scale to axis min. + xmin: null, + // prop: xmax + // x value for the end of the line, null to scale to axis max. + xmax: null, + // prop xOffset + // offset ends of the line inside the grid. Number + xOffset: '6px', // number or string. Number interpreted as units, string as pixels. + xminOffset: null, + xmaxOffset: null + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + HorizontalLine.prototype = new LineBase(); + HorizontalLine.prototype.constructor = HorizontalLine; + + + /** + * Class: DashedHorizontalLine + * A straight dashed horizontal line. + */ + function DashedHorizontalLine(options) { + LineBase.call(this); + this.type = 'dashedHorizontalLine'; + var opts = { + y: null, + xmin: null, + xmax: null, + xOffset: '6px', // number or string. Number interpreted as units, string as pixels. + xminOffset: null, + xmaxOffset: null, + // prop: dashPattern + // Array of line, space settings in pixels. + // Default is 8 pixel of line, 8 pixel of space. + // Note, limit to a 2 element array b/c of bug with higher order arrays. + dashPattern: [8,8] + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + DashedHorizontalLine.prototype = new LineBase(); + DashedHorizontalLine.prototype.constructor = DashedHorizontalLine; + + + /** + * Class: VerticalLine + * A straight vertical line. + */ + function VerticalLine(options) { + LineBase.call(this); + this.type = 'verticalLine'; + var opts = { + x: null, + ymin: null, + ymax: null, + yOffset: '6px', // number or string. Number interpreted as units, string as pixels. + yminOffset: null, + ymaxOffset: null + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + VerticalLine.prototype = new LineBase(); + VerticalLine.prototype.constructor = VerticalLine; + + + /** + * Class: DashedVerticalLine + * A straight dashed vertical line. + */ + function DashedVerticalLine(options) { + LineBase.call(this); + this.type = 'dashedVerticalLine'; + this.start = null; + this.stop = null; + var opts = { + x: null, + ymin: null, + ymax: null, + yOffset: '6px', // number or string. Number interpreted as units, string as pixels. + yminOffset: null, + ymaxOffset: null, + // prop: dashPattern + // Array of line, space settings in pixels. + // Default is 8 pixel of line, 8 pixel of space. + // Note, limit to a 2 element array b/c of bug with higher order arrays. + dashPattern: [8,8] + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + DashedVerticalLine.prototype = new LineBase(); + DashedVerticalLine.prototype.constructor = DashedVerticalLine; + + $.jqplot.CanvasOverlay.prototype.addLine = function(opts) { + var line = new Line(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addHorizontalLine = function(opts) { + var line = new HorizontalLine(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine = function(opts) { + var line = new DashedHorizontalLine(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addVerticalLine = function(opts) { + var line = new VerticalLine(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addDashedVerticalLine = function(opts) { + var line = new DashedVerticalLine(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.removeObject = function(idx) { + // check if integer, remove by index + if ($.type(idx) == 'number') { + this.objects.splice(idx, 1); + this.objectNames.splice(idx, 1); + } + // if string, remove by name + else { + var id = $.inArray(idx, this.objectNames); + if (id != -1) { + this.objects.splice(id, 1); + this.objectNames.splice(id, 1); + } + } + }; + + $.jqplot.CanvasOverlay.prototype.getObject = function(idx) { + // check if integer, remove by index + if ($.type(idx) == 'number') { + return this.objects[idx]; + } + // if string, remove by name + else { + var id = $.inArray(idx, this.objectNames); + if (id != -1) { + return this.objects[id]; + } + } + }; + + // Set get as alias for getObject. + $.jqplot.CanvasOverlay.prototype.get = $.jqplot.CanvasOverlay.prototype.getObject; + + $.jqplot.CanvasOverlay.prototype.clear = function(plot) { + this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight()); + }; + + $.jqplot.CanvasOverlay.prototype.draw = function(plot) { + var obj, + objs = this.objects, + mr = this.markerRenderer, + start, + stop; + if (this.options.show) { + this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight()); + for (var k=0; k<objs.length; k++) { + obj = objs[k]; + var opts = $.extend(true, {}, obj.options); + if (obj.options.show) { + // style and shadow properties should be set before + // every draw of marker renderer. + mr.shadow = obj.options.shadow; + obj.tooltipWidthFactor = obj.options.lineWidth / obj.options.showTooltipPrecision; + switch (obj.type) { + case 'line': + // style and shadow properties should be set before + // every draw of marker renderer. + mr.style = 'line'; + opts.closePath = false; + start = [plot.axes[obj.options.xaxis].series_u2p(obj.options.start[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.start[1])]; + stop = [plot.axes[obj.options.xaxis].series_u2p(obj.options.stop[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.stop[1])]; + obj.gridStart = start; + obj.gridStop = stop; + mr.draw(start, stop, this.canvas._ctx, opts); + break; + case 'horizontalLine': + + // style and shadow properties should be set before + // every draw of marker renderer. + if (obj.options.y != null) { + mr.style = 'line'; + opts.closePath = false; + var xaxis = plot.axes[obj.options.xaxis], + xstart, + xstop, + y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y), + xminoff = obj.options.xminOffset || obj.options.xOffset, + xmaxoff = obj.options.xmaxOffset || obj.options.xOffset; + if (obj.options.xmin != null) { + xstart = xaxis.series_u2p(obj.options.xmin); + } + else if (xminoff != null) { + if ($.type(xminoff) == "number") { + xstart = xaxis.series_u2p(xaxis.min + xminoff); + } + else if ($.type(xminoff) == "string") { + xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff); + } + } + if (obj.options.xmax != null) { + xstop = xaxis.series_u2p(obj.options.xmax); + } + else if (xmaxoff != null) { + if ($.type(xmaxoff) == "number") { + xstop = xaxis.series_u2p(xaxis.max - xmaxoff); + } + else if ($.type(xmaxoff) == "string") { + xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff); + } + } + if (xstop != null && xstart != null) { + obj.gridStart = [xstart, y]; + obj.gridStop = [xstop, y]; + mr.draw([xstart, y], [xstop, y], this.canvas._ctx, opts); + } + } + break; + + case 'dashedHorizontalLine': + + var dashPat = obj.options.dashPattern; + var dashPatLen = 0; + for (var i=0; i<dashPat.length; i++) { + dashPatLen += dashPat[i]; + } + + // style and shadow properties should be set before + // every draw of marker renderer. + if (obj.options.y != null) { + mr.style = 'line'; + opts.closePath = false; + var xaxis = plot.axes[obj.options.xaxis], + xstart, + xstop, + y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y), + xminoff = obj.options.xminOffset || obj.options.xOffset, + xmaxoff = obj.options.xmaxOffset || obj.options.xOffset; + if (obj.options.xmin != null) { + xstart = xaxis.series_u2p(obj.options.xmin); + } + else if (xminoff != null) { + if ($.type(xminoff) == "number") { + xstart = xaxis.series_u2p(xaxis.min + xminoff); + } + else if ($.type(xminoff) == "string") { + xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff); + } + } + if (obj.options.xmax != null) { + xstop = xaxis.series_u2p(obj.options.xmax); + } + else if (xmaxoff != null) { + if ($.type(xmaxoff) == "number") { + xstop = xaxis.series_u2p(xaxis.max - xmaxoff); + } + else if ($.type(xmaxoff) == "string") { + xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff); + } + } + if (xstop != null && xstart != null) { + obj.gridStart = [xstart, y]; + obj.gridStop = [xstop, y]; + var numDash = Math.ceil((xstop - xstart)/dashPatLen); + var b=xstart, e; + for (var i=0; i<numDash; i++) { + for (var j=0; j<dashPat.length; j+=2) { + e = b+dashPat[j]; + mr.draw([b, y], [e, y], this.canvas._ctx, opts); + b += dashPat[j]; + if (j < dashPat.length-1) { + b += dashPat[j+1]; + } + } + } + } + } + break; + + case 'verticalLine': + + // style and shadow properties should be set before + // every draw of marker renderer. + if (obj.options.x != null) { + mr.style = 'line'; + opts.closePath = false; + var yaxis = plot.axes[obj.options.yaxis], + ystart, + ystop, + x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x), + yminoff = obj.options.yminOffset || obj.options.yOffset, + ymaxoff = obj.options.ymaxOffset || obj.options.yOffset; + if (obj.options.ymin != null) { + ystart = yaxis.series_u2p(obj.options.ymin); + } + else if (yminoff != null) { + if ($.type(yminoff) == "number") { + ystart = yaxis.series_u2p(yaxis.min - yminoff); + } + else if ($.type(yminoff) == "string") { + ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff); + } + } + if (obj.options.ymax != null) { + ystop = yaxis.series_u2p(obj.options.ymax); + } + else if (ymaxoff != null) { + if ($.type(ymaxoff) == "number") { + ystop = yaxis.series_u2p(yaxis.max + ymaxoff); + } + else if ($.type(ymaxoff) == "string") { + ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff); + } + } + if (ystop != null && ystart != null) { + obj.gridStart = [x, ystart]; + obj.gridStop = [x, ystop]; + mr.draw([x, ystart], [x, ystop], this.canvas._ctx, opts); + } + } + break; + + case 'dashedVerticalLine': + + var dashPat = obj.options.dashPattern; + var dashPatLen = 0; + for (var i=0; i<dashPat.length; i++) { + dashPatLen += dashPat[i]; + } + + // style and shadow properties should be set before + // every draw of marker renderer. + if (obj.options.x != null) { + mr.style = 'line'; + opts.closePath = false; + var yaxis = plot.axes[obj.options.yaxis], + ystart, + ystop, + x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x), + yminoff = obj.options.yminOffset || obj.options.yOffset, + ymaxoff = obj.options.ymaxOffset || obj.options.yOffset; + if (obj.options.ymin != null) { + ystart = yaxis.series_u2p(obj.options.ymin); + } + else if (yminoff != null) { + if ($.type(yminoff) == "number") { + ystart = yaxis.series_u2p(yaxis.min - yminoff); + } + else if ($.type(yminoff) == "string") { + ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff); + } + } + if (obj.options.ymax != null) { + ystop = yaxis.series_u2p(obj.options.ymax); + } + else if (ymaxoff != null) { + if ($.type(ymaxoff) == "number") { + ystop = yaxis.series_u2p(yaxis.max + ymaxoff); + } + else if ($.type(ymaxoff) == "string") { + ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff); + } + } + + + if (ystop != null && ystart != null) { + obj.gridStart = [x, ystart]; + obj.gridStop = [x, ystop]; + var numDash = Math.ceil((ystart - ystop)/dashPatLen); + var firstDashAdjust = ((numDash * dashPatLen) - (ystart - ystop))/2.0; + var b=ystart, e, bs, es; + for (var i=0; i<numDash; i++) { + for (var j=0; j<dashPat.length; j+=2) { + e = b - dashPat[j]; + if (e < ystop) { + e = ystop; + } + if (b < ystop) { + b = ystop; + } + // es = e; + // if (i == 0) { + // es += firstDashAdjust; + // } + mr.draw([x, b], [x, e], this.canvas._ctx, opts); + b -= dashPat[j]; + if (j < dashPat.length-1) { + b -= dashPat[j+1]; + } + } + } + } + } + break; + + default: + break; + } + } + } + } + }; + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + $.jqplot.CanvasOverlay.postPlotDraw = function() { + var co = this.plugins.canvasOverlay; + // Memory Leaks patch + if (co && co.highlightCanvas) { + co.highlightCanvas.resetCanvas(); + co.highlightCanvas = null; + } + co.canvas = new $.jqplot.GenericCanvas(); + + this.eventCanvas._elem.before(co.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions, this)); + co.canvas.setContext(); + if (!co.deferDraw) { + co.draw(this); + } + + var elem = document.createElement('div'); + co._tooltipElem = $(elem); + elem = null; + co._tooltipElem.addClass('jqplot-canvasOverlay-tooltip'); + co._tooltipElem.css({position:'absolute', display:'none'}); + + this.eventCanvas._elem.before(co._tooltipElem); + this.eventCanvas._elem.bind('mouseleave', { elem: co._tooltipElem }, function (ev) { ev.data.elem.hide(); }); + + var co = null; + }; + + + function showTooltip(plot, obj, gridpos, datapos) { + var co = plot.plugins.canvasOverlay; + var elem = co._tooltipElem; + + var opts = obj.options, x, y; + + elem.html($.jqplot.sprintf(opts.tooltipFormatString, datapos[0], datapos[1])); + + switch (opts.tooltipLocation) { + case 'nw': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true); + break; + case 'n': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2; + y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true); + break; + case 'ne': + x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true); + break; + case 'e': + x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2; + break; + case 'se': + x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset; + break; + case 's': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2; + y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset; + break; + case 'sw': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset; + break; + case 'w': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2; + break; + default: // same as 'nw' + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true); + break; + } + + elem.css('left', x); + elem.css('top', y); + if (opts.fadeTooltip) { + // Fix for stacked up animations. Thnanks Trevor! + elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed); + } + else { + elem.show(); + } + elem = null; + } + + + function isNearLine(point, lstart, lstop, width) { + // r is point to test, p and q are end points. + var rx = point[0]; + var ry = point[1]; + var px = Math.round(lstop[0]); + var py = Math.round(lstop[1]); + var qx = Math.round(lstart[0]); + var qy = Math.round(lstart[1]); + + var l = Math.sqrt(Math.pow(px-qx, 2) + Math.pow(py-qy, 2)); + + // scale error term by length of line. + var eps = width*l; + var res = Math.abs((qx-px) * (ry-py) - (qy-py) * (rx-px)); + var ret = (res < eps) ? true : false; + return ret; + } + + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + var co = plot.plugins.canvasOverlay; + var objs = co.objects; + var l = objs.length; + var obj, haveHighlight=false; + var elem; + for (var i=0; i<l; i++) { + obj = objs[i]; + if (obj.options.showTooltip) { + var n = isNearLine([gridpos.x, gridpos.y], obj.gridStart, obj.gridStop, obj.tooltipWidthFactor); + datapos = [plot.axes[obj.options.xaxis].series_p2u(gridpos.x), plot.axes[obj.options.yaxis].series_p2u(gridpos.y)]; + + // cases: + // near line, no highlighting + // near line, highliting on this line + // near line, highlighting another line + // not near any line, highlighting + // not near any line, no highlighting + + // near line, not currently highlighting + if (n && co.highlightObjectIndex == null) { + switch (obj.type) { + case 'line': + showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos); + break; + + case 'horizontalLine': + case 'dashedHorizontalLine': + showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]); + break; + + case 'verticalLine': + case 'dashedVerticalLine': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + default: + break; + } + co.highlightObjectIndex = i; + haveHighlight = true; + break; + } + + // near line, highlighting another line. + else if (n && co.highlightObjectIndex !== i) { + // turn off tooltip. + elem = co._tooltipElem; + if (obj.fadeTooltip) { + elem.fadeOut(obj.tooltipFadeSpeed); + } + else { + elem.hide(); + } + + // turn on right tooltip. + switch (obj.type) { + case 'line': + showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos); + break; + + case 'horizontalLine': + case 'dashedHorizontalLine': + showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]); + break; + + case 'verticalLine': + case 'dashedVerticalLine': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + default: + break; + } + + co.highlightObjectIndex = i; + haveHighlight = true; + break; + } + + // near line, already highlighting this line, update + else if (n) { + switch (obj.type) { + case 'line': + showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos); + break; + + case 'horizontalLine': + case 'dashedHorizontalLine': + showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]); + break; + + case 'verticalLine': + case 'dashedVerticalLine': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + default: + break; + } + + haveHighlight = true; + break; + } + } + } + + // check if we are highlighting and not near a line, turn it off. + if (!haveHighlight && co.highlightObjectIndex !== null) { + elem = co._tooltipElem; + obj = co.getObject(co.highlightObjectIndex); + if (obj.fadeTooltip) { + elem.fadeOut(obj.tooltipFadeSpeed); + } + else { + elem.hide(); + } + co.highlightObjectIndex = null; + } + } + + $.jqplot.postInitHooks.push($.jqplot.CanvasOverlay.postPlotInit); + $.jqplot.postDrawHooks.push($.jqplot.CanvasOverlay.postPlotDraw); + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]); + +})(jQuery);
\ No newline at end of file |