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...

This commit is contained in:
Torkel Ödegaard 2014-02-20 23:00:32 +01:00
parent 47db82d69b
commit f0f4c8cc52
10 changed files with 161 additions and 48 deletions

View File

@ -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();
});
});

View 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
};
}

View File

@ -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>

View 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);

View File

@ -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)

View File

@ -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();
});

View File

@ -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') {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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;
}