about summary refs log tree commit diff
path: root/wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js
diff options
context:
space:
mode:
authorZachary Sloan2013-01-09 14:58:57 -0600
committerZachary Sloan2013-01-09 14:58:57 -0600
commit1685d588ecfb13a1a5c0f5aa10018e7ddbab7244 (patch)
treefa50cc0be6461ff23367288f1280e6b66422c4df /wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js
parentf09f6ffa285ad0aa7280dbadaa4eb8f0686d329f (diff)
downloadgenenetwork2-1685d588ecfb13a1a5c0f5aa10018e7ddbab7244.tar.gz
jqplot added
Diffstat (limited to 'wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js')
-rw-r--r--wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js865
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