mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
progess on adding annotations
This commit is contained in:
parent
0335c1f368
commit
a151de1d37
@ -1,8 +1,9 @@
|
||||
|
||||
import {AnnotationsSrv} from './annotations_srv';
|
||||
import {eventEditor} from './event_editor';
|
||||
import {eventEditor, EventManager} from './event_editor';
|
||||
|
||||
export {
|
||||
AnnotationsSrv,
|
||||
eventEditor
|
||||
eventEditor,
|
||||
EventManager
|
||||
};
|
||||
|
@ -17,22 +17,15 @@ export class AnnotationEvent {
|
||||
|
||||
export class EventEditorCtrl {
|
||||
panelCtrl: MetricsPanelCtrl;
|
||||
annotation: AnnotationEvent;
|
||||
event: AnnotationEvent;
|
||||
timeRange: {from: number, to: number};
|
||||
form: any;
|
||||
close: any;
|
||||
|
||||
/** @ngInject **/
|
||||
constructor(private annotationsSrv) {
|
||||
this.annotation = new AnnotationEvent();
|
||||
this.annotation.panelId = this.panelCtrl.panel.id;
|
||||
this.annotation.dashboardId = this.panelCtrl.dashboard.id;
|
||||
|
||||
this.annotation.time = moment(this.timeRange.from);
|
||||
if (this.timeRange.to) {
|
||||
this.annotation.timeEnd = moment(this.timeRange.to);
|
||||
this.annotation.isRegion = true;
|
||||
}
|
||||
this.event.panelId = this.panelCtrl.panel.id;
|
||||
this.event.dashboardId = this.panelCtrl.dashboard.id;
|
||||
}
|
||||
|
||||
save() {
|
||||
@ -40,15 +33,17 @@ export class EventEditorCtrl {
|
||||
return;
|
||||
}
|
||||
|
||||
let saveModel = _.cloneDeep(this.annotation);
|
||||
let saveModel = _.cloneDeep(this.event);
|
||||
saveModel.time = saveModel.time.valueOf();
|
||||
saveModel.timeEnd = 0;
|
||||
|
||||
if (saveModel.isRegion) {
|
||||
saveModel.timeEnd = saveModel.timeEnd.valueOf();
|
||||
}
|
||||
|
||||
if (saveModel.timeEnd < saveModel.time) {
|
||||
console.log('invalid time');
|
||||
return;
|
||||
if (saveModel.timeEnd < saveModel.time) {
|
||||
console.log('invalid time');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.annotationsSrv.saveAnnotationEvent(saveModel).then(() => {
|
||||
@ -56,6 +51,10 @@ export class EventEditorCtrl {
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
|
||||
timeChanged() {
|
||||
this.panelCtrl.render();
|
||||
}
|
||||
}
|
||||
|
||||
export function eventEditor() {
|
||||
@ -67,10 +66,68 @@ export function eventEditor() {
|
||||
templateUrl: 'public/app/features/annotations/partials/event_editor.html',
|
||||
scope: {
|
||||
"panelCtrl": "=",
|
||||
"timeRange": "=",
|
||||
"event": "=",
|
||||
"close": "&",
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
coreModule.directive('eventEditor', eventEditor);
|
||||
|
||||
export class EventManager {
|
||||
event: AnnotationEvent;
|
||||
|
||||
constructor(private panelCtrl: MetricsPanelCtrl,
|
||||
private elem,
|
||||
private popoverSrv) {
|
||||
}
|
||||
|
||||
editorClosed() {
|
||||
console.log('editorClosed');
|
||||
this.event = null;
|
||||
this.panelCtrl.render();
|
||||
}
|
||||
|
||||
updateTime(range) {
|
||||
let newEvent = true;
|
||||
|
||||
if (this.event) {
|
||||
newEvent = false;
|
||||
} else {
|
||||
// init new event
|
||||
this.event = new AnnotationEvent();
|
||||
this.event.dashboardId = this.panelCtrl.dashboard.id;
|
||||
this.event.panelId = this.panelCtrl.panel.id;
|
||||
}
|
||||
|
||||
// update time
|
||||
this.event.time = moment(range.from);
|
||||
this.event.isRegion = false;
|
||||
if (range.to) {
|
||||
this.event.timeEnd = moment(range.to);
|
||||
this.event.isRegion = true;
|
||||
}
|
||||
|
||||
// newEvent means the editor is not visible
|
||||
if (!newEvent) {
|
||||
this.panelCtrl.render();
|
||||
return;
|
||||
}
|
||||
|
||||
this.popoverSrv.show({
|
||||
element: this.elem[0],
|
||||
classNames: 'drop-popover drop-popover--form',
|
||||
position: 'bottom center',
|
||||
openOn: null,
|
||||
template: '<event-editor panel-ctrl="panelCtrl" event="event" close="dismiss()"></event-editor>',
|
||||
onClose: this.editorClosed.bind(this),
|
||||
model: {
|
||||
event: this.event,
|
||||
panelCtrl: this.panelCtrl,
|
||||
},
|
||||
});
|
||||
|
||||
this.panelCtrl.render();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,29 +5,29 @@
|
||||
<div style="display: inline-block">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Title</span>
|
||||
<input type="text" ng-model="ctrl.annotation.title" class="gf-form-input max-width-20" required>
|
||||
<input type="text" ng-model="ctrl.event.title" class="gf-form-input max-width-20" required>
|
||||
</div>
|
||||
<!-- single event -->
|
||||
<div ng-if="!ctrl.annotation.isRegion">
|
||||
<div ng-if="!ctrl.event.isRegion">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Time</span>
|
||||
<input type="text" ng-model="ctrl.annotation.time" class="gf-form-input max-width-20" input-datetime required>
|
||||
<input type="text" ng-model="ctrl.event.time" class="gf-form-input max-width-20" input-datetime required ng-change="ctrl.timeChanged()">
|
||||
</div>
|
||||
</div>
|
||||
<!-- region event -->
|
||||
<div ng-if="ctrl.annotation.isRegion">
|
||||
<div ng-if="ctrl.event.isRegion">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">Start</span>
|
||||
<input type="text" ng-model="ctrl.annotation.time" class="gf-form-input max-width-20" input-datetime required>
|
||||
<input type="text" ng-model="ctrl.event.time" class="gf-form-input max-width-20" input-datetime required ng-change="ctrl.timeChanged()">
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-7">End</span>
|
||||
<input type="text" ng-model="ctrl.annotation.timeEnd" class="gf-form-input max-width-20" input-datetime required>
|
||||
<input type="text" ng-model="ctrl.event.timeEnd" class="gf-form-input max-width-20" input-datetime required ng-change="ctrl.timeChanged()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form gf-form--v-stretch">
|
||||
<span class="gf-form-label width-7">Description</span>
|
||||
<textarea class="gf-form-input width-20" rows="3" ng-model="ctrl.annotation.text" placeholder="Event description"></textarea>
|
||||
<textarea class="gf-form-input width-20" rows="3" ng-model="ctrl.event.text" placeholder="Event description"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
|
@ -17,6 +17,7 @@ import {tickStep} from 'app/core/utils/ticks';
|
||||
import {appEvents, coreModule} from 'app/core/core';
|
||||
import GraphTooltip from './graph_tooltip';
|
||||
import {ThresholdManager} from './threshold_manager';
|
||||
import {EventManager} from 'app/features/annotations/all';
|
||||
import {convertValuesToHistogram, getSeriesValues} from './histogram';
|
||||
|
||||
coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
@ -27,13 +28,14 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
var ctrl = scope.ctrl;
|
||||
var dashboard = ctrl.dashboard;
|
||||
var panel = ctrl.panel;
|
||||
var annotations = [];
|
||||
var data;
|
||||
var annotations;
|
||||
var plot;
|
||||
var sortedSeries;
|
||||
var legendSideLastValue = null;
|
||||
var rootScope = scope.$root;
|
||||
var panelWidth = 0;
|
||||
var eventManager = new EventManager(ctrl, elem, popoverSrv);
|
||||
var thresholdManager = new ThresholdManager(ctrl);
|
||||
var tooltip = new GraphTooltip(elem, dashboard, scope, function() {
|
||||
return sortedSeries;
|
||||
@ -54,7 +56,7 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
annotations = ctrl.annotations;
|
||||
annotations = ctrl.annotations || [];
|
||||
render_panel();
|
||||
});
|
||||
|
||||
@ -79,20 +81,6 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
}
|
||||
}, scope);
|
||||
|
||||
function showAddAnnotationView(timeRange) {
|
||||
popoverSrv.show({
|
||||
element: elem[0],
|
||||
classNames: 'drop-popover drop-popover--form',
|
||||
position: 'bottom center',
|
||||
openOn: 'click',
|
||||
template: '<event-editor panel-ctrl="panelCtrl" time-range="timeRange" close="dismiss()"></event-editor>',
|
||||
model: {
|
||||
timeRange: timeRange,
|
||||
panelCtrl: ctrl,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function getLegendHeight(panelHeight) {
|
||||
if (!panel.legend.show || panel.legend.rightSide) {
|
||||
return 0;
|
||||
@ -343,7 +331,7 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
}
|
||||
|
||||
thresholdManager.addPlotOptions(options, panel);
|
||||
addAnnotations(options);
|
||||
addAnnotationEvents(options);
|
||||
configureAxisOptions(data, options);
|
||||
|
||||
sortedSeries = _.sortBy(data, function(series) { return series.zindex; });
|
||||
@ -475,8 +463,12 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
};
|
||||
}
|
||||
|
||||
function addAnnotations(options) {
|
||||
if (!annotations || annotations.length === 0) {
|
||||
function hasAnnotationEvents() {
|
||||
return eventManager.event || annotations.length > 0 ;
|
||||
}
|
||||
|
||||
function addAnnotationEvents(options) {
|
||||
if (!hasAnnotationEvents()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -501,26 +493,41 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
|
||||
types['$__execution_error'] = ['$__no_data'];
|
||||
|
||||
for (var i = 0; i < annotations.length; i++) {
|
||||
var item = annotations[i];
|
||||
if (item.newState) {
|
||||
console.log(item.newState);
|
||||
item.eventType = '$__' + item.newState;
|
||||
continue;
|
||||
}
|
||||
var annotationsToShow;
|
||||
// adding/edditing event, only show that one
|
||||
if (eventManager.event) {
|
||||
const event = eventManager.event;
|
||||
annotationsToShow = [
|
||||
{
|
||||
min: event.time.valueOf(),
|
||||
title: event.title,
|
||||
description: event.text,
|
||||
eventType: '$__alerting',
|
||||
}
|
||||
];
|
||||
} else {
|
||||
// annotations from query
|
||||
for (var i = 0; i < annotations.length; i++) {
|
||||
var item = annotations[i];
|
||||
if (item.newState) {
|
||||
item.eventType = '$__' + item.newState;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!types[item.source.name]) {
|
||||
types[item.source.name] = {
|
||||
color: item.source.iconColor,
|
||||
position: 'BOTTOM',
|
||||
markerSize: 5,
|
||||
};
|
||||
if (!types[item.source.name]) {
|
||||
types[item.source.name] = {
|
||||
color: item.source.iconColor,
|
||||
position: 'BOTTOM',
|
||||
markerSize: 5,
|
||||
};
|
||||
}
|
||||
}
|
||||
annotationsToShow = annotations;
|
||||
}
|
||||
|
||||
options.events = {
|
||||
levels: _.keys(types).length + 1,
|
||||
data: annotations,
|
||||
data: annotationsToShow,
|
||||
types: types,
|
||||
};
|
||||
}
|
||||
@ -653,8 +660,10 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
}
|
||||
|
||||
elem.bind("plotselected", function (event, ranges) {
|
||||
if (ranges.ctrlKey || ranges.metaKey) {
|
||||
showAddAnnotationView(ranges.xaxis);
|
||||
if (ranges.ctrlKey || ranges.metaKey) {
|
||||
scope.$apply(() => {
|
||||
eventManager.updateTime(ranges.xaxis);
|
||||
});
|
||||
} else {
|
||||
scope.$apply(function() {
|
||||
timeSrv.setTime({
|
||||
@ -666,11 +675,14 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) {
|
||||
});
|
||||
|
||||
elem.bind("plotclick", function (event, pos, item) {
|
||||
// Skip if range selected (added in "plotselected" event handler)
|
||||
let isRangeSelection = pos.x !== pos.x1;
|
||||
let createAnnotation = !isRangeSelection && (pos.ctrlKey || pos.metaKey);
|
||||
if (createAnnotation) {
|
||||
showAddAnnotationView({from: pos.x, to: null});
|
||||
if (pos.ctrlKey || pos.metaKey || eventManager.event) {
|
||||
// Skip if range selected (added in "plotselected" event handler)
|
||||
let isRangeSelection = pos.x !== pos.x1;
|
||||
if (!isRangeSelection) {
|
||||
scope.$apply(() => {
|
||||
eventManager.updateTime({from: pos.x, to: null});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user