mirror of https://github.com/grafana/grafana
Merge pull request #11469 from grafana/jquery-flot-events-to-ts
migrated jquery.flot.events to tspull/12691/head
commit
dde484be60
@ -1,604 +0,0 @@ |
||||
define([ |
||||
'jquery', |
||||
'lodash', |
||||
'angular', |
||||
'tether-drop', |
||||
], |
||||
function ($, _, angular, Drop) { |
||||
'use strict'; |
||||
|
||||
function createAnnotationToolip(element, event, plot) { |
||||
var injector = angular.element(document).injector(); |
||||
var content = document.createElement('div'); |
||||
content.innerHTML = '<annotation-tooltip event="event" on-edit="onEdit()"></annotation-tooltip>'; |
||||
|
||||
injector.invoke(["$compile", "$rootScope", function($compile, $rootScope) { |
||||
var eventManager = plot.getOptions().events.manager; |
||||
var tmpScope = $rootScope.$new(true); |
||||
tmpScope.event = event; |
||||
tmpScope.onEdit = function() { |
||||
eventManager.editEvent(event); |
||||
}; |
||||
|
||||
$compile(content)(tmpScope); |
||||
tmpScope.$digest(); |
||||
tmpScope.$destroy(); |
||||
|
||||
var drop = new Drop({ |
||||
target: element[0], |
||||
content: content, |
||||
position: "bottom center", |
||||
classes: 'drop-popover drop-popover--annotation', |
||||
openOn: 'hover', |
||||
hoverCloseDelay: 200, |
||||
tetherOptions: { |
||||
constraints: [{to: 'window', pin: true, attachment: "both"}] |
||||
} |
||||
}); |
||||
|
||||
drop.open(); |
||||
|
||||
drop.on('close', function() { |
||||
setTimeout(function() { |
||||
drop.destroy(); |
||||
}); |
||||
}); |
||||
}]); |
||||
} |
||||
|
||||
var markerElementToAttachTo = null; |
||||
|
||||
function createEditPopover(element, event, plot) { |
||||
var eventManager = plot.getOptions().events.manager; |
||||
if (eventManager.editorOpen) { |
||||
// update marker element to attach to (needed in case of legend on the right
|
||||
// when there is a double render pass and the initial marker element is removed)
|
||||
markerElementToAttachTo = element; |
||||
return; |
||||
} |
||||
|
||||
// mark as openend
|
||||
eventManager.editorOpened(); |
||||
// set marker element to attache to
|
||||
markerElementToAttachTo = element; |
||||
|
||||
// wait for element to be attached and positioned
|
||||
setTimeout(function() { |
||||
|
||||
var injector = angular.element(document).injector(); |
||||
var content = document.createElement('div'); |
||||
content.innerHTML = '<event-editor panel-ctrl="panelCtrl" event="event" close="close()"></event-editor>'; |
||||
|
||||
injector.invoke(["$compile", "$rootScope", function($compile, $rootScope) { |
||||
var scope = $rootScope.$new(true); |
||||
var drop; |
||||
|
||||
scope.event = event; |
||||
scope.panelCtrl = eventManager.panelCtrl; |
||||
scope.close = function() { |
||||
drop.close(); |
||||
}; |
||||
|
||||
$compile(content)(scope); |
||||
scope.$digest(); |
||||
|
||||
drop = new Drop({ |
||||
target: markerElementToAttachTo[0], |
||||
content: content, |
||||
position: "bottom center", |
||||
classes: 'drop-popover drop-popover--form', |
||||
openOn: 'click', |
||||
tetherOptions: { |
||||
constraints: [{to: 'window', pin: true, attachment: "both"}] |
||||
} |
||||
}); |
||||
|
||||
drop.open(); |
||||
eventManager.editorOpened(); |
||||
|
||||
drop.on('close', function() { |
||||
// need timeout here in order call drop.destroy
|
||||
setTimeout(function() { |
||||
eventManager.editorClosed(); |
||||
scope.$destroy(); |
||||
drop.destroy(); |
||||
}); |
||||
}); |
||||
}]); |
||||
|
||||
}, 100); |
||||
} |
||||
|
||||
/* |
||||
* jquery.flot.events |
||||
* |
||||
* description: Flot plugin for adding events/markers to the plot |
||||
* version: 0.2.5 |
||||
* authors: |
||||
* Alexander Wunschik <alex@wunschik.net> |
||||
* Joel Oughton <joeloughton@gmail.com> |
||||
* Nicolas Joseph <www.nicolasjoseph.com> |
||||
* |
||||
* website: https://github.com/mojoaxel/flot-events
|
||||
* |
||||
* released under MIT License and GPLv2+ |
||||
*/ |
||||
|
||||
/** |
||||
* A class that allows for the drawing an remove of some object |
||||
*/ |
||||
var DrawableEvent = function(object, drawFunc, clearFunc, moveFunc, left, top, width, height) { |
||||
var _object = object; |
||||
var _drawFunc = drawFunc; |
||||
var _clearFunc = clearFunc; |
||||
var _moveFunc = moveFunc; |
||||
var _position = { left: left, top: top }; |
||||
var _width = width; |
||||
var _height = height; |
||||
|
||||
this.width = function() { return _width; }; |
||||
this.height = function() { return _height; }; |
||||
this.position = function() { return _position; }; |
||||
this.draw = function() { _drawFunc(_object); }; |
||||
this.clear = function() { _clearFunc(_object); }; |
||||
this.getObject = function() { return _object; }; |
||||
this.moveTo = function(position) { |
||||
_position = position; |
||||
_moveFunc(_object, _position); |
||||
}; |
||||
}; |
||||
|
||||
/** |
||||
* Event class that stores options (eventType, min, max, title, description) and the object to draw. |
||||
*/ |
||||
var VisualEvent = function(options, drawableEvent) { |
||||
var _parent; |
||||
var _options = options; |
||||
var _drawableEvent = drawableEvent; |
||||
var _hidden = false; |
||||
|
||||
this.visual = function() { return _drawableEvent; }; |
||||
this.getOptions = function() { return _options; }; |
||||
this.getParent = function() { return _parent; }; |
||||
this.isHidden = function() { return _hidden; }; |
||||
this.hide = function() { _hidden = true; }; |
||||
this.unhide = function() { _hidden = false; }; |
||||
}; |
||||
|
||||
/** |
||||
* A Class that handles the event-markers inside the given plot |
||||
*/ |
||||
var EventMarkers = function(plot) { |
||||
var _events = []; |
||||
|
||||
this._types = []; |
||||
this._plot = plot; |
||||
this.eventsEnabled = false; |
||||
|
||||
this.getEvents = function() { |
||||
return _events; |
||||
}; |
||||
|
||||
this.setTypes = function(types) { |
||||
return this._types = types; |
||||
}; |
||||
|
||||
/** |
||||
* create internal objects for the given events |
||||
*/ |
||||
this.setupEvents = function(events) { |
||||
var that = this; |
||||
var parts = _.partition(events, 'isRegion'); |
||||
var regions = parts[0]; |
||||
events = parts[1]; |
||||
|
||||
$.each(events, function(index, event) { |
||||
var ve = new VisualEvent(event, that._buildDiv(event)); |
||||
_events.push(ve); |
||||
}); |
||||
|
||||
$.each(regions, function (index, event) { |
||||
var vre = new VisualEvent(event, that._buildRegDiv(event)); |
||||
_events.push(vre); |
||||
}); |
||||
|
||||
_events.sort(function(a, b) { |
||||
var ao = a.getOptions(), bo = b.getOptions(); |
||||
if (ao.min > bo.min) { return 1; } |
||||
if (ao.min < bo.min) { return -1; } |
||||
return 0; |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* draw the events to the plot |
||||
*/ |
||||
this.drawEvents = function() { |
||||
var that = this; |
||||
// var o = this._plot.getPlotOffset();
|
||||
|
||||
$.each(_events, function(index, event) { |
||||
// check event is inside the graph range
|
||||
if (that._insidePlot(event.getOptions().min) && !event.isHidden()) { |
||||
event.visual().draw(); |
||||
} else { |
||||
event.visual().getObject().hide(); |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* update the position of the event-markers (e.g. after scrolling or zooming) |
||||
*/ |
||||
this.updateEvents = function() { |
||||
var that = this; |
||||
var o = this._plot.getPlotOffset(), left, top; |
||||
var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; |
||||
|
||||
$.each(_events, function(index, event) { |
||||
top = o.top + that._plot.height() - event.visual().height(); |
||||
left = xaxis.p2c(event.getOptions().min) + o.left - event.visual().width() / 2; |
||||
event.visual().moveTo({ top: top, left: left }); |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* remove all events from the plot |
||||
*/ |
||||
this._clearEvents = function() { |
||||
$.each(_events, function(index, val) { |
||||
val.visual().clear(); |
||||
}); |
||||
_events = []; |
||||
}; |
||||
|
||||
/** |
||||
* create a DOM element for the given event |
||||
*/ |
||||
this._buildDiv = function(event) { |
||||
var that = this; |
||||
|
||||
var container = this._plot.getPlaceholder(); |
||||
var o = this._plot.getPlotOffset(); |
||||
var axes = this._plot.getAxes(); |
||||
var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; |
||||
var yaxis, top, left, color, markerSize, markerShow, lineStyle, lineWidth; |
||||
var markerTooltip; |
||||
|
||||
// determine the y axis used
|
||||
if (axes.yaxis && axes.yaxis.used) { yaxis = axes.yaxis; } |
||||
if (axes.yaxis2 && axes.yaxis2.used) { yaxis = axes.yaxis2; } |
||||
|
||||
// map the eventType to a types object
|
||||
var eventTypeId = event.eventType; |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) { |
||||
color = '#666'; |
||||
} else { |
||||
color = this._types[eventTypeId].color; |
||||
} |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].markerSize) { |
||||
markerSize = 8; //default marker size
|
||||
} else { |
||||
markerSize = this._types[eventTypeId].markerSize; |
||||
} |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerShow === undefined) { |
||||
markerShow = true; |
||||
} else { |
||||
markerShow = this._types[eventTypeId].markerShow; |
||||
} |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerTooltip === undefined) { |
||||
markerTooltip = true; |
||||
} else { |
||||
markerTooltip = this._types[eventTypeId].markerTooltip; |
||||
} |
||||
|
||||
if (this._types == null || !this._types[eventTypeId] || !this._types[eventTypeId].lineStyle) { |
||||
lineStyle = 'dashed'; //default line style
|
||||
} else { |
||||
lineStyle = this._types[eventTypeId].lineStyle.toLowerCase(); |
||||
} |
||||
|
||||
if (this._types == null || !this._types[eventTypeId] || this._types[eventTypeId].lineWidth === undefined) { |
||||
lineWidth = 1; //default line width
|
||||
} else { |
||||
lineWidth = this._types[eventTypeId].lineWidth; |
||||
} |
||||
|
||||
var topOffset = xaxis.options.eventSectionHeight || 0; |
||||
topOffset = topOffset / 3; |
||||
|
||||
top = o.top + this._plot.height() + topOffset; |
||||
left = xaxis.p2c(event.min) + o.left; |
||||
|
||||
var line = $('<div class="events_line flot-temp-elem"></div>').css({ |
||||
"position": "absolute", |
||||
"opacity": 0.8, |
||||
"left": left + 'px', |
||||
"top": 8, |
||||
"width": lineWidth + "px", |
||||
"height": this._plot.height() + topOffset * 0.8, |
||||
"border-left-width": lineWidth + "px", |
||||
"border-left-style": lineStyle, |
||||
"border-left-color": color, |
||||
"color": color |
||||
}) |
||||
.appendTo(container); |
||||
|
||||
if (markerShow) { |
||||
var marker = $('<div class="events_marker"></div>').css({ |
||||
"position": "absolute", |
||||
"left": (-markerSize - Math.round(lineWidth / 2)) + "px", |
||||
"font-size": 0, |
||||
"line-height": 0, |
||||
"width": 0, |
||||
"height": 0, |
||||
"border-left": markerSize+"px solid transparent", |
||||
"border-right": markerSize+"px solid transparent" |
||||
}); |
||||
|
||||
marker.appendTo(line); |
||||
|
||||
if (this._types[eventTypeId] && this._types[eventTypeId].position && this._types[eventTypeId].position.toUpperCase() === 'BOTTOM') { |
||||
marker.css({ |
||||
"top": top-markerSize-8 +"px", |
||||
"border-top": "none", |
||||
"border-bottom": markerSize+"px solid " + color |
||||
}); |
||||
} else { |
||||
marker.css({ |
||||
"top": "0px", |
||||
"border-top": markerSize+"px solid " + color, |
||||
"border-bottom": "none" |
||||
}); |
||||
} |
||||
|
||||
marker.data({ |
||||
"event": event |
||||
}); |
||||
|
||||
var mouseenter = function() { |
||||
createAnnotationToolip(marker, $(this).data("event"), that._plot); |
||||
}; |
||||
|
||||
if (event.editModel) { |
||||
createEditPopover(marker, event.editModel, that._plot); |
||||
} |
||||
|
||||
var mouseleave = function() { |
||||
that._plot.clearSelection(); |
||||
}; |
||||
|
||||
if (markerTooltip) { |
||||
marker.css({ "cursor": "help" }); |
||||
marker.hover(mouseenter, mouseleave); |
||||
} |
||||
} |
||||
|
||||
var drawableEvent = new DrawableEvent( |
||||
line, |
||||
function drawFunc(obj) { obj.show(); }, |
||||
function(obj) { obj.remove(); }, |
||||
function(obj, position) { |
||||
obj.css({ |
||||
top: position.top, |
||||
left: position.left |
||||
}); |
||||
}, |
||||
left, |
||||
top, |
||||
line.width(), |
||||
line.height() |
||||
); |
||||
|
||||
return drawableEvent; |
||||
}; |
||||
|
||||
/** |
||||
* create a DOM element for the given region |
||||
*/ |
||||
this._buildRegDiv = function (event) { |
||||
var that = this; |
||||
|
||||
var container = this._plot.getPlaceholder(); |
||||
var o = this._plot.getPlotOffset(); |
||||
var axes = this._plot.getAxes(); |
||||
var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; |
||||
var yaxis, top, left, lineWidth, regionWidth, lineStyle, color, markerTooltip; |
||||
|
||||
// determine the y axis used
|
||||
if (axes.yaxis && axes.yaxis.used) { yaxis = axes.yaxis; } |
||||
if (axes.yaxis2 && axes.yaxis2.used) { yaxis = axes.yaxis2; } |
||||
|
||||
// map the eventType to a types object
|
||||
var eventTypeId = event.eventType; |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) { |
||||
color = '#666'; |
||||
} else { |
||||
color = this._types[eventTypeId].color; |
||||
} |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerTooltip === undefined) { |
||||
markerTooltip = true; |
||||
} else { |
||||
markerTooltip = this._types[eventTypeId].markerTooltip; |
||||
} |
||||
|
||||
if (this._types == null || !this._types[eventTypeId] || this._types[eventTypeId].lineWidth === undefined) { |
||||
lineWidth = 1; //default line width
|
||||
} else { |
||||
lineWidth = this._types[eventTypeId].lineWidth; |
||||
} |
||||
|
||||
if (this._types == null || !this._types[eventTypeId] || !this._types[eventTypeId].lineStyle) { |
||||
lineStyle = 'dashed'; //default line style
|
||||
} else { |
||||
lineStyle = this._types[eventTypeId].lineStyle.toLowerCase(); |
||||
} |
||||
|
||||
var topOffset = 2; |
||||
top = o.top + this._plot.height() + topOffset; |
||||
|
||||
var timeFrom = Math.min(event.min, event.timeEnd); |
||||
var timeTo = Math.max(event.min, event.timeEnd); |
||||
left = xaxis.p2c(timeFrom) + o.left; |
||||
var right = xaxis.p2c(timeTo) + o.left; |
||||
regionWidth = right - left; |
||||
|
||||
_.each([left, right], function(position) { |
||||
var line = $('<div class="events_line flot-temp-elem"></div>').css({ |
||||
"position": "absolute", |
||||
"opacity": 0.8, |
||||
"left": position + 'px', |
||||
"top": 8, |
||||
"width": lineWidth + "px", |
||||
"height": that._plot.height() + topOffset, |
||||
"border-left-width": lineWidth + "px", |
||||
"border-left-style": lineStyle, |
||||
"border-left-color": color, |
||||
"color": color |
||||
}); |
||||
line.appendTo(container); |
||||
}); |
||||
|
||||
var region = $('<div class="events_marker region_marker flot-temp-elem"></div>').css({ |
||||
"position": "absolute", |
||||
"opacity": 0.5, |
||||
"left": left + 'px', |
||||
"top": top, |
||||
"width": Math.round(regionWidth + lineWidth) + "px", |
||||
"height": "0.5rem", |
||||
"border-left-color": color, |
||||
"color": color, |
||||
"background-color": color |
||||
}); |
||||
region.appendTo(container); |
||||
|
||||
region.data({ |
||||
"event": event |
||||
}); |
||||
|
||||
var mouseenter = function () { |
||||
createAnnotationToolip(region, $(this).data("event"), that._plot); |
||||
}; |
||||
|
||||
if (event.editModel) { |
||||
createEditPopover(region, event.editModel, that._plot); |
||||
} |
||||
|
||||
var mouseleave = function () { |
||||
that._plot.clearSelection(); |
||||
}; |
||||
|
||||
if (markerTooltip) { |
||||
region.css({ "cursor": "help" }); |
||||
region.hover(mouseenter, mouseleave); |
||||
} |
||||
|
||||
var drawableEvent = new DrawableEvent( |
||||
region, |
||||
function drawFunc(obj) { obj.show(); }, |
||||
function (obj) { obj.remove(); }, |
||||
function (obj, position) { |
||||
obj.css({ |
||||
top: position.top, |
||||
left: position.left |
||||
}); |
||||
}, |
||||
left, |
||||
top, |
||||
region.width(), |
||||
region.height() |
||||
); |
||||
|
||||
return drawableEvent; |
||||
}; |
||||
|
||||
/** |
||||
* check if the event is inside visible range |
||||
*/ |
||||
this._insidePlot = function(x) { |
||||
var xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; |
||||
var xc = xaxis.p2c(x); |
||||
return xc > 0 && xc < xaxis.p2c(xaxis.max); |
||||
}; |
||||
}; |
||||
|
||||
/** |
||||
* initialize the plugin for the given plot |
||||
*/ |
||||
function init(plot) { |
||||
/*jshint validthis:true */ |
||||
var that = this; |
||||
var eventMarkers = new EventMarkers(plot); |
||||
|
||||
plot.getEvents = function() { |
||||
return eventMarkers._events; |
||||
}; |
||||
|
||||
plot.hideEvents = function() { |
||||
$.each(eventMarkers._events, function(index, event) { |
||||
event.visual().getObject().hide(); |
||||
}); |
||||
}; |
||||
|
||||
plot.showEvents = function() { |
||||
plot.hideEvents(); |
||||
$.each(eventMarkers._events, function(index, event) { |
||||
event.hide(); |
||||
}); |
||||
|
||||
that.eventMarkers.drawEvents(); |
||||
}; |
||||
|
||||
// change events on an existing plot
|
||||
plot.setEvents = function(events) { |
||||
if (eventMarkers.eventsEnabled) { |
||||
eventMarkers.setupEvents(events); |
||||
} |
||||
}; |
||||
|
||||
plot.hooks.processOptions.push(function(plot, options) { |
||||
// enable the plugin
|
||||
if (options.events.data != null) { |
||||
eventMarkers.eventsEnabled = true; |
||||
} |
||||
}); |
||||
|
||||
plot.hooks.draw.push(function(plot) { |
||||
var options = plot.getOptions(); |
||||
|
||||
if (eventMarkers.eventsEnabled) { |
||||
// check for first run
|
||||
if (eventMarkers.getEvents().length < 1) { |
||||
eventMarkers.setTypes(options.events.types); |
||||
eventMarkers.setupEvents(options.events.data); |
||||
} else { |
||||
eventMarkers.updateEvents(); |
||||
} |
||||
} |
||||
|
||||
eventMarkers.drawEvents(); |
||||
}); |
||||
} |
||||
|
||||
var defaultOptions = { |
||||
events: { |
||||
data: null, |
||||
types: null, |
||||
xaxis: 1, |
||||
position: 'BOTTOM' |
||||
} |
||||
}; |
||||
|
||||
$.plot.plugins.push({ |
||||
init: init, |
||||
options: defaultOptions, |
||||
name: "events", |
||||
version: "0.2.5" |
||||
}); |
||||
}); |
@ -0,0 +1,671 @@ |
||||
import angular from 'angular'; |
||||
import $ from 'jquery'; |
||||
import _ from 'lodash'; |
||||
import Drop from 'tether-drop'; |
||||
|
||||
/** @ngInject */ |
||||
export function createAnnotationToolip(element, event, plot) { |
||||
let injector = angular.element(document).injector(); |
||||
let content = document.createElement('div'); |
||||
content.innerHTML = '<annotation-tooltip event="event" on-edit="onEdit()"></annotation-tooltip>'; |
||||
|
||||
injector.invoke([ |
||||
'$compile', |
||||
'$rootScope', |
||||
function($compile, $rootScope) { |
||||
let eventManager = plot.getOptions().events.manager; |
||||
let tmpScope = $rootScope.$new(true); |
||||
tmpScope.event = event; |
||||
tmpScope.onEdit = function() { |
||||
eventManager.editEvent(event); |
||||
}; |
||||
|
||||
$compile(content)(tmpScope); |
||||
tmpScope.$digest(); |
||||
tmpScope.$destroy(); |
||||
|
||||
let drop = new Drop({ |
||||
target: element[0], |
||||
content: content, |
||||
position: 'bottom center', |
||||
classes: 'drop-popover drop-popover--annotation', |
||||
openOn: 'hover', |
||||
hoverCloseDelay: 200, |
||||
tetherOptions: { |
||||
constraints: [{ to: 'window', pin: true, attachment: 'both' }], |
||||
}, |
||||
}); |
||||
|
||||
drop.open(); |
||||
|
||||
drop.on('close', function() { |
||||
setTimeout(function() { |
||||
drop.destroy(); |
||||
}); |
||||
}); |
||||
}, |
||||
]); |
||||
} |
||||
|
||||
let markerElementToAttachTo = null; |
||||
|
||||
/** @ngInject */ |
||||
export function createEditPopover(element, event, plot) { |
||||
let eventManager = plot.getOptions().events.manager; |
||||
if (eventManager.editorOpen) { |
||||
// update marker element to attach to (needed in case of legend on the right
|
||||
// when there is a double render pass and the inital marker element is removed)
|
||||
markerElementToAttachTo = element; |
||||
return; |
||||
} |
||||
|
||||
// mark as openend
|
||||
eventManager.editorOpened(); |
||||
// set marker elment to attache to
|
||||
markerElementToAttachTo = element; |
||||
|
||||
// wait for element to be attached and positioned
|
||||
setTimeout(function() { |
||||
let injector = angular.element(document).injector(); |
||||
let content = document.createElement('div'); |
||||
content.innerHTML = '<event-editor panel-ctrl="panelCtrl" event="event" close="close()"></event-editor>'; |
||||
|
||||
injector.invoke([ |
||||
'$compile', |
||||
'$rootScope', |
||||
function($compile, $rootScope) { |
||||
let scope = $rootScope.$new(true); |
||||
let drop; |
||||
|
||||
scope.event = event; |
||||
scope.panelCtrl = eventManager.panelCtrl; |
||||
scope.close = function() { |
||||
drop.close(); |
||||
}; |
||||
|
||||
$compile(content)(scope); |
||||
scope.$digest(); |
||||
|
||||
drop = new Drop({ |
||||
target: markerElementToAttachTo[0], |
||||
content: content, |
||||
position: 'bottom center', |
||||
classes: 'drop-popover drop-popover--form', |
||||
openOn: 'click', |
||||
tetherOptions: { |
||||
constraints: [{ to: 'window', pin: true, attachment: 'both' }], |
||||
}, |
||||
}); |
||||
|
||||
drop.open(); |
||||
eventManager.editorOpened(); |
||||
|
||||
drop.on('close', function() { |
||||
// need timeout here in order call drop.destroy
|
||||
setTimeout(function() { |
||||
eventManager.editorClosed(); |
||||
scope.$destroy(); |
||||
drop.destroy(); |
||||
}); |
||||
}); |
||||
}, |
||||
]); |
||||
}, 100); |
||||
} |
||||
|
||||
/* |
||||
* jquery.flot.events |
||||
* |
||||
* description: Flot plugin for adding events/markers to the plot |
||||
* version: 0.2.5 |
||||
* authors: |
||||
* Alexander Wunschik <alex@wunschik.net> |
||||
* Joel Oughton <joeloughton@gmail.com> |
||||
* Nicolas Joseph <www.nicolasjoseph.com> |
||||
* |
||||
* website: https://github.com/mojoaxel/flot-events
|
||||
* |
||||
* released under MIT License and GPLv2+ |
||||
*/ |
||||
|
||||
/** |
||||
* A class that allows for the drawing an remove of some object |
||||
*/ |
||||
export class DrawableEvent { |
||||
_object: any; |
||||
_drawFunc: any; |
||||
_clearFunc: any; |
||||
_moveFunc: any; |
||||
_position: any; |
||||
_width: any; |
||||
_height: any; |
||||
|
||||
/** @ngInject */ |
||||
constructor(object, drawFunc, clearFunc, moveFunc, left, top, width, height) { |
||||
this._object = object; |
||||
this._drawFunc = drawFunc; |
||||
this._clearFunc = clearFunc; |
||||
this._moveFunc = moveFunc; |
||||
this._position = { left: left, top: top }; |
||||
this._width = width; |
||||
this._height = height; |
||||
} |
||||
|
||||
width() { |
||||
return this._width; |
||||
} |
||||
height() { |
||||
return this._height; |
||||
} |
||||
position() { |
||||
return this._position; |
||||
} |
||||
draw() { |
||||
this._drawFunc(this._object); |
||||
} |
||||
clear() { |
||||
this._clearFunc(this._object); |
||||
} |
||||
getObject() { |
||||
return this._object; |
||||
} |
||||
moveTo(position) { |
||||
this._position = position; |
||||
this._moveFunc(this._object, this._position); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Event class that stores options (eventType, min, max, title, description) and the object to draw. |
||||
*/ |
||||
export class VisualEvent { |
||||
_parent: any; |
||||
_options: any; |
||||
_drawableEvent: any; |
||||
_hidden: any; |
||||
|
||||
/** @ngInject */ |
||||
constructor(options, drawableEvent) { |
||||
this._options = options; |
||||
this._drawableEvent = drawableEvent; |
||||
this._hidden = false; |
||||
} |
||||
|
||||
visual() { |
||||
return this._drawableEvent; |
||||
} |
||||
getOptions() { |
||||
return this._options; |
||||
} |
||||
getParent() { |
||||
return this._parent; |
||||
} |
||||
isHidden() { |
||||
return this._hidden; |
||||
} |
||||
hide() { |
||||
this._hidden = true; |
||||
} |
||||
unhide() { |
||||
this._hidden = false; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* A Class that handles the event-markers inside the given plot |
||||
*/ |
||||
export class EventMarkers { |
||||
_events: any; |
||||
_types: any; |
||||
_plot: any; |
||||
eventsEnabled: any; |
||||
|
||||
/** @ngInject */ |
||||
constructor(plot) { |
||||
this._events = []; |
||||
this._types = []; |
||||
this._plot = plot; |
||||
this.eventsEnabled = false; |
||||
} |
||||
|
||||
getEvents() { |
||||
return this._events; |
||||
} |
||||
|
||||
setTypes(types) { |
||||
return (this._types = types); |
||||
} |
||||
|
||||
/** |
||||
* create internal objects for the given events |
||||
*/ |
||||
setupEvents(events) { |
||||
let parts = _.partition(events, 'isRegion'); |
||||
let regions = parts[0]; |
||||
events = parts[1]; |
||||
|
||||
$.each(events, (index, event) => { |
||||
let ve = new VisualEvent(event, this._buildDiv(event)); |
||||
this._events.push(ve); |
||||
}); |
||||
|
||||
$.each(regions, (index, event) => { |
||||
let vre = new VisualEvent(event, this._buildRegDiv(event)); |
||||
this._events.push(vre); |
||||
}); |
||||
|
||||
this._events.sort((a, b) => { |
||||
let ao = a.getOptions(), |
||||
bo = b.getOptions(); |
||||
if (ao.min > bo.min) { |
||||
return 1; |
||||
} |
||||
if (ao.min < bo.min) { |
||||
return -1; |
||||
} |
||||
return 0; |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* draw the events to the plot |
||||
*/ |
||||
drawEvents() { |
||||
// var o = this._plot.getPlotOffset();
|
||||
|
||||
$.each(this._events, (index, event) => { |
||||
// check event is inside the graph range
|
||||
if (this._insidePlot(event.getOptions().min) && !event.isHidden()) { |
||||
event.visual().draw(); |
||||
} else { |
||||
event |
||||
.visual() |
||||
.getObject() |
||||
.hide(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* update the position of the event-markers (e.g. after scrolling or zooming) |
||||
*/ |
||||
updateEvents() { |
||||
let o = this._plot.getPlotOffset(), |
||||
left, |
||||
top; |
||||
let xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; |
||||
|
||||
$.each(this._events, (index, event) => { |
||||
top = o.top + this._plot.height() - event.visual().height(); |
||||
left = xaxis.p2c(event.getOptions().min) + o.left - event.visual().width() / 2; |
||||
event.visual().moveTo({ top: top, left: left }); |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* remove all events from the plot |
||||
*/ |
||||
_clearEvents() { |
||||
$.each(this._events, (index, val) => { |
||||
val.visual().clear(); |
||||
}); |
||||
this._events = []; |
||||
} |
||||
|
||||
/** |
||||
* create a DOM element for the given event |
||||
*/ |
||||
_buildDiv(event) { |
||||
let that = this; |
||||
|
||||
let container = this._plot.getPlaceholder(); |
||||
let o = this._plot.getPlotOffset(); |
||||
let xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; |
||||
let top, left, color, markerSize, markerShow, lineStyle, lineWidth; |
||||
let markerTooltip; |
||||
|
||||
// map the eventType to a types object
|
||||
let eventTypeId = event.eventType; |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) { |
||||
color = '#666'; |
||||
} else { |
||||
color = this._types[eventTypeId].color; |
||||
} |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].markerSize) { |
||||
markerSize = 8; //default marker size
|
||||
} else { |
||||
markerSize = this._types[eventTypeId].markerSize; |
||||
} |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerShow === undefined) { |
||||
markerShow = true; |
||||
} else { |
||||
markerShow = this._types[eventTypeId].markerShow; |
||||
} |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerTooltip === undefined) { |
||||
markerTooltip = true; |
||||
} else { |
||||
markerTooltip = this._types[eventTypeId].markerTooltip; |
||||
} |
||||
|
||||
if (this._types == null || !this._types[eventTypeId] || !this._types[eventTypeId].lineStyle) { |
||||
lineStyle = 'dashed'; //default line style
|
||||
} else { |
||||
lineStyle = this._types[eventTypeId].lineStyle.toLowerCase(); |
||||
} |
||||
|
||||
if (this._types == null || !this._types[eventTypeId] || this._types[eventTypeId].lineWidth === undefined) { |
||||
lineWidth = 1; //default line width
|
||||
} else { |
||||
lineWidth = this._types[eventTypeId].lineWidth; |
||||
} |
||||
|
||||
let topOffset = xaxis.options.eventSectionHeight || 0; |
||||
topOffset = topOffset / 3; |
||||
|
||||
top = o.top + this._plot.height() + topOffset; |
||||
left = xaxis.p2c(event.min) + o.left; |
||||
|
||||
let line = $('<div class="events_line flot-temp-elem"></div>') |
||||
.css({ |
||||
position: 'absolute', |
||||
opacity: 0.8, |
||||
left: left + 'px', |
||||
top: 8, |
||||
width: lineWidth + 'px', |
||||
height: this._plot.height() + topOffset * 0.8, |
||||
'border-left-width': lineWidth + 'px', |
||||
'border-left-style': lineStyle, |
||||
'border-left-color': color, |
||||
color: color, |
||||
}) |
||||
.appendTo(container); |
||||
|
||||
if (markerShow) { |
||||
let marker = $('<div class="events_marker"></div>').css({ |
||||
position: 'absolute', |
||||
left: -markerSize - Math.round(lineWidth / 2) + 'px', |
||||
'font-size': 0, |
||||
'line-height': 0, |
||||
width: 0, |
||||
height: 0, |
||||
'border-left': markerSize + 'px solid transparent', |
||||
'border-right': markerSize + 'px solid transparent', |
||||
}); |
||||
|
||||
marker.appendTo(line); |
||||
|
||||
if ( |
||||
this._types[eventTypeId] && |
||||
this._types[eventTypeId].position && |
||||
this._types[eventTypeId].position.toUpperCase() === 'BOTTOM' |
||||
) { |
||||
marker.css({ |
||||
top: top - markerSize - 8 + 'px', |
||||
'border-top': 'none', |
||||
'border-bottom': markerSize + 'px solid ' + color, |
||||
}); |
||||
} else { |
||||
marker.css({ |
||||
top: '0px', |
||||
'border-top': markerSize + 'px solid ' + color, |
||||
'border-bottom': 'none', |
||||
}); |
||||
} |
||||
|
||||
marker.data({ |
||||
event: event, |
||||
}); |
||||
|
||||
let mouseenter = function() { |
||||
createAnnotationToolip(marker, $(this).data('event'), that._plot); |
||||
}; |
||||
|
||||
if (event.editModel) { |
||||
createEditPopover(marker, event.editModel, that._plot); |
||||
} |
||||
|
||||
let mouseleave = function() { |
||||
that._plot.clearSelection(); |
||||
}; |
||||
|
||||
if (markerTooltip) { |
||||
marker.css({ cursor: 'help' }); |
||||
marker.hover(mouseenter, mouseleave); |
||||
} |
||||
} |
||||
|
||||
let drawableEvent = new DrawableEvent( |
||||
line, |
||||
function drawFunc(obj) { |
||||
obj.show(); |
||||
}, |
||||
function(obj) { |
||||
obj.remove(); |
||||
}, |
||||
function(obj, position) { |
||||
obj.css({ |
||||
top: position.top, |
||||
left: position.left, |
||||
}); |
||||
}, |
||||
left, |
||||
top, |
||||
line.width(), |
||||
line.height() |
||||
); |
||||
|
||||
return drawableEvent; |
||||
} |
||||
|
||||
/** |
||||
* create a DOM element for the given region |
||||
*/ |
||||
_buildRegDiv(event) { |
||||
let that = this; |
||||
|
||||
let container = this._plot.getPlaceholder(); |
||||
let o = this._plot.getPlotOffset(); |
||||
let xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; |
||||
let top, left, lineWidth, regionWidth, lineStyle, color, markerTooltip; |
||||
|
||||
// map the eventType to a types object
|
||||
let eventTypeId = event.eventType; |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || !this._types[eventTypeId].color) { |
||||
color = '#666'; |
||||
} else { |
||||
color = this._types[eventTypeId].color; |
||||
} |
||||
|
||||
if (this._types === null || !this._types[eventTypeId] || this._types[eventTypeId].markerTooltip === undefined) { |
||||
markerTooltip = true; |
||||
} else { |
||||
markerTooltip = this._types[eventTypeId].markerTooltip; |
||||
} |
||||
|
||||
if (this._types == null || !this._types[eventTypeId] || this._types[eventTypeId].lineWidth === undefined) { |
||||
lineWidth = 1; //default line width
|
||||
} else { |
||||
lineWidth = this._types[eventTypeId].lineWidth; |
||||
} |
||||
|
||||
if (this._types == null || !this._types[eventTypeId] || !this._types[eventTypeId].lineStyle) { |
||||
lineStyle = 'dashed'; //default line style
|
||||
} else { |
||||
lineStyle = this._types[eventTypeId].lineStyle.toLowerCase(); |
||||
} |
||||
|
||||
let topOffset = 2; |
||||
top = o.top + this._plot.height() + topOffset; |
||||
|
||||
let timeFrom = Math.min(event.min, event.timeEnd); |
||||
let timeTo = Math.max(event.min, event.timeEnd); |
||||
left = xaxis.p2c(timeFrom) + o.left; |
||||
let right = xaxis.p2c(timeTo) + o.left; |
||||
regionWidth = right - left; |
||||
|
||||
_.each([left, right], position => { |
||||
let line = $('<div class="events_line flot-temp-elem"></div>').css({ |
||||
position: 'absolute', |
||||
opacity: 0.8, |
||||
left: position + 'px', |
||||
top: 8, |
||||
width: lineWidth + 'px', |
||||
height: this._plot.height() + topOffset, |
||||
'border-left-width': lineWidth + 'px', |
||||
'border-left-style': lineStyle, |
||||
'border-left-color': color, |
||||
color: color, |
||||
}); |
||||
line.appendTo(container); |
||||
}); |
||||
|
||||
let region = $('<div class="events_marker region_marker flot-temp-elem"></div>').css({ |
||||
position: 'absolute', |
||||
opacity: 0.5, |
||||
left: left + 'px', |
||||
top: top, |
||||
width: Math.round(regionWidth + lineWidth) + 'px', |
||||
height: '0.5rem', |
||||
'border-left-color': color, |
||||
color: color, |
||||
'background-color': color, |
||||
}); |
||||
region.appendTo(container); |
||||
|
||||
region.data({ |
||||
event: event, |
||||
}); |
||||
|
||||
let mouseenter = function() { |
||||
createAnnotationToolip(region, $(this).data('event'), that._plot); |
||||
}; |
||||
|
||||
if (event.editModel) { |
||||
createEditPopover(region, event.editModel, that._plot); |
||||
} |
||||
|
||||
let mouseleave = function() { |
||||
that._plot.clearSelection(); |
||||
}; |
||||
|
||||
if (markerTooltip) { |
||||
region.css({ cursor: 'help' }); |
||||
region.hover(mouseenter, mouseleave); |
||||
} |
||||
|
||||
let drawableEvent = new DrawableEvent( |
||||
region, |
||||
function drawFunc(obj) { |
||||
obj.show(); |
||||
}, |
||||
function(obj) { |
||||
obj.remove(); |
||||
}, |
||||
function(obj, position) { |
||||
obj.css({ |
||||
top: position.top, |
||||
left: position.left, |
||||
}); |
||||
}, |
||||
left, |
||||
top, |
||||
region.width(), |
||||
region.height() |
||||
); |
||||
|
||||
return drawableEvent; |
||||
} |
||||
|
||||
/** |
||||
* check if the event is inside visible range |
||||
*/ |
||||
_insidePlot(x) { |
||||
let xaxis = this._plot.getXAxes()[this._plot.getOptions().events.xaxis - 1]; |
||||
let xc = xaxis.p2c(x); |
||||
return xc > 0 && xc < xaxis.p2c(xaxis.max); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* initialize the plugin for the given plot |
||||
*/ |
||||
|
||||
/** @ngInject */ |
||||
export function init(plot) { |
||||
/*jshint validthis:true */ |
||||
let that = this; |
||||
let eventMarkers = new EventMarkers(plot); |
||||
|
||||
plot.getEvents = function() { |
||||
return eventMarkers._events; |
||||
}; |
||||
|
||||
plot.hideEvents = function() { |
||||
$.each(eventMarkers._events, (index, event) => { |
||||
event |
||||
.visual() |
||||
.getObject() |
||||
.hide(); |
||||
}); |
||||
}; |
||||
|
||||
plot.showEvents = function() { |
||||
plot.hideEvents(); |
||||
$.each(eventMarkers._events, (index, event) => { |
||||
event.hide(); |
||||
}); |
||||
|
||||
that.eventMarkers.drawEvents(); |
||||
}; |
||||
|
||||
// change events on an existing plot
|
||||
plot.setEvents = function(events) { |
||||
if (eventMarkers.eventsEnabled) { |
||||
eventMarkers.setupEvents(events); |
||||
} |
||||
}; |
||||
|
||||
plot.hooks.processOptions.push(function(plot, options) { |
||||
// enable the plugin
|
||||
if (options.events.data != null) { |
||||
eventMarkers.eventsEnabled = true; |
||||
} |
||||
}); |
||||
|
||||
plot.hooks.draw.push(function(plot) { |
||||
let options = plot.getOptions(); |
||||
|
||||
if (eventMarkers.eventsEnabled) { |
||||
// check for first run
|
||||
if (eventMarkers.getEvents().length < 1) { |
||||
eventMarkers.setTypes(options.events.types); |
||||
eventMarkers.setupEvents(options.events.data); |
||||
} else { |
||||
eventMarkers.updateEvents(); |
||||
} |
||||
} |
||||
|
||||
eventMarkers.drawEvents(); |
||||
}); |
||||
} |
||||
|
||||
let defaultOptions = { |
||||
events: { |
||||
data: null, |
||||
types: null, |
||||
xaxis: 1, |
||||
position: 'BOTTOM', |
||||
}, |
||||
}; |
||||
|
||||
$.plot.plugins.push({ |
||||
init: init, |
||||
options: defaultOptions, |
||||
name: 'events', |
||||
version: '0.2.5', |
||||
}); |
Loading…
Reference in new issue