src/pyams_skin/resources/js/ext/flot/jquery.flot.logaxis.js
changeset 546 9f02c09d2393
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_skin/resources/js/ext/flot/jquery.flot.logaxis.js	Wed Oct 16 13:00:43 2019 +0200
@@ -0,0 +1,298 @@
+/* Pretty handling of log axes.
+
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Copyright (c) 2015 Ciprian Ceteras cipix2000@gmail.com.
+Copyright (c) 2017 Raluca Portase
+Licensed under the MIT license.
+
+Set axis.mode to "log" to enable.
+*/
+
+/* global jQuery*/
+
+/**
+## jquery.flot.logaxis
+This plugin is used to create logarithmic axis. This includes tick generation,
+formatters and transformers to and from logarithmic representation.
+
+### Methods and hooks
+*/
+
+(function ($) {
+    'use strict';
+
+    var options = {
+        xaxis: {}
+    };
+
+    /*tick generators and formatters*/
+    var PREFERRED_LOG_TICK_VALUES = computePreferedLogTickValues(Number.MAX_VALUE, 10),
+        EXTENDED_LOG_TICK_VALUES = computePreferedLogTickValues(Number.MAX_VALUE, 4);
+
+    function computePreferedLogTickValues(endLimit, rangeStep) {
+        var log10End = Math.floor(Math.log(endLimit) * Math.LOG10E) - 1,
+            log10Start = -log10End,
+            val, range, vals = [];
+
+        for (var power = log10Start; power <= log10End; power++) {
+            range = parseFloat('1e' + power);
+            for (var mult = 1; mult < 9; mult += rangeStep) {
+                val = range * mult;
+                vals.push(val);
+            }
+        }
+        return vals;
+    }
+
+    /**
+    - logTickGenerator(plot, axis, noTicks)
+
+    Generates logarithmic ticks, depending on axis range.
+    In case the number of ticks that can be generated is less than the expected noTicks/4,
+    a linear tick generation is used.
+    */
+    var logTickGenerator = function (plot, axis, noTicks) {
+        var ticks = [],
+            minIdx = -1,
+            maxIdx = -1,
+            surface = plot.getCanvas(),
+            logTickValues = PREFERRED_LOG_TICK_VALUES,
+            min = clampAxis(axis, plot),
+            max = axis.max;
+
+        if (!noTicks) {
+            noTicks = 0.3 * Math.sqrt(axis.direction === "x" ? surface.width : surface.height);
+        }
+
+        PREFERRED_LOG_TICK_VALUES.some(function (val, i) {
+            if (val >= min) {
+                minIdx = i;
+                return true;
+            } else {
+                return false;
+            }
+        });
+
+        PREFERRED_LOG_TICK_VALUES.some(function (val, i) {
+            if (val >= max) {
+                maxIdx = i;
+                return true;
+            } else {
+                return false;
+            }
+        });
+
+        if (maxIdx === -1) {
+            maxIdx = PREFERRED_LOG_TICK_VALUES.length - 1;
+        }
+
+        if (maxIdx - minIdx <= noTicks / 4 && logTickValues.length !== EXTENDED_LOG_TICK_VALUES.length) {
+            //try with multiple of 5 for tick values
+            logTickValues = EXTENDED_LOG_TICK_VALUES;
+            minIdx *= 2;
+            maxIdx *= 2;
+        }
+
+        var lastDisplayed = null,
+            inverseNoTicks = 1 / noTicks,
+            tickValue, pixelCoord, tick;
+
+        // Count the number of tick values would appear, if we can get at least
+        // nTicks / 4 accept them.
+        if (maxIdx - minIdx >= noTicks / 4) {
+            for (var idx = maxIdx; idx >= minIdx; idx--) {
+                tickValue = logTickValues[idx];
+                pixelCoord = (Math.log(tickValue) - Math.log(min)) / (Math.log(max) - Math.log(min));
+                tick = tickValue;
+
+                if (lastDisplayed === null) {
+                    lastDisplayed = {
+                        pixelCoord: pixelCoord,
+                        idealPixelCoord: pixelCoord
+                    };
+                } else {
+                    if (Math.abs(pixelCoord - lastDisplayed.pixelCoord) >= inverseNoTicks) {
+                        lastDisplayed = {
+                            pixelCoord: pixelCoord,
+                            idealPixelCoord: lastDisplayed.idealPixelCoord - inverseNoTicks
+                        };
+                    } else {
+                        tick = null;
+                    }
+                }
+
+                if (tick) {
+                    ticks.push(tick);
+                }
+            }
+            // Since we went in backwards order.
+            ticks.reverse();
+        } else {
+            var tickSize = plot.computeTickSize(min, max, noTicks),
+                customAxis = {min: min, max: max, tickSize: tickSize};
+            ticks = $.plot.linearTickGenerator(customAxis);
+        }
+
+        return ticks;
+    };
+
+    var clampAxis = function (axis, plot) {
+        var min = axis.min,
+            max = axis.max;
+
+        if (min <= 0) {
+            //for empty graph if axis.min is not strictly positive make it 0.1
+            if (axis.datamin === null) {
+                min = axis.min = 0.1;
+            } else {
+                min = processAxisOffset(plot, axis);
+            }
+
+            if (max < min) {
+                axis.max = axis.datamax !== null ? axis.datamax : axis.options.max;
+                axis.options.offset.below = 0;
+                axis.options.offset.above = 0;
+            }
+        }
+
+        return min;
+    }
+
+    /**
+    - logTickFormatter(value, axis, precision)
+
+    This is the corresponding tickFormatter of the logaxis.
+    For a number greater that 10^6 or smaller than 10^(-3), this will be drawn
+    with e representation
+    */
+    var logTickFormatter = function (value, axis, precision) {
+        var tenExponent = value > 0 ? Math.floor(Math.log(value) / Math.LN10) : 0;
+
+        if (precision) {
+            if ((tenExponent >= -4) && (tenExponent <= 7)) {
+                return $.plot.defaultTickFormatter(value, axis, precision);
+            } else {
+                return $.plot.expRepTickFormatter(value, axis, precision);
+            }
+        }
+        if ((tenExponent >= -4) && (tenExponent <= 7)) {
+            //if we have float numbers, return a limited length string(ex: 0.0009 is represented as 0.000900001)
+            var formattedValue = tenExponent < 0 ? value.toFixed(-tenExponent) : value.toFixed(tenExponent + 2);
+            if (formattedValue.indexOf('.') !== -1) {
+                var lastZero = formattedValue.lastIndexOf('0');
+
+                while (lastZero === formattedValue.length - 1) {
+                    formattedValue = formattedValue.slice(0, -1);
+                    lastZero = formattedValue.lastIndexOf('0');
+                }
+
+                //delete the dot if is last
+                if (formattedValue.indexOf('.') === formattedValue.length - 1) {
+                    formattedValue = formattedValue.slice(0, -1);
+                }
+            }
+            return formattedValue;
+        } else {
+            return $.plot.expRepTickFormatter(value, axis);
+        }
+    };
+
+    /*logaxis caracteristic functions*/
+    var logTransform = function (v) {
+        if (v < PREFERRED_LOG_TICK_VALUES[0]) {
+            v = PREFERRED_LOG_TICK_VALUES[0];
+        }
+
+        return Math.log(v);
+    };
+
+    var logInverseTransform = function (v) {
+        return Math.exp(v);
+    };
+
+    var invertedTransform = function (v) {
+        return -v;
+    }
+
+    var invertedLogTransform = function (v) {
+        return -logTransform(v);
+    }
+
+    var invertedLogInverseTransform = function (v) {
+        return logInverseTransform(-v);
+    }
+
+    /**
+    - setDataminRange(plot, axis)
+
+    It is used for clamping the starting point of a logarithmic axis.
+    This will set the axis datamin range to 0.1 or to the first datapoint greater then 0.
+    The function is usefull since the logarithmic representation can not show
+    values less than or equal to 0.
+    */
+    function setDataminRange(plot, axis) {
+        if (axis.options.mode === 'log' && axis.datamin <= 0) {
+            if (axis.datamin === null) {
+                axis.datamin = 0.1;
+            } else {
+                axis.datamin = processAxisOffset(plot, axis);
+            }
+        }
+    }
+
+    function processAxisOffset(plot, axis) {
+        var series = plot.getData(),
+            range = series
+                .filter(function(series) {
+                    return series.xaxis === axis || series.yaxis === axis;
+                })
+                .map(function(series) {
+                    return plot.computeRangeForDataSeries(series, null, isValid);
+                }),
+            min = axis.direction === 'x' 
+            ? Math.min(0.1, range && range[0] ? range[0].xmin : 0.1) 
+            : Math.min(0.1, range && range[0] ? range[0].ymin : 0.1);
+
+        axis.min = min;
+
+        return min;
+    }
+
+    function isValid(a) {
+        return a > 0;
+    }
+
+    function init(plot) {
+        plot.hooks.processOptions.push(function (plot) {
+            $.each(plot.getAxes(), function (axisName, axis) {
+                var opts = axis.options;
+                if (opts.mode === 'log') {
+                    axis.tickGenerator = function (axis) {
+                        var noTicks = 11;
+                        return logTickGenerator(plot, axis, noTicks);
+                    };
+                    if (typeof axis.options.tickFormatter !== 'function') {
+                        axis.options.tickFormatter = logTickFormatter;
+                    }
+                    axis.options.transform = opts.inverted ? invertedLogTransform : logTransform;
+                    axis.options.inverseTransform = opts.inverted ? invertedLogInverseTransform : logInverseTransform;
+                    axis.options.autoScaleMargin = 0;
+                    plot.hooks.setRange.push(setDataminRange);
+                } else if (opts.inverted) {
+                    axis.options.transform = invertedTransform;
+                    axis.options.inverseTransform = invertedTransform;
+                }
+            });
+        });
+    }
+
+    $.plot.plugins.push({
+        init: init,
+        options: options,
+        name: 'log',
+        version: '0.1'
+    });
+
+    $.plot.logTicksGenerator = logTickGenerator;
+    $.plot.logTickFormatter = logTickFormatter;
+})(jQuery);