/* 
 | 
 * jquery.flot.tooltip 
 | 
 *  
 | 
 * description: easy-to-use tooltips for Flot charts 
 | 
 * version: 0.8.7 
 | 
 * authors: Krzysztof Urbas @krzysu [myviews.pl],Evan Steinkerchner @Roundaround 
 | 
 * website: https://github.com/krzysu/flot.tooltip 
 | 
 *  
 | 
 * build on 2016-03-15 
 | 
 * released under MIT License, 2012 
 | 
*/  
 | 
(function ($) { 
 | 
    // plugin options, default values 
 | 
    var defaultOptions = { 
 | 
        tooltip: { 
 | 
            show: false, 
 | 
            cssClass: "flotTip", 
 | 
            content: "%s | X: %x | Y: %y", 
 | 
            // allowed templates are: 
 | 
            // %s -> series label, 
 | 
            // %c -> series color, 
 | 
            // %lx -> x axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels), 
 | 
            // %ly -> y axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels), 
 | 
            // %x -> X value, 
 | 
            // %y -> Y value, 
 | 
            // %x.2 -> precision of X value, 
 | 
            // %p -> percent 
 | 
        // %n -> value (not percent) of pie chart 
 | 
            xDateFormat: null, 
 | 
            yDateFormat: null, 
 | 
            monthNames: null, 
 | 
            dayNames: null, 
 | 
            shifts: { 
 | 
                x: 10, 
 | 
                y: 20 
 | 
            }, 
 | 
            defaultTheme: true, 
 | 
            snap: true, 
 | 
            lines: false, 
 | 
            clickTips: false, 
 | 
  
 | 
            // callbacks 
 | 
            onHover: function (flotItem, $tooltipEl) {}, 
 | 
  
 | 
            $compat: false 
 | 
        } 
 | 
    }; 
 | 
  
 | 
    // dummy default options object for legacy code (<0.8.5) - is deleted later 
 | 
    defaultOptions.tooltipOpts = defaultOptions.tooltip; 
 | 
  
 | 
    // object 
 | 
    var FlotTooltip = function (plot) { 
 | 
        // variables 
 | 
        this.tipPosition = {x: 0, y: 0}; 
 | 
  
 | 
        this.init(plot); 
 | 
    }; 
 | 
  
 | 
    // main plugin function 
 | 
    FlotTooltip.prototype.init = function (plot) { 
 | 
        var that = this; 
 | 
  
 | 
        // detect other flot plugins 
 | 
        var plotPluginsLength = $.plot.plugins.length; 
 | 
        this.plotPlugins = []; 
 | 
  
 | 
        if (plotPluginsLength) { 
 | 
            for (var p = 0; p < plotPluginsLength; p++) { 
 | 
                this.plotPlugins.push($.plot.plugins[p].name); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        plot.hooks.bindEvents.push(function (plot, eventHolder) { 
 | 
  
 | 
            // get plot options 
 | 
            that.plotOptions = plot.getOptions(); 
 | 
  
 | 
            // for legacy (<0.8.5) implementations 
 | 
            if (typeof(that.plotOptions.tooltip) === 'boolean') { 
 | 
                that.plotOptions.tooltipOpts.show = that.plotOptions.tooltip; 
 | 
                that.plotOptions.tooltip = that.plotOptions.tooltipOpts; 
 | 
                delete that.plotOptions.tooltipOpts; 
 | 
            } 
 | 
  
 | 
            // if not enabled return 
 | 
            if (that.plotOptions.tooltip.show === false || typeof that.plotOptions.tooltip.show === 'undefined') return; 
 | 
  
 | 
            // shortcut to access tooltip options 
 | 
            that.tooltipOptions = that.plotOptions.tooltip; 
 | 
  
 | 
            if (that.tooltipOptions.$compat) { 
 | 
                that.wfunc = 'width'; 
 | 
                that.hfunc = 'height'; 
 | 
            } else { 
 | 
                that.wfunc = 'innerWidth'; 
 | 
                that.hfunc = 'innerHeight'; 
 | 
            } 
 | 
  
 | 
            // create tooltip DOM element 
 | 
            var $tip = that.getDomElement(); 
 | 
  
 | 
            // bind event 
 | 
            $( plot.getPlaceholder() ).bind("plothover", plothover); 
 | 
            if (that.tooltipOptions.clickTips) { 
 | 
                $( plot.getPlaceholder() ).bind("plotclick", plotclick); 
 | 
            } 
 | 
            that.clickmode = false; 
 | 
  
 | 
            $(eventHolder).bind('mousemove', mouseMove); 
 | 
        }); 
 | 
  
 | 
        plot.hooks.shutdown.push(function (plot, eventHolder){ 
 | 
            $(plot.getPlaceholder()).unbind("plothover", plothover); 
 | 
            $(plot.getPlaceholder()).unbind("plotclick", plotclick); 
 | 
            plot.removeTooltip(); 
 | 
            $(eventHolder).unbind("mousemove", mouseMove); 
 | 
        }); 
 | 
  
 | 
        function mouseMove(e){ 
 | 
            var pos = {}; 
 | 
            pos.x = e.pageX; 
 | 
            pos.y = e.pageY; 
 | 
            plot.setTooltipPosition(pos); 
 | 
        } 
 | 
  
 | 
        /** 
 | 
         *  open the tooltip (if not already open) and freeze it on the current position till the next click 
 | 
         */ 
 | 
        function plotclick(event, pos, item) { 
 | 
            if (! that.clickmode) { 
 | 
                // it is the click activating the clicktip 
 | 
                plothover(event, pos, item); 
 | 
                if (that.getDomElement().is(":visible")) { 
 | 
                    $(plot.getPlaceholder()).unbind("plothover", plothover); 
 | 
                    that.clickmode = true; 
 | 
                } 
 | 
            } else { 
 | 
                // it is the click deactivating the clicktip 
 | 
                $( plot.getPlaceholder() ).bind("plothover", plothover); 
 | 
                plot.hideTooltip(); 
 | 
                that.clickmode = false; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        function plothover(event, pos, item) { 
 | 
            // Simple distance formula. 
 | 
            var lineDistance = function (p1x, p1y, p2x, p2y) { 
 | 
                return Math.sqrt((p2x - p1x) * (p2x - p1x) + (p2y - p1y) * (p2y - p1y)); 
 | 
            }; 
 | 
  
 | 
            // Here is some voodoo magic for determining the distance to a line form a given point {x, y}. 
 | 
            var dotLineLength = function (x, y, x0, y0, x1, y1, o) { 
 | 
                if (o && !(o = 
 | 
                    function (x, y, x0, y0, x1, y1) { 
 | 
                        if (typeof x0 !== 'undefined') return { x: x0, y: y }; 
 | 
                        else if (typeof y0 !== 'undefined') return { x: x, y: y0 }; 
 | 
  
 | 
                        var left, 
 | 
                            tg = -1 / ((y1 - y0) / (x1 - x0)); 
 | 
  
 | 
                        return { 
 | 
                            x: left = (x1 * (x * tg - y + y0) + x0 * (x * -tg + y - y1)) / (tg * (x1 - x0) + y0 - y1), 
 | 
                            y: tg * left - tg * x + y 
 | 
                        }; 
 | 
                    } (x, y, x0, y0, x1, y1), 
 | 
                    o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1)) 
 | 
                ) { 
 | 
                    var l1 = lineDistance(x, y, x0, y0), l2 = lineDistance(x, y, x1, y1); 
 | 
                    return l1 > l2 ? l2 : l1; 
 | 
                } else { 
 | 
                    var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1; 
 | 
                    return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b); 
 | 
                } 
 | 
            }; 
 | 
  
 | 
            if (item) { 
 | 
                plot.showTooltip(item, that.tooltipOptions.snap ? item : pos); 
 | 
            } else if (that.plotOptions.series.lines.show && that.tooltipOptions.lines === true) { 
 | 
                var maxDistance = that.plotOptions.grid.mouseActiveRadius; 
 | 
  
 | 
                var closestTrace = { 
 | 
                    distance: maxDistance + 1 
 | 
                }; 
 | 
  
 | 
                var ttPos = pos; 
 | 
  
 | 
                $.each(plot.getData(), function (i, series) { 
 | 
                    var xBeforeIndex = 0, 
 | 
                        xAfterIndex = -1; 
 | 
  
 | 
                    // Our search here assumes our data is sorted via the x-axis. 
 | 
                    // TODO: Improve efficiency somehow - search smaller sets of data. 
 | 
                    for (var j = 1; j < series.data.length; j++) { 
 | 
                        if (series.data[j - 1][0] <= pos.x && series.data[j][0] >= pos.x) { 
 | 
                            xBeforeIndex = j - 1; 
 | 
                            xAfterIndex = j; 
 | 
                        } 
 | 
                    } 
 | 
  
 | 
                    if (xAfterIndex === -1) { 
 | 
                        plot.hideTooltip(); 
 | 
                        return; 
 | 
                    } 
 | 
  
 | 
                    var pointPrev = { x: series.data[xBeforeIndex][0], y: series.data[xBeforeIndex][1] }, 
 | 
                        pointNext = { x: series.data[xAfterIndex][0], y: series.data[xAfterIndex][1] }; 
 | 
  
 | 
                    var distToLine = dotLineLength(series.xaxis.p2c(pos.x), series.yaxis.p2c(pos.y), series.xaxis.p2c(pointPrev.x), 
 | 
                        series.yaxis.p2c(pointPrev.y), series.xaxis.p2c(pointNext.x), series.yaxis.p2c(pointNext.y), false); 
 | 
  
 | 
                    if (distToLine < closestTrace.distance) { 
 | 
  
 | 
                        var closestIndex = lineDistance(pointPrev.x, pointPrev.y, pos.x, pos.y) < 
 | 
                            lineDistance(pos.x, pos.y, pointNext.x, pointNext.y) ? xBeforeIndex : xAfterIndex; 
 | 
  
 | 
                        var pointSize = series.datapoints.pointsize; 
 | 
  
 | 
                        // Calculate the point on the line vertically closest to our cursor. 
 | 
                        var pointOnLine = [ 
 | 
                            pos.x, 
 | 
                            pointPrev.y + ((pointNext.y - pointPrev.y) * ((pos.x - pointPrev.x) / (pointNext.x - pointPrev.x))) 
 | 
                        ]; 
 | 
  
 | 
                        var item = { 
 | 
                            datapoint: pointOnLine, 
 | 
                            dataIndex: closestIndex, 
 | 
                            series: series, 
 | 
                            seriesIndex: i 
 | 
                        }; 
 | 
  
 | 
                        closestTrace = { 
 | 
                            distance: distToLine, 
 | 
                            item: item 
 | 
                        }; 
 | 
  
 | 
                        if (that.tooltipOptions.snap) { 
 | 
                            ttPos = { 
 | 
                                pageX: series.xaxis.p2c(pointOnLine[0]), 
 | 
                                pageY: series.yaxis.p2c(pointOnLine[1]) 
 | 
                            }; 
 | 
                        } 
 | 
                    } 
 | 
                }); 
 | 
  
 | 
                if (closestTrace.distance < maxDistance + 1) 
 | 
                    plot.showTooltip(closestTrace.item, ttPos); 
 | 
                else 
 | 
                    plot.hideTooltip(); 
 | 
            } else { 
 | 
                plot.hideTooltip(); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        // Quick little function for setting the tooltip position. 
 | 
        plot.setTooltipPosition = function (pos) { 
 | 
            var $tip = that.getDomElement(); 
 | 
  
 | 
            var totalTipWidth = $tip.outerWidth() + that.tooltipOptions.shifts.x; 
 | 
            var totalTipHeight = $tip.outerHeight() + that.tooltipOptions.shifts.y; 
 | 
            if ((pos.x - $(window).scrollLeft()) > ($(window)[that.wfunc]() - totalTipWidth)) { 
 | 
                pos.x -= totalTipWidth; 
 | 
            } 
 | 
            if ((pos.y - $(window).scrollTop()) > ($(window)[that.hfunc]() - totalTipHeight)) { 
 | 
                pos.y -= totalTipHeight; 
 | 
            } 
 | 
  
 | 
        /*  
 | 
           The section applies the new positioning ONLY if pos.x and pos.y 
 | 
           are numbers. If they are undefined or not a number, use the last 
 | 
           known numerical position. This hack fixes a bug that kept pie  
 | 
           charts from keeping their tooltip positioning. 
 | 
         */ 
 | 
         
 | 
            if (isNaN(pos.x)) { 
 | 
        that.tipPosition.x = that.tipPosition.xPrev; 
 | 
        } 
 | 
        else { 
 | 
        that.tipPosition.x = pos.x; 
 | 
        that.tipPosition.xPrev = pos.x; 
 | 
        } 
 | 
        if (isNaN(pos.y)) { 
 | 
        that.tipPosition.y = that.tipPosition.yPrev; 
 | 
        } 
 | 
        else { 
 | 
        that.tipPosition.y = pos.y; 
 | 
        that.tipPosition.yPrev = pos.y; 
 | 
        } 
 | 
         
 | 
        }; 
 | 
  
 | 
        // Quick little function for showing the tooltip. 
 | 
        plot.showTooltip = function (target, position, targetPosition) { 
 | 
            var $tip = that.getDomElement(); 
 | 
  
 | 
            // convert tooltip content template to real tipText 
 | 
            var tipText = that.stringFormat(that.tooltipOptions.content, target); 
 | 
            if (tipText === '') 
 | 
                return; 
 | 
  
 | 
            $tip.html(tipText); 
 | 
            plot.setTooltipPosition({ x: position.pageX, y: position.pageY }); 
 | 
            $tip.css({ 
 | 
                left: that.tipPosition.x + that.tooltipOptions.shifts.x, 
 | 
                top: that.tipPosition.y + that.tooltipOptions.shifts.y 
 | 
            }).show(); 
 | 
  
 | 
            // run callback 
 | 
            if (typeof that.tooltipOptions.onHover === 'function') { 
 | 
                that.tooltipOptions.onHover(target, $tip); 
 | 
            } 
 | 
        }; 
 | 
  
 | 
        // Quick little function for hiding the tooltip. 
 | 
        plot.hideTooltip = function () { 
 | 
            that.getDomElement().hide().html(''); 
 | 
        }; 
 | 
  
 | 
        plot.removeTooltip = function() { 
 | 
            that.getDomElement().remove(); 
 | 
        }; 
 | 
    }; 
 | 
  
 | 
    /** 
 | 
     * get or create tooltip DOM element 
 | 
     * @return jQuery object 
 | 
     */ 
 | 
    FlotTooltip.prototype.getDomElement = function () { 
 | 
        var $tip = $('<div>'); 
 | 
        if (this.tooltipOptions && this.tooltipOptions.cssClass) { 
 | 
            $tip = $('.' + this.tooltipOptions.cssClass); 
 | 
  
 | 
            if( $tip.length === 0 ){ 
 | 
                $tip = $('<div />').addClass(this.tooltipOptions.cssClass); 
 | 
                $tip.appendTo('body').hide().css({position: 'absolute'}); 
 | 
     
 | 
                if(this.tooltipOptions.defaultTheme) { 
 | 
                    $tip.css({ 
 | 
                        'background': '#fff', 
 | 
                        'z-index': '1040', 
 | 
                        'padding': '0.4em 0.6em', 
 | 
                        'border-radius': '0.5em', 
 | 
                        'font-size': '0.8em', 
 | 
                        'border': '1px solid #111', 
 | 
                        'display': 'none', 
 | 
                        'white-space': 'nowrap' 
 | 
                    }); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
  
 | 
        return $tip; 
 | 
    }; 
 | 
  
 | 
    /** 
 | 
     * core function, create tooltip content 
 | 
     * @param  {string} content - template with tooltip content 
 | 
     * @param  {object} item - Flot item 
 | 
     * @return {string} real tooltip content for current item 
 | 
     */ 
 | 
    FlotTooltip.prototype.stringFormat = function (content, item) { 
 | 
        var percentPattern = /%p\.{0,1}(\d{0,})/; 
 | 
        var seriesPattern = /%s/; 
 | 
        var colorPattern = /%c/; 
 | 
        var xLabelPattern = /%lx/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded 
 | 
        var yLabelPattern = /%ly/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded 
 | 
        var xPattern = /%x\.{0,1}(\d{0,})/; 
 | 
        var yPattern = /%y\.{0,1}(\d{0,})/; 
 | 
        var xPatternWithoutPrecision = "%x"; 
 | 
        var yPatternWithoutPrecision = "%y"; 
 | 
        var customTextPattern = "%ct"; 
 | 
    var nPiePattern = "%n"; 
 | 
     
 | 
        var x, y, customText, p, n; 
 | 
  
 | 
        // for threshold plugin we need to read data from different place 
 | 
        if (typeof item.series.threshold !== "undefined") { 
 | 
            x = item.datapoint[0]; 
 | 
            y = item.datapoint[1]; 
 | 
            customText = item.datapoint[2]; 
 | 
    } 
 | 
  
 | 
    // for CurvedLines plugin we need to read data from different place 
 | 
        else if (typeof item.series.curvedLines !== "undefined") { 
 | 
        x = item.datapoint[0]; 
 | 
        y = item.datapoint[1]; 
 | 
        } 
 | 
         
 | 
        else if (typeof item.series.lines !== "undefined" && item.series.lines.steps) { 
 | 
            x = item.series.datapoints.points[item.dataIndex * 2]; 
 | 
            y = item.series.datapoints.points[item.dataIndex * 2 + 1]; 
 | 
            // TODO: where to find custom text in this variant? 
 | 
            customText = ""; 
 | 
        } else { 
 | 
            x = item.series.data[item.dataIndex][0]; 
 | 
            y = item.series.data[item.dataIndex][1]; 
 | 
            customText = item.series.data[item.dataIndex][2]; 
 | 
        } 
 | 
  
 | 
        // I think this is only in case of threshold plugin 
 | 
        if (item.series.label === null && item.series.originSeries) { 
 | 
            item.series.label = item.series.originSeries.label; 
 | 
        } 
 | 
  
 | 
        // if it is a function callback get the content string 
 | 
        if (typeof(content) === 'function') { 
 | 
            content = content(item.series.label, x, y, item); 
 | 
        } 
 | 
  
 | 
        // the case where the passed content is equal to false 
 | 
        if (typeof(content) === 'boolean' && !content) { 
 | 
            return ''; 
 | 
        } 
 | 
  
 | 
    /* replacement of %ct and other multi-character templates must 
 | 
       precede the replacement of single-character templates  
 | 
       to avoid conflict between '%c' and '%ct'  and similar substrings 
 | 
    */ 
 | 
    if (customText) 
 | 
            content = content.replace(customTextPattern, customText); 
 | 
  
 | 
        // percent match for pie charts and stacked percent 
 | 
        if (typeof (item.series.percent) !== 'undefined') { 
 | 
            p = item.series.percent; 
 | 
        } else if (typeof (item.series.percents) !== 'undefined') { 
 | 
            p = item.series.percents[item.dataIndex]; 
 | 
        }         
 | 
        if (typeof p === 'number') { 
 | 
            content = this.adjustValPrecision(percentPattern, content, p); 
 | 
        } 
 | 
  
 | 
    // replace %n with number of items represented by slice in pie charts 
 | 
    if (item.series.hasOwnProperty('pie')) { 
 | 
        if (typeof (item.series.data[0][1] !== 'undefined')) { 
 | 
        n = item.series.data[0][1]; 
 | 
        } 
 | 
    } 
 | 
    if (typeof n === 'number') { 
 | 
            content = content.replace(nPiePattern, n); 
 | 
    } 
 | 
     
 | 
        // series match 
 | 
        if (typeof(item.series.label) !== 'undefined') { 
 | 
            content = content.replace(seriesPattern, item.series.label); 
 | 
        } else { 
 | 
            //remove %s if label is undefined 
 | 
            content = content.replace(seriesPattern, ""); 
 | 
        } 
 | 
         
 | 
        // color match 
 | 
        if (typeof(item.series.color) !== 'undefined') { 
 | 
            content = content.replace(colorPattern, item.series.color); 
 | 
        } else { 
 | 
            //remove %s if color is undefined 
 | 
            content = content.replace(colorPattern, ""); 
 | 
        } 
 | 
  
 | 
        // x axis label match 
 | 
        if (this.hasAxisLabel('xaxis', item)) { 
 | 
            content = content.replace(xLabelPattern, item.series.xaxis.options.axisLabel); 
 | 
        } else { 
 | 
            //remove %lx if axis label is undefined or axislabels plugin not present 
 | 
            content = content.replace(xLabelPattern, ""); 
 | 
        } 
 | 
  
 | 
        // y axis label match 
 | 
        if (this.hasAxisLabel('yaxis', item)) { 
 | 
            content = content.replace(yLabelPattern, item.series.yaxis.options.axisLabel); 
 | 
        } else { 
 | 
            //remove %ly if axis label is undefined or axislabels plugin not present 
 | 
            content = content.replace(yLabelPattern, ""); 
 | 
        } 
 | 
  
 | 
        // time mode axes with custom dateFormat 
 | 
        if (this.isTimeMode('xaxis', item) && this.isXDateFormat(item)) { 
 | 
            content = content.replace(xPattern, this.timestampToDate(x, this.tooltipOptions.xDateFormat, item.series.xaxis.options)); 
 | 
        } 
 | 
        if (this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) { 
 | 
            content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat, item.series.yaxis.options)); 
 | 
        } 
 | 
  
 | 
        // set precision if defined 
 | 
        if (typeof x === 'number') { 
 | 
            content = this.adjustValPrecision(xPattern, content, x); 
 | 
        } 
 | 
        if (typeof y === 'number') { 
 | 
            content = this.adjustValPrecision(yPattern, content, y); 
 | 
        } 
 | 
  
 | 
        // change x from number to given label, if given 
 | 
        if (typeof item.series.xaxis.ticks !== 'undefined') { 
 | 
  
 | 
            var ticks; 
 | 
            if (this.hasRotatedXAxisTicks(item)) { 
 | 
                // xaxis.ticks will be an empty array if tickRotor is being used, but the values are available in rotatedTicks 
 | 
                ticks = 'rotatedTicks'; 
 | 
            } else { 
 | 
                ticks = 'ticks'; 
 | 
            } 
 | 
  
 | 
            // see https://github.com/krzysu/flot.tooltip/issues/65 
 | 
            var tickIndex = item.dataIndex + item.seriesIndex; 
 | 
  
 | 
            for (var xIndex in item.series.xaxis[ticks]) { 
 | 
                if (item.series.xaxis[ticks].hasOwnProperty(tickIndex) && !this.isTimeMode('xaxis', item)) { 
 | 
                    var valueX = (this.isCategoriesMode('xaxis', item)) ? item.series.xaxis[ticks][tickIndex].label : item.series.xaxis[ticks][tickIndex].v; 
 | 
                    if (valueX === x) { 
 | 
                        content = content.replace(xPattern, item.series.xaxis[ticks][tickIndex].label.replace(/\$/g, '$$$$')); 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
  
 | 
        // change y from number to given label, if given 
 | 
        if (typeof item.series.yaxis.ticks !== 'undefined') { 
 | 
            for (var yIndex in item.series.yaxis.ticks) { 
 | 
                if (item.series.yaxis.ticks.hasOwnProperty(yIndex)) { 
 | 
                    var valueY = (this.isCategoriesMode('yaxis', item)) ? item.series.yaxis.ticks[yIndex].label : item.series.yaxis.ticks[yIndex].v; 
 | 
                    if (valueY === y) { 
 | 
                        content = content.replace(yPattern, item.series.yaxis.ticks[yIndex].label.replace(/\$/g, '$$$$')); 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
  
 | 
        // if no value customization, use tickFormatter by default 
 | 
        if (typeof item.series.xaxis.tickFormatter !== 'undefined') { 
 | 
            //escape dollar 
 | 
            content = content.replace(xPatternWithoutPrecision, item.series.xaxis.tickFormatter(x, item.series.xaxis).replace(/\$/g, '$$')); 
 | 
        } 
 | 
        if (typeof item.series.yaxis.tickFormatter !== 'undefined') { 
 | 
            //escape dollar 
 | 
            content = content.replace(yPatternWithoutPrecision, item.series.yaxis.tickFormatter(y, item.series.yaxis).replace(/\$/g, '$$')); 
 | 
        } 
 | 
  
 | 
        return content; 
 | 
    }; 
 | 
  
 | 
    // helpers just for readability 
 | 
    FlotTooltip.prototype.isTimeMode = function (axisName, item) { 
 | 
        return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'time'); 
 | 
    }; 
 | 
  
 | 
    FlotTooltip.prototype.isXDateFormat = function (item) { 
 | 
        return (typeof this.tooltipOptions.xDateFormat !== 'undefined' && this.tooltipOptions.xDateFormat !== null); 
 | 
    }; 
 | 
  
 | 
    FlotTooltip.prototype.isYDateFormat = function (item) { 
 | 
        return (typeof this.tooltipOptions.yDateFormat !== 'undefined' && this.tooltipOptions.yDateFormat !== null); 
 | 
    }; 
 | 
  
 | 
    FlotTooltip.prototype.isCategoriesMode = function (axisName, item) { 
 | 
        return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'categories'); 
 | 
    }; 
 | 
  
 | 
    // 
 | 
    FlotTooltip.prototype.timestampToDate = function (tmst, dateFormat, options) { 
 | 
        var theDate = $.plot.dateGenerator(tmst, options); 
 | 
        return $.plot.formatDate(theDate, dateFormat, this.tooltipOptions.monthNames, this.tooltipOptions.dayNames); 
 | 
    }; 
 | 
  
 | 
    // 
 | 
    FlotTooltip.prototype.adjustValPrecision = function (pattern, content, value) { 
 | 
  
 | 
        var precision; 
 | 
        var matchResult = content.match(pattern); 
 | 
        if( matchResult !== null ) { 
 | 
            if(RegExp.$1 !== '') { 
 | 
                precision = RegExp.$1; 
 | 
                value = value.toFixed(precision); 
 | 
  
 | 
                // only replace content if precision exists, in other case use thickformater 
 | 
                content = content.replace(pattern, value); 
 | 
            } 
 | 
        } 
 | 
        return content; 
 | 
    }; 
 | 
  
 | 
    // other plugins detection below 
 | 
  
 | 
    // check if flot-axislabels plugin (https://github.com/markrcote/flot-axislabels) is used and that an axis label is given 
 | 
    FlotTooltip.prototype.hasAxisLabel = function (axisName, item) { 
 | 
        return ($.inArray('axisLabels', this.plotPlugins) !== -1 && typeof item.series[axisName].options.axisLabel !== 'undefined' && item.series[axisName].options.axisLabel.length > 0); 
 | 
    }; 
 | 
  
 | 
    // check whether flot-tickRotor, a plugin which allows rotation of X-axis ticks, is being used 
 | 
    FlotTooltip.prototype.hasRotatedXAxisTicks = function (item) { 
 | 
        return ($.inArray('tickRotor',this.plotPlugins) !== -1 && typeof item.series.xaxis.rotatedTicks !== 'undefined'); 
 | 
    }; 
 | 
  
 | 
    // 
 | 
    var init = function (plot) { 
 | 
      new FlotTooltip(plot); 
 | 
    }; 
 | 
  
 | 
    // define Flot plugin 
 | 
    $.plot.plugins.push({ 
 | 
        init: init, 
 | 
        options: defaultOptions, 
 | 
        name: 'tooltip', 
 | 
        version: '0.8.5' 
 | 
    }); 
 | 
  
 | 
})(jQuery); 
 |