Commit f0f4c8cc by Torkel Ödegaard

A lot more work on annotations (#44, #8). Graphite events is working, editing,…

A lot more work on annotations (#44, #8). Graphite events is working, editing, icon size, color and vertical line toggle/options working. To sleepy now...
parent 47db82d6
......@@ -183,6 +183,16 @@ function (angular, $, config, _) {
return _.isNull(_error) ? data : _error[1];
};
$scope.colors = [
"#7EB26D","#EAB839","#6ED0E0","#EF843C","#E24D42","#1F78C1","#BA43A9","#705DA0", //1
"#508642","#CCA300","#447EBC","#C15C17","#890F02","#0A437C","#6D1F62","#584477", //2
"#B7DBAB","#F4D598","#70DBED","#F9BA8F","#F29191","#82B5D8","#E5A8E2","#AEA2E0", //3
"#629E51","#E5AC0E","#64B0C8","#E0752D","#BF1B00","#0A50A1","#962D82","#614D93", //4
"#9AC48A","#F2C96D","#65C5DB","#F9934E","#EA6460","#5195CE","#D683CE","#806EB7", //5
"#3F6833","#967302","#2F575E","#99440A","#58140C","#052B51","#511749","#3F2B5B", //6
"#E0F9D7","#FCEACA","#CFFAFF","#F9E2D2","#FCE2DE","#BADFF4","#F9D9F9","#DEDAF7" //7
];
$scope.init();
});
});
\ No newline at end of file
......@@ -20,7 +20,6 @@ function (angular, $, kbn, moment, _) {
scope.$on('refresh',function() {
if (scope.otherPanelInFullscreenMode()) { return; }
scope.get_data();
});
......@@ -121,6 +120,7 @@ function (angular, $, kbn, moment, _) {
ticks: elem.width()/100
},
grid: {
markings: [],
backgroundColor: null,
borderWidth: 0,
hoverable: true,
......@@ -191,7 +191,6 @@ function (angular, $, kbn, moment, _) {
function addGridThresholds(options, panel) {
if (panel.grid.threshold1) {
var limit1 = panel.grid.thresholdLine ? panel.grid.threshold1 : (panel.grid.threshold2 || null);
options.grid.markings = [];
options.grid.markings.push({
yaxis: { from: panel.grid.threshold1, to: limit1 },
color: panel.grid.threshold1Color
......@@ -217,20 +216,33 @@ function (angular, $, kbn, moment, _) {
return;
}
options.events = {
levels: 1,
data: data.annotations,
types: {
'annotation': {
level: 1,
var types = {};
_.each(data.annotations, function(event) {
if (!types[event.annotation.name]) {
types[event.annotation.name] = {
level: _.keys(types).length + 1,
icon: {
icon: "icon-tag icon-flip-vertical",
size: 20,
color: "#222",
outline: "#bbb"
icon: "icon-chevron-up",
size: event.annotation.iconSize,
color: event.annotation.iconColor,
}
}
};
}
if (event.annotation.showLine) {
options.grid.markings.push({
color: event.annotation.lineColor,
lineWidth: 1,
xaxis: { from: event.min, to: event.max }
});
}
});
options.events = {
levels: _.keys(types).length + 1,
data: data.annotations,
types: types
};
}
......
......@@ -2,19 +2,20 @@
<div class="pull-right editor-title">Annotations</div>
<div class="editor-row">
<table class="table table-striped annotation-editor-table">
<table class="table table-striped annotation-editor-table" style="width: 700px">
<thead>
<th width="1%"></th>
<th width="1%">Type</th>
<th width="90%">Name</th>
<th width="1%"></th>
<th width="1%"></th>
<th width="1%"></th>
</thead>
<tr ng-repeat="annotation in panel.annotations">
<td><a ng-click="edit(annotation)"><i class="icon-pencil" /></a></td>
<td>{{annotation.type}}</td>
<td>{{annotation.name}}</td>
<td>
<a ng-click="edit(annotation)" bs-tooltip="'Click to edit'">
<i class="icon-cog"></i>
{{annotation.name}}
</a>
</td>
<td><i ng-click="_.move(panel.annotations,$index,$index-1)" ng-hide="$first" class="pointer icon-arrow-up"></i></td>
<td><i ng-click="_.move(panel.annotations,$index,$index+1)" ng-hide="$last" class="pointer icon-arrow-down"></i></td>
<td><i ng-click="panel.annotations = _.without(panel.annotations, annotation)" class="pointer icon-remove"></i></td>
......@@ -34,6 +35,22 @@
<label class="small">Type</label>
<select ng-model="currentAnnnotation.type" ng-options="f for f in ['graphite metric', 'graphite events']"></select>
</div>
<div class="editor-option">
<label class="small">Icon color</label>
<spectrum-picker ng-model="currentAnnnotation.iconColor"></spectrum-picker>
</div>
<div class="editor-option">
<label class="small">Icon size</label>
<select class="input-mini" ng-model="currentAnnnotation.iconSize" ng-options="f for f in [7,8,9,10,13,15,17,20,25,30]"></select>
</div>
<div class="editor-option">
<label class="small">Grid line</label>
<input type="checkbox" ng-model="currentAnnnotation.showLine" ng-checked="currentAnnnotation.showLine">
</div>
<div class="editor-option">
<label class="small">Line color</label>
<spectrum-picker ng-model="currentAnnnotation.lineColor"></spectrum-picker>
</div>
</div>
<div class="editor-row" ng-if="currentAnnnotation.type === 'graphite metric'">
......@@ -55,5 +72,5 @@
<div class="modal-footer">
<button ng-show="currentIsNew" type="button" class="btn btn-success" ng-click="add()">Add annotation</button>
<button ng-show="!currentIsNew" type="button" class="btn btn-success" ng-click="update()">Update</button>
<button type="button" class="btn btn-danger" ng-click="close_edit();dismiss()">Close</button>
</div>
<button type="button" class="btn btn-danger" ng-click="close_edit();dismiss();dashboard.refresh();">Close</button>
</div>
\ No newline at end of file
......@@ -28,7 +28,12 @@ function (angular, app, _) {
var annotationDefaults = {
name: '',
type: 'graphite metric'
type: 'graphite metric',
showLine: true,
iconColor: '#E24D42',
lineColor: '#E24D42',
iconSize: 15,
enable: true
};
_.defaults($scope.panel,_d);
......
......@@ -266,16 +266,6 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
}
};
$scope.colors = [
"#7EB26D","#EAB839","#6ED0E0","#EF843C","#E24D42","#1F78C1","#BA43A9","#705DA0", //1
"#508642","#CCA300","#447EBC","#C15C17","#890F02","#0A437C","#6D1F62","#584477", //2
"#B7DBAB","#F4D598","#70DBED","#F9BA8F","#F29191","#82B5D8","#E5A8E2","#AEA2E0", //3
"#629E51","#E5AC0E","#64B0C8","#E0752D","#BF1B00","#0A50A1","#962D82","#614D93", //4
"#9AC48A","#F2C96D","#65C5DB","#F9934E","#EA6460","#5195CE","#D683CE","#806EB7", //5
"#3F6833","#967302","#2F575E","#99440A","#58140C","#052B51","#511749","#3F2B5B", //6
"#E0F9D7","#FCEACA","#CFFAFF","#F9E2D2","#FCE2DE","#BADFF4","#F9D9F9","#DEDAF7" //7
];
/**
* Fetch the data for a chunk of a queries results. Multiple segments occur when several indicies
* need to be consulted (like timestamped logstash indicies)
......
......@@ -35,6 +35,45 @@ define([
return promiseCached;
}
var graphiteMetrics = this.getGraphiteMetrics(rangeUnparsed);
var graphiteEvents = this.getGraphiteEvents(rangeUnparsed);
promiseCached = $q.all([graphiteMetrics, graphiteEvents])
.then(function(allAnnotations) {
var nonNull = _.filter(allAnnotations, function(value) { return value !== null; });
return _.flatten(nonNull);
});
return promiseCached;
};
this.getGraphiteEvents = function(rangeUnparsed) {
var annotations = _.where(annotationPanel.annotations, { type: 'graphite events', enable: true });
var tags = _.pluck(annotations, 'tags');
if (tags.length === 0) {
return $q.when(null);
}
var eventsQuery = {
range: rangeUnparsed,
tags: tags.join(' '),
};
return datasourceSrv.default.events(eventsQuery)
.then(function(results) {
var list = [];
_.each(results.data, function (event) {
list.push(createAnnotation(annotations[0], event.when * 1000, event.what, event.tags, event.data));
});
return list;
})
.then(null, function() {
alertSrv.set('Annotations','Could not fetch annotations','error');
});
};
this.getGraphiteMetrics = function(rangeUnparsed) {
var graphiteAnnotations = _.where(annotationPanel.annotations, { type: 'graphite metric', enable: true });
var graphiteTargets = _.map(graphiteAnnotations, function(annotation) {
return { target: annotation.target };
......@@ -51,7 +90,7 @@ define([
maxDataPoints: 100
};
promiseCached = datasourceSrv.default.query(graphiteQuery)
return datasourceSrv.default.query(graphiteQuery)
.then(function(results) {
return _.reduce(results.data, function(list, target) {
_.each(target.datapoints, function (values) {
......@@ -59,16 +98,7 @@ define([
return;
}
list.push({
min: values[1] * 1000,
max: values[1] * 1000,
eventType: "annotation",
title: null,
description: "<small>" + target.target + "</small><br>"+
moment(values[1] * 1000).format('YYYY-MM-DD HH:mm:ss'),
score: 1
});
list.push(createAnnotation(graphiteAnnotations[0], values[1] * 1000, target.target));
});
return list;
......@@ -77,10 +107,30 @@ define([
.then(null, function() {
alertSrv.set('Annotations','Could not fetch annotations','error');
});
return promiseCached;
};
function createAnnotation(annotation, time, description, tags, data) {
var tooltip = "<small><b>" + description + "</b><br/>";
if (tags) {
tooltip += (tags || '') + '<br/>';
}
tooltip += '<i>' + moment(time).format('YYYY-MM-DD HH:mm:ss') + '</i><br/>';
if (data) {
tooltip += data;
}
tooltip += "</small>";
return {
annotation: annotation,
min: time,
max: time,
eventType: annotation.name,
title: null,
description: tooltip,
score: 1
};
}
// Now init
this.init();
});
......
......@@ -37,7 +37,6 @@ function (angular, _, $, config, kbn, moment) {
return this.doGraphiteRequest({
method: 'POST',
url: '/render',
datasource: options.datasource,
data: params.join('&'),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
......@@ -49,6 +48,23 @@ function (angular, _, $, config, kbn, moment) {
}
};
GraphiteDatasource.prototype.events = function(options) {
try {
var tags = '';
if (options.tags) {
tags = '&tags=' + options.tags;
}
return this.doGraphiteRequest({
method: 'GET',
url: '/events/get_data?from=' + this.translateTime(options.range.from) + '&until=' + this.translateTime(options.range.to) + tags,
});
}
catch(err) {
return this.$q.reject(err);
}
};
GraphiteDatasource.prototype.translateTime = function(date) {
if (_.isString(date)) {
if (date === 'now') {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -437,4 +437,17 @@ input[type=text].func-param {
border: none;
}
.sp-dd {
display: none;
}
.sp-preview {
position: relative;
width: 15px;
height: 15px;
border: none;
margin-right: 5px;
float: left;
z-index: 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment