diff d3s_examples/python-neo4jrestclient/static/platin/lib/flot/jquery.flot.tooltip.js @ 8:18ef6948d689

new d3s examples
author Dirk Wintergruen <dwinter@mpiwg-berlin.mpg.de>
date Thu, 01 Oct 2015 17:17:27 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/d3s_examples/python-neo4jrestclient/static/platin/lib/flot/jquery.flot.tooltip.js	Thu Oct 01 17:17:27 2015 +0200
@@ -0,0 +1,394 @@
+/*
+ * jquery.flot.tooltip
+ * 
+ * description: easy-to-use tooltips for Flot charts
+ * version: 0.6.7
+ * author: Krzysztof Urbas @krzysu [myviews.pl]
+ * website: https://github.com/krzysu/flot.tooltip
+ * 
+ * build on 2014-03-26
+ * released under MIT License, 2012
+*/ 
+// IE8 polyfill for Array.indexOf
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (searchElement, fromIndex) {
+        if ( this === undefined || this === null ) {
+            throw new TypeError( '"this" is null or not defined' );
+        }
+        var length = this.length >>> 0; // Hack to convert object.length to a UInt32
+        fromIndex = +fromIndex || 0;
+        if (Math.abs(fromIndex) === Infinity) {
+            fromIndex = 0;
+        }
+        if (fromIndex < 0) {
+            fromIndex += length;
+            if (fromIndex < 0) {
+                fromIndex = 0;
+            }
+        }
+
+        for (;fromIndex < length; fromIndex++) {
+            if (this[fromIndex] === searchElement) {
+                return fromIndex;
+            }
+        }
+
+        return -1;
+    };
+}
+
+(function ($) {
+
+    // plugin options, default values
+    var defaultOptions = {
+        tooltip: false,
+        tooltipOpts: {
+            content: "%s | X: %x | Y: %y",
+            // allowed templates are:
+            // %s -> series label,
+            // %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
+            xDateFormat: null,
+            yDateFormat: null,
+            monthNames: null,
+            dayNames: null,
+            shifts: {
+                x: 10,
+                y: 20
+            },
+            defaultTheme: true,
+
+            // callbacks
+            onHover: function(flotItem, $tooltipEl) {}
+        }
+    };
+
+    // 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();
+
+            // if not enabled return
+            if (that.plotOptions.tooltip === false || typeof that.plotOptions.tooltip === 'undefined') return;
+
+            // shortcut to access tooltip options
+            that.tooltipOptions = that.plotOptions.tooltipOpts;
+
+            // create tooltip DOM element
+            var $tip = that.getDomElement();
+
+            // bind event
+            $( plot.getPlaceholder() ).bind("plothover", plothover);
+
+            $(eventHolder).bind('mousemove', mouseMove);
+        });
+
+        plot.hooks.shutdown.push(function (plot, eventHolder){
+            $(plot.getPlaceholder()).unbind("plothover", plothover);
+            $(eventHolder).unbind("mousemove", mouseMove);
+        });
+
+        function mouseMove(e){
+            var pos = {};
+            pos.x = e.pageX;
+            pos.y = e.pageY;
+            that.updateTooltipPosition(pos);
+        }
+
+        function plothover(event, pos, item) {
+            var $tip = that.getDomElement();
+            if (item) {
+                var tipText;
+
+                // convert tooltip content template to real tipText
+                tipText = that.stringFormat(that.tooltipOptions.content, item);
+
+                $tip.html( tipText );
+                that.updateTooltipPosition({ x: pos.pageX, y: pos.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(item, $tip);
+                }
+            }
+            else {
+                $tip.hide().html('');
+            }
+        }
+    };
+
+    /**
+     * get or create tooltip DOM element
+     * @return jQuery object
+     */
+    FlotTooltip.prototype.getDomElement = function() {
+        var $tip;
+
+        if( $('#flotTip').length > 0 ){
+            $tip = $('#flotTip');
+        }
+        else {
+            $tip = $('<div />').attr('id', 'flotTip');
+            $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;
+    };
+
+    // as the name says
+    FlotTooltip.prototype.updateTooltipPosition = function(pos) {
+        var totalTipWidth = $("#flotTip").outerWidth() + this.tooltipOptions.shifts.x;
+        var totalTipHeight = $("#flotTip").outerHeight() + this.tooltipOptions.shifts.y;
+        if ((pos.x - $(window).scrollLeft()) > ($(window).innerWidth() - totalTipWidth)) {
+            pos.x -= totalTipWidth;
+        }
+        if ((pos.y - $(window).scrollTop()) > ($(window).innerHeight() - totalTipHeight)) {
+            pos.y -= totalTipHeight;
+        }
+        this.tipPosition.x = pos.x;
+        this.tipPosition.y = pos.y;
+    };
+
+    /**
+     * 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 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 x, y;
+
+        // 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];
+        } else {
+            x = item.series.data[item.dataIndex][0];
+            y = item.series.data[item.dataIndex][1];
+        }
+
+        // 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);
+        }
+
+        // percent match for pie charts
+        if( typeof (item.series.percent) !== 'undefined' ) {
+            content = this.adjustValPrecision(percentPattern, content, item.series.percent);
+        }
+
+        // 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, "");
+        }
+
+        // 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));
+        }
+
+        if(this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) {
+            content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat));
+        }
+
+        // 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;
+
+            if(item.series.xaxis[ticks].length > tickIndex && !this.isTimeMode('xaxis', item))
+                content = content.replace(xPattern, item.series.xaxis[ticks][tickIndex].label);
+        }
+
+        // change y from number to given label, if given
+        if(typeof item.series.yaxis.ticks !== 'undefined') {
+            for (var index in item.series.yaxis.ticks) {
+                if (item.series.yaxis.ticks.hasOwnProperty(index)) {
+                    var value = (this.isCategoriesMode('yaxis', item)) ? item.series.yaxis.ticks[index].label : item.series.yaxis.ticks[index].v;
+                    if (value === y) {
+                        content = content.replace(yPattern, item.series.yaxis.ticks[index].label);
+                    }
+                }
+            }
+        }
+
+        // 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) {
+        var theDate = new Date(tmst*1);
+        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 (this.plotPlugins.indexOf('axisLabels') !== -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 ($.grep($.plot.plugins, function(p){ return p.name === "tickRotor"; }).length === 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.6.7'
+    });
+
+})(jQuery);