diff options
Diffstat (limited to 'build/resources/main/static/plugins/flot/plugins/jquery.flot.hover.js')
-rw-r--r-- | build/resources/main/static/plugins/flot/plugins/jquery.flot.hover.js | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/build/resources/main/static/plugins/flot/plugins/jquery.flot.hover.js b/build/resources/main/static/plugins/flot/plugins/jquery.flot.hover.js new file mode 100644 index 0000000..f24936a --- /dev/null +++ b/build/resources/main/static/plugins/flot/plugins/jquery.flot.hover.js @@ -0,0 +1,359 @@ +/* global jQuery */ + +/** +## jquery.flot.hover.js + +This plugin is used for mouse hover and tap on a point of plot series. +It supports the following options: +```js +grid: { + hoverable: false, //to trigger plothover event on mouse hover or tap on a point + clickable: false //to trigger plotclick event on mouse hover +} +``` + +It listens to native mouse move event or click, as well as artificial generated +tap and touchevent. + +When the mouse is over a point or a tap on a point is performed, that point or +the correscponding bar will be highlighted and a "plothover" event will be generated. + +Custom "touchevent" is triggered when any touch interaction is made. Hover plugin +handles this events by unhighlighting all of the previously highlighted points and generates +"plothovercleanup" event to notify any part that is handling plothover (for exemple to cleanup +the tooltip from webcharts). +*/ + +(function($) { + 'use strict'; + + var options = { + grid: { + hoverable: false, + clickable: false + } + }; + + var browser = $.plot.browser; + + var eventType = { + click: 'click', + hover: 'hover' + } + + function init(plot) { + var lastMouseMoveEvent; + var highlights = []; + + function bindEvents(plot, eventHolder) { + var o = plot.getOptions(); + + if (o.grid.hoverable || o.grid.clickable) { + eventHolder[0].addEventListener('touchevent', triggerCleanupEvent, false); + eventHolder[0].addEventListener('tap', generatePlothoverEvent, false); + } + + if (o.grid.clickable) { + eventHolder.bind("click", onClick); + } + + if (o.grid.hoverable) { + eventHolder.bind("mousemove", onMouseMove); + + // Use bind, rather than .mouseleave, because we officially + // still support jQuery 1.2.6, which doesn't define a shortcut + // for mouseenter or mouseleave. This was a bug/oversight that + // was fixed somewhere around 1.3.x. We can return to using + // .mouseleave when we drop support for 1.2.6. + + eventHolder.bind("mouseleave", onMouseLeave); + } + } + + function shutdown(plot, eventHolder) { + eventHolder[0].removeEventListener('tap', generatePlothoverEvent); + eventHolder[0].removeEventListener('touchevent', triggerCleanupEvent); + eventHolder.unbind("mousemove", onMouseMove); + eventHolder.unbind("mouseleave", onMouseLeave); + eventHolder.unbind("click", onClick); + highlights = []; + } + + function generatePlothoverEvent(e) { + var o = plot.getOptions(), + newEvent = new CustomEvent('mouseevent'); + + //transform from touch event to mouse event format + newEvent.pageX = e.detail.changedTouches[0].pageX; + newEvent.pageY = e.detail.changedTouches[0].pageY; + newEvent.clientX = e.detail.changedTouches[0].clientX; + newEvent.clientY = e.detail.changedTouches[0].clientY; + + if (o.grid.hoverable) { + doTriggerClickHoverEvent(newEvent, eventType.hover, 30); + } + return false; + } + + function doTriggerClickHoverEvent(event, eventType, searchDistance) { + var series = plot.getData(); + if (event !== undefined && + series.length > 0 && + series[0].xaxis.c2p !== undefined && + series[0].yaxis.c2p !== undefined) { + var eventToTrigger = "plot" + eventType; + var seriesFlag = eventType + "able"; + triggerClickHoverEvent(eventToTrigger, event, + function(i) { + return series[i][seriesFlag] !== false; + }, searchDistance); + } + } + + function onMouseMove(e) { + lastMouseMoveEvent = e; + plot.getPlaceholder()[0].lastMouseMoveEvent = e; + doTriggerClickHoverEvent(e, eventType.hover); + } + + function onMouseLeave(e) { + lastMouseMoveEvent = undefined; + plot.getPlaceholder()[0].lastMouseMoveEvent = undefined; + triggerClickHoverEvent("plothover", e, + function(i) { + return false; + }); + } + + function onClick(e) { + doTriggerClickHoverEvent(e, eventType.click); + } + + function triggerCleanupEvent() { + plot.unhighlight(); + plot.getPlaceholder().trigger('plothovercleanup'); + } + + // trigger click or hover event (they send the same parameters + // so we share their code) + function triggerClickHoverEvent(eventname, event, seriesFilter, searchDistance) { + var options = plot.getOptions(), + offset = plot.offset(), + page = browser.getPageXY(event), + canvasX = page.X - offset.left, + canvasY = page.Y - offset.top, + pos = plot.c2p({ + left: canvasX, + top: canvasY + }), + distance = searchDistance !== undefined ? searchDistance : options.grid.mouseActiveRadius; + + pos.pageX = page.X; + pos.pageY = page.Y; + + var items = plot.findNearbyItems(canvasX, canvasY, seriesFilter, distance); + var item = items[0]; + + for (let i = 1; i < items.length; ++i) { + if (item.distance === undefined || + items[i].distance < item.distance) { + item = items[i]; + } + } + + if (item) { + // fill in mouse pos for any listeners out there + item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left, 10); + item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top, 10); + } else { + item = null; + } + + if (options.grid.autoHighlight) { + // clear auto-highlights + for (let i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if ((h.auto === eventname && + !(item && h.series === item.series && + h.point[0] === item.datapoint[0] && + h.point[1] === item.datapoint[1])) || !item) { + unhighlight(h.series, h.point); + } + } + + if (item) { + highlight(item.series, item.datapoint, eventname); + } + } + + plot.getPlaceholder().trigger(eventname, [pos, item, items]); + } + + function highlight(s, point, auto) { + if (typeof s === "number") { + s = plot.getData()[s]; + } + + if (typeof point === "number") { + var ps = s.datapoints.pointsize; + point = s.datapoints.points.slice(ps * point, ps * (point + 1)); + } + + var i = indexOfHighlight(s, point); + if (i === -1) { + highlights.push({ + series: s, + point: point, + auto: auto + }); + + plot.triggerRedrawOverlay(); + } else if (!auto) { + highlights[i].auto = false; + } + } + + function unhighlight(s, point) { + if (s == null && point == null) { + highlights = []; + plot.triggerRedrawOverlay(); + return; + } + + if (typeof s === "number") { + s = plot.getData()[s]; + } + + if (typeof point === "number") { + var ps = s.datapoints.pointsize; + point = s.datapoints.points.slice(ps * point, ps * (point + 1)); + } + + var i = indexOfHighlight(s, point); + if (i !== -1) { + highlights.splice(i, 1); + + plot.triggerRedrawOverlay(); + } + } + + function indexOfHighlight(s, p) { + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.series === s && + h.point[0] === p[0] && + h.point[1] === p[1]) { + return i; + } + } + + return -1; + } + + function processDatapoints() { + triggerCleanupEvent(); + doTriggerClickHoverEvent(lastMouseMoveEvent, eventType.hover); + } + + function setupGrid() { + doTriggerClickHoverEvent(lastMouseMoveEvent, eventType.hover); + } + + function drawOverlay(plot, octx, overlay) { + var plotOffset = plot.getPlotOffset(), + i, hi; + + octx.save(); + octx.translate(plotOffset.left, plotOffset.top); + for (i = 0; i < highlights.length; ++i) { + hi = highlights[i]; + + if (hi.series.bars.show) drawBarHighlight(hi.series, hi.point, octx); + else drawPointHighlight(hi.series, hi.point, octx, plot); + } + octx.restore(); + } + + function drawPointHighlight(series, point, octx, plot) { + var x = point[0], + y = point[1], + axisx = series.xaxis, + axisy = series.yaxis, + highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); + + if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) { + return; + } + + var pointRadius = series.points.radius + series.points.lineWidth / 2; + octx.lineWidth = pointRadius; + octx.strokeStyle = highlightColor; + var radius = 1.5 * pointRadius; + x = axisx.p2c(x); + y = axisy.p2c(y); + + octx.beginPath(); + var symbol = series.points.symbol; + if (symbol === 'circle') { + octx.arc(x, y, radius, 0, 2 * Math.PI, false); + } else if (typeof symbol === 'string' && plot.drawSymbol && plot.drawSymbol[symbol]) { + plot.drawSymbol[symbol](octx, x, y, radius, false); + } + + octx.closePath(); + octx.stroke(); + } + + function drawBarHighlight(series, point, octx) { + var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), + fillStyle = highlightColor, + barLeft; + + var barWidth = series.bars.barWidth[0] || series.bars.barWidth; + switch (series.bars.align) { + case "left": + barLeft = 0; + break; + case "right": + barLeft = -barWidth; + break; + default: + barLeft = -barWidth / 2; + } + + octx.lineWidth = series.bars.lineWidth; + octx.strokeStyle = highlightColor; + + var fillTowards = series.bars.fillTowards || 0, + bottom = fillTowards > series.yaxis.min ? Math.min(series.yaxis.max, fillTowards) : series.yaxis.min; + + $.plot.drawSeries.drawBar(point[0], point[1], point[2] || bottom, barLeft, barLeft + barWidth, + function() { + return fillStyle; + }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); + } + + function initHover(plot, options) { + plot.highlight = highlight; + plot.unhighlight = unhighlight; + if (options.grid.hoverable || options.grid.clickable) { + plot.hooks.drawOverlay.push(drawOverlay); + plot.hooks.processDatapoints.push(processDatapoints); + plot.hooks.setupGrid.push(setupGrid); + } + + lastMouseMoveEvent = plot.getPlaceholder()[0].lastMouseMoveEvent; + } + + plot.hooks.bindEvents.push(bindEvents); + plot.hooks.shutdown.push(shutdown); + plot.hooks.processOptions.push(initHover); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'hover', + version: '0.1' + }); +})(jQuery); |