diff -r 318533413200 -r a1707c607eec src/pyams_skin/resources/js/ext/flot/jquery.flot.selection.js --- a/src/pyams_skin/resources/js/ext/flot/jquery.flot.selection.js Sun Jul 19 02:02:20 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,529 +0,0 @@ -/* Flot plugin for selecting regions of a plot. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -The plugin supports these options: - -selection: { - mode: null or "x" or "y" or "xy" or "smart", - color: color, - shape: "round" or "miter" or "bevel", - visualization: "fill" or "focus", - minSize: number of pixels -} - -Selection support is enabled by setting the mode to one of "x", "y" or "xy". -In "x" mode, the user will only be able to specify the x range, similarly for -"y" mode. For "xy", the selection becomes a rectangle where both ranges can be -specified. "color" is color of the selection (if you need to change the color -later on, you can get to it with plot.getOptions().selection.color). "shape" -is the shape of the corners of the selection. - -The way how the selection is visualized, can be changed by using the option -"visualization". Flot currently supports two modes: "focus" and "fill". The -option "focus" draws a colored bezel around the selected area while keeping -the selected area clear. The option "fill" highlights (i.e., fills) the -selected area with a colored highlight. - -"minSize" is the minimum size a selection can be in pixels. This value can -be customized to determine the smallest size a selection can be and still -have the selection rectangle be displayed. When customizing this value, the -fact that it refers to pixels, not axis units must be taken into account. -Thus, for example, if there is a bar graph in time mode with BarWidth set to 1 -minute, setting "minSize" to 1 will not make the minimum selection size 1 -minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent -"plotunselected" events from being fired when the user clicks the mouse without -dragging. - -When selection support is enabled, a "plotselected" event will be emitted on -the DOM element you passed into the plot function. The event handler gets a -parameter with the ranges selected on the axes, like this: - - placeholder.bind( "plotselected", function( event, ranges ) { - alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to) - // similar for yaxis - with multiple axes, the extra ones are in - // x2axis, x3axis, ... - }); - -The "plotselected" event is only fired when the user has finished making the -selection. A "plotselecting" event is fired during the process with the same -parameters as the "plotselected" event, in case you want to know what's -happening while it's happening, - -A "plotunselected" event with no arguments is emitted when the user clicks the -mouse to remove the selection. As stated above, setting "minSize" to 0 will -destroy this behavior. - -The plugin allso adds the following methods to the plot object: - -- setSelection( ranges, preventEvent ) - - Set the selection rectangle. The passed in ranges is on the same form as - returned in the "plotselected" event. If the selection mode is "x", you - should put in either an xaxis range, if the mode is "y" you need to put in - an yaxis range and both xaxis and yaxis if the selection mode is "xy", like - this: - - setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } }); - - setSelection will trigger the "plotselected" event when called. If you don't - want that to happen, e.g. if you're inside a "plotselected" handler, pass - true as the second parameter. If you are using multiple axes, you can - specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of - xaxis, the plugin picks the first one it sees. - -- clearSelection( preventEvent ) - - Clear the selection rectangle. Pass in true to avoid getting a - "plotunselected" event. - -- getSelection() - - Returns the current selection in the same format as the "plotselected" - event. If there's currently no selection, the function returns null. - -*/ - -(function ($) { - function init(plot) { - var selection = { - first: {x: -1, y: -1}, - second: {x: -1, y: -1}, - show: false, - currentMode: 'xy', - active: false - }; - - var SNAPPING_CONSTANT = $.plot.uiConstants.SNAPPING_CONSTANT; - - // FIXME: The drag handling implemented here should be - // abstracted out, there's some similar code from a library in - // the navigation plugin, this should be massaged a bit to fit - // the Flot cases here better and reused. Doing this would - // make this plugin much slimmer. - var savedhandlers = {}; - - var mouseUpHandler = null; - - function onMouseMove(e) { - if (selection.active) { - updateSelection(e); - - plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]); - } - } - - function onMouseDown(e) { - var o = plot.getOptions(); - // only accept left-click - if (e.which !== 1 || o.selection.mode === null) return; - - // reinitialize currentMode - selection.currentMode = 'xy'; - - // cancel out any text selections - document.body.focus(); - - // prevent text selection and drag in old-school browsers - if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) { - savedhandlers.onselectstart = document.onselectstart; - document.onselectstart = function () { return false; }; - } - if (document.ondrag !== undefined && savedhandlers.ondrag == null) { - savedhandlers.ondrag = document.ondrag; - document.ondrag = function () { return false; }; - } - - setSelectionPos(selection.first, e); - - selection.active = true; - - // this is a bit silly, but we have to use a closure to be - // able to whack the same handler again - mouseUpHandler = function (e) { onMouseUp(e); }; - - $(document).one("mouseup", mouseUpHandler); - } - - function onMouseUp(e) { - mouseUpHandler = null; - - // revert drag stuff for old-school browsers - if (document.onselectstart !== undefined) { - document.onselectstart = savedhandlers.onselectstart; - } - - if (document.ondrag !== undefined) { - document.ondrag = savedhandlers.ondrag; - } - - // no more dragging - selection.active = false; - updateSelection(e); - - if (selectionIsSane()) { - triggerSelectedEvent(); - } else { - // this counts as a clear - plot.getPlaceholder().trigger("plotunselected", [ ]); - plot.getPlaceholder().trigger("plotselecting", [ null ]); - } - - return false; - } - - function getSelection() { - if (!selectionIsSane()) return null; - - if (!selection.show) return null; - - var r = {}, - c1 = {x: selection.first.x, y: selection.first.y}, - c2 = {x: selection.second.x, y: selection.second.y}; - - if (selectionDirection(plot) === 'x') { - c1.y = 0; - c2.y = plot.height(); - } - - if (selectionDirection(plot) === 'y') { - c1.x = 0; - c2.x = plot.width(); - } - - $.each(plot.getAxes(), function (name, axis) { - if (axis.used) { - var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); - r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) }; - } - }); - return r; - } - - function triggerSelectedEvent() { - var r = getSelection(); - - plot.getPlaceholder().trigger("plotselected", [ r ]); - - // backwards-compat stuff, to be removed in future - if (r.xaxis && r.yaxis) { - plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]); - } - } - - function clamp(min, value, max) { - return value < min ? min : (value > max ? max : value); - } - - function selectionDirection(plot) { - var o = plot.getOptions(); - - if (o.selection.mode === 'smart') { - return selection.currentMode; - } else { - return o.selection.mode; - } - } - - function updateMode(pos) { - if (selection.first) { - var delta = { - x: pos.x - selection.first.x, - y: pos.y - selection.first.y - }; - - if (Math.abs(delta.x) < SNAPPING_CONSTANT) { - selection.currentMode = 'y'; - } else if (Math.abs(delta.y) < SNAPPING_CONSTANT) { - selection.currentMode = 'x'; - } else { - selection.currentMode = 'xy'; - } - } - } - - function setSelectionPos(pos, e) { - var offset = plot.getPlaceholder().offset(); - var plotOffset = plot.getPlotOffset(); - pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width()); - pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height()); - - if (pos !== selection.first) updateMode(pos); - - if (selectionDirection(plot) === "y") { - pos.x = pos === selection.first ? 0 : plot.width(); - } - - if (selectionDirection(plot) === "x") { - pos.y = pos === selection.first ? 0 : plot.height(); - } - } - - function updateSelection(pos) { - if (pos.pageX == null) return; - - setSelectionPos(selection.second, pos); - if (selectionIsSane()) { - selection.show = true; - plot.triggerRedrawOverlay(); - } else clearSelection(true); - } - - function clearSelection(preventEvent) { - if (selection.show) { - selection.show = false; - selection.currentMode = ''; - plot.triggerRedrawOverlay(); - if (!preventEvent) { - plot.getPlaceholder().trigger("plotunselected", [ ]); - } - } - } - - // function taken from markings support in Flot - function extractRange(ranges, coord) { - var axis, from, to, key, axes = plot.getAxes(); - - for (var k in axes) { - axis = axes[k]; - if (axis.direction === coord) { - key = coord + axis.n + "axis"; - if (!ranges[key] && axis.n === 1) { - // support x1axis as xaxis - key = coord + "axis"; - } - - if (ranges[key]) { - from = ranges[key].from; - to = ranges[key].to; - break; - } - } - } - - // backwards-compat stuff - to be removed in future - if (!ranges[key]) { - axis = coord === "x" ? plot.getXAxes()[0] : plot.getYAxes()[0]; - from = ranges[coord + "1"]; - to = ranges[coord + "2"]; - } - - // auto-reverse as an added bonus - if (from != null && to != null && from > to) { - var tmp = from; - from = to; - to = tmp; - } - - return { from: from, to: to, axis: axis }; - } - - function setSelection(ranges, preventEvent) { - var range; - - if (selectionDirection(plot) === "y") { - selection.first.x = 0; - selection.second.x = plot.width(); - } else { - range = extractRange(ranges, "x"); - selection.first.x = range.axis.p2c(range.from); - selection.second.x = range.axis.p2c(range.to); - } - - if (selectionDirection(plot) === "x") { - selection.first.y = 0; - selection.second.y = plot.height(); - } else { - range = extractRange(ranges, "y"); - selection.first.y = range.axis.p2c(range.from); - selection.second.y = range.axis.p2c(range.to); - } - - selection.show = true; - plot.triggerRedrawOverlay(); - if (!preventEvent && selectionIsSane()) { - triggerSelectedEvent(); - } - } - - function selectionIsSane() { - var minSize = plot.getOptions().selection.minSize; - return Math.abs(selection.second.x - selection.first.x) >= minSize && - Math.abs(selection.second.y - selection.first.y) >= minSize; - } - - plot.clearSelection = clearSelection; - plot.setSelection = setSelection; - plot.getSelection = getSelection; - - plot.hooks.bindEvents.push(function(plot, eventHolder) { - var o = plot.getOptions(); - if (o.selection.mode != null) { - eventHolder.mousemove(onMouseMove); - eventHolder.mousedown(onMouseDown); - } - }); - - function drawSelectionDecorations(ctx, x, y, w, h, oX, oY, mode) { - var spacing = 3; - var fullEarWidth = 15; - var earWidth = Math.max(0, Math.min(fullEarWidth, w / 2 - 2, h / 2 - 2)); - ctx.fillStyle = '#ffffff'; - - if (mode === 'xy') { - ctx.beginPath(); - ctx.moveTo(x, y + earWidth); - ctx.lineTo(x - 3, y + earWidth); - ctx.lineTo(x - 3, y - 3); - ctx.lineTo(x + earWidth, y - 3); - ctx.lineTo(x + earWidth, y); - ctx.lineTo(x, y); - ctx.closePath(); - - ctx.moveTo(x, y + h - earWidth); - ctx.lineTo(x - 3, y + h - earWidth); - ctx.lineTo(x - 3, y + h + 3); - ctx.lineTo(x + earWidth, y + h + 3); - ctx.lineTo(x + earWidth, y + h); - ctx.lineTo(x, y + h); - ctx.closePath(); - - ctx.moveTo(x + w, y + earWidth); - ctx.lineTo(x + w + 3, y + earWidth); - ctx.lineTo(x + w + 3, y - 3); - ctx.lineTo(x + w - earWidth, y - 3); - ctx.lineTo(x + w - earWidth, y); - ctx.lineTo(x + w, y); - ctx.closePath(); - - ctx.moveTo(x + w, y + h - earWidth); - ctx.lineTo(x + w + 3, y + h - earWidth); - ctx.lineTo(x + w + 3, y + h + 3); - ctx.lineTo(x + w - earWidth, y + h + 3); - ctx.lineTo(x + w - earWidth, y + h); - ctx.lineTo(x + w, y + h); - ctx.closePath(); - - ctx.stroke(); - ctx.fill(); - } - - x = oX; - y = oY; - - if (mode === 'x') { - ctx.beginPath(); - ctx.moveTo(x, y + fullEarWidth); - ctx.lineTo(x, y - fullEarWidth); - ctx.lineTo(x - spacing, y - fullEarWidth); - ctx.lineTo(x - spacing, y + fullEarWidth); - ctx.closePath(); - - ctx.moveTo(x + w, y + fullEarWidth); - ctx.lineTo(x + w, y - fullEarWidth); - ctx.lineTo(x + w + spacing, y - fullEarWidth); - ctx.lineTo(x + w + spacing, y + fullEarWidth); - ctx.closePath(); - ctx.stroke(); - ctx.fill(); - } - - if (mode === 'y') { - ctx.beginPath(); - - ctx.moveTo(x - fullEarWidth, y); - ctx.lineTo(x + fullEarWidth, y); - ctx.lineTo(x + fullEarWidth, y - spacing); - ctx.lineTo(x - fullEarWidth, y - spacing); - ctx.closePath(); - - ctx.moveTo(x - fullEarWidth, y + h); - ctx.lineTo(x + fullEarWidth, y + h); - ctx.lineTo(x + fullEarWidth, y + h + spacing); - ctx.lineTo(x - fullEarWidth, y + h + spacing); - ctx.closePath(); - ctx.stroke(); - ctx.fill(); - } - } - - plot.hooks.drawOverlay.push(function (plot, ctx) { - // draw selection - if (selection.show && selectionIsSane()) { - var plotOffset = plot.getPlotOffset(); - var o = plot.getOptions(); - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - var c = $.color.parse(o.selection.color); - var visualization = o.selection.visualization; - - var scalingFactor = 1; - - // use a dimmer scaling factor if visualization is "fill" - if (visualization === "fill") { - scalingFactor = 0.8; - } - - ctx.strokeStyle = c.scale('a', scalingFactor).toString(); - ctx.lineWidth = 1; - ctx.lineJoin = o.selection.shape; - ctx.fillStyle = c.scale('a', 0.4).toString(); - - var x = Math.min(selection.first.x, selection.second.x) + 0.5, - oX = x, - y = Math.min(selection.first.y, selection.second.y) + 0.5, - oY = y, - w = Math.abs(selection.second.x - selection.first.x) - 1, - h = Math.abs(selection.second.y - selection.first.y) - 1; - - if (selectionDirection(plot) === 'x') { - h += y; - y = 0; - } - - if (selectionDirection(plot) === 'y') { - w += x; - x = 0; - } - - if (visualization === "fill") { - ctx.fillRect(x, y, w, h); - ctx.strokeRect(x, y, w, h); - } else { - ctx.fillRect(0, 0, plot.width(), plot.height()); - ctx.clearRect(x, y, w, h); - drawSelectionDecorations(ctx, x, y, w, h, oX, oY, selectionDirection(plot)); - } - - ctx.restore(); - } - }); - - plot.hooks.shutdown.push(function (plot, eventHolder) { - eventHolder.unbind("mousemove", onMouseMove); - eventHolder.unbind("mousedown", onMouseDown); - - if (mouseUpHandler) { - $(document).unbind("mouseup", mouseUpHandler); - } - }); - } - - $.plot.plugins.push({ - init: init, - options: { - selection: { - mode: null, // one of null, "x", "y" or "xy" - visualization: "focus", // "focus" or "fill" - color: "#888888", - shape: "round", // one of "round", "miter", or "bevel" - minSize: 5 // minimum number of pixels - } - }, - name: 'selection', - version: '1.1' - }); -})(jQuery);