mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
a3c8b09547
2
common/css/bootstrap.min.css
vendored
2
common/css/bootstrap.min.css
vendored
@ -646,7 +646,7 @@ button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-
|
||||
.nav>.disabled>a{color:#4d4d4d;}
|
||||
.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;background-color:transparent;cursor:default;}
|
||||
.navbar{overflow:visible;margin-bottom:20px;*position:relative;*z-index:2;}
|
||||
.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#2e2e2e;background-image:-moz-linear-gradient(top, #333333, #262626);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#262626));background-image:-webkit-linear-gradient(top, #333333, #262626);background-image:-o-linear-gradient(top, #333333, #262626);background-image:linear-gradient(to bottom, #333333, #262626);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff333333', endColorstr='#ff262626', GradientType=0);border:1px solid #080808;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;}
|
||||
.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#2e2e2e;background-image:-moz-linear-gradient(top, #404040, #262626);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#404040), to(#262626));background-image:-webkit-linear-gradient(top, #404040, #262626);background-image:-o-linear-gradient(top, #404040, #262626);background-image:linear-gradient(to bottom, #404040, #262626);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff404040', endColorstr='#ff262626', GradientType=0);border:1px solid #080808;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;}
|
||||
.navbar-inner:after{clear:both;}
|
||||
.navbar .container{width:auto;}
|
||||
.nav-collapse.collapse{height:auto;overflow:visible;}
|
||||
|
@ -6,6 +6,50 @@
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.kibana-row {
|
||||
margin-left: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.navbar .brand {
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.navbar-inner {
|
||||
border-width: 0 0 0px;
|
||||
}
|
||||
|
||||
.row-close {
|
||||
color: #bbb;
|
||||
position: absolute;
|
||||
font-size: 9pt;
|
||||
font-weight: 200;
|
||||
padding-left: 35px;
|
||||
padding-top:0px;
|
||||
}
|
||||
|
||||
.row-open {
|
||||
text-align: right;
|
||||
color: #bbb;
|
||||
margin-top:30px;
|
||||
position: absolute;
|
||||
font-size: 13pt;
|
||||
font-weight: 200;
|
||||
-moz-transform-origin: 40px;
|
||||
-ms-transform-origin: 40px;
|
||||
-o-transform-origin: 40px;
|
||||
-webkit-transform-origin: 40px;
|
||||
transform-origin: 40px;
|
||||
transform: rotate(-90deg);
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
|
||||
-webkit-transform: rotate(-90deg);
|
||||
-moz-transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.row-open i {
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.odd {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
@ -95,4 +139,9 @@
|
||||
background-color: #A60000;
|
||||
}
|
||||
|
||||
.typeahead { z-index: 1051; }
|
||||
.typeahead { z-index: 1051; }
|
||||
|
||||
.navbar-inner {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
/*! elastic.js - v1.0.0 - 2013-01-15
|
||||
/*! elastic.js - v1.0.0 - 2013-03-05
|
||||
* https://github.com/fullscale/elastic.js
|
||||
* Copyright (c) 2013 FullScale Labs, LLC; Licensed MIT */
|
||||
|
||||
/*jshint browser:true */
|
||||
/*global angular:true */
|
||||
/*jshint es5:true */
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
@ -26,8 +27,8 @@ angular.module('elasticjs.service', [])
|
||||
(successcb || angular.noop)(response.data);
|
||||
return response.data;
|
||||
}, function (response) {
|
||||
(errorcb || angular.noop)(undefined);
|
||||
return undefined;
|
||||
(errorcb || angular.noop)(response.data);
|
||||
return response.data;
|
||||
});
|
||||
};
|
||||
|
||||
|
4
common/lib/elastic-angular-client.min.js
vendored
4
common/lib/elastic-angular-client.min.js
vendored
@ -1,4 +1,4 @@
|
||||
/*! elastic.js - v1.0.0 - 2013-01-15
|
||||
/*! elastic.js - v1.0.0 - 2013-03-05
|
||||
* https://github.com/fullscale/elastic.js
|
||||
* Copyright (c) 2013 FullScale Labs, LLC; Licensed MIT */
|
||||
"use strict";angular.module("elasticjs.service",[]).factory("ejsResource",["$http",function(e){return function(t){var n=window.ejs||{},r=function(e,t,n){return e.then(function(e){return(t||angular.noop)(e.data),e.data},function(e){return(n||angular.noop)(undefined),undefined})};return t==null&&(t=""),n.client={server:function(e){return e==null?t:(t=e,this)},post:function(n,i,s,o){return n=t+n,r(e.post(n,i),s,o)},get:function(n,i,s,o){return n=t+n,r(e.get(n,i),s,o)},put:function(n,i,s,o){return n=t+n,r(e.put(n,i),s,o)},del:function(n,i,s,o){return n=t+n,r(e.delete(n,i),s,o)},head:function(n,r,i,s){return n=t+n,e.head(n,r).then(function(e){return(i||angular.noop)(e.headers()),e.headers()},function(e){return(s||angular.noop)(undefined),undefined})}},n}}]);
|
||||
"use strict";angular.module("elasticjs.service",[]).factory("ejsResource",["$http",function(e){return function(t){var n=window.ejs||{},r=function(e,t,n){return e.then(function(e){return(t||angular.noop)(e.data),e.data},function(e){return(n||angular.noop)(undefined),undefined})};return t==null&&(t=""),n.client={server:function(e){return e==null?t:(t=e,this)},post:function(n,i,s,o){return n=t+n,r(e.post(n,i),s,o)},get:function(n,i,s,o){return n=t+n,r(e.get(n,i),s,o)},put:function(n,i,s,o){return n=t+n,r(e.put(n,i),s,o)},del:function(n,i,s,o){return n=t+n,r(e.delete(n,i),s,o)},head:function(n,r,i,s){return n=t+n,e.head(n,r).then(function(e){return(i||angular.noop)(e.headers()),e.headers()},function(e){return(s||angular.noop)(undefined),undefined})}},n}}]);
|
File diff suppressed because it is too large
Load Diff
4
common/lib/elastic.min.js
vendored
4
common/lib/elastic.min.js
vendored
File diff suppressed because one or more lines are too long
@ -36,13 +36,13 @@
|
||||
<div class="navbar navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<p class="navbar-text pull-right"><small>Kibana 3 Preview</small></p>
|
||||
<p class="navbar-text pull-right"><small><strong>Kibana 3</strong> <small>milestone 1</small></small></p>
|
||||
<span class="brand">{{dashboards.title}}</span>
|
||||
<div class="brand"><i class='icon-edit pointer' ng-show='dashboards.editable' bs-modal="'partials/dasheditor.html'"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid main">
|
||||
<div class="row-fluid">
|
||||
<div ng-view></div>
|
||||
</div>
|
||||
|
@ -27,7 +27,7 @@ var labjs = $LAB
|
||||
.script("common/lib/angular-strap.min.js")
|
||||
.script("common/lib/angular-sanitize.min.js")
|
||||
.script("common/lib/elastic.min.js")
|
||||
.script("common/lib/elastic-angular-client.min.js")
|
||||
.script("common/lib/elastic-angular-client.js")
|
||||
.script("common/lib/dateformat.js")
|
||||
.script("common/lib/date.js")
|
||||
.script("common/lib/datepicker.js")
|
||||
|
@ -3,7 +3,7 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('kibana.controllers', [])
|
||||
.controller('DashCtrl', function($scope, $rootScope, $http, $timeout, ejsResource, eventBus) {
|
||||
.controller('DashCtrl', function($scope, $rootScope, $http, $timeout, ejsResource, eventBus, fields) {
|
||||
|
||||
var _d = {
|
||||
title: "",
|
||||
@ -14,7 +14,11 @@ angular.module('kibana.controllers', [])
|
||||
$scope.init = function() {
|
||||
|
||||
$scope.config = config;
|
||||
// Make underscore.js available to views
|
||||
$scope._ = _;
|
||||
|
||||
// Provide a global list of all see fields
|
||||
$scope.fields = fields
|
||||
$scope.reset_row();
|
||||
$scope.clear_all_alerts();
|
||||
|
||||
@ -44,6 +48,10 @@ angular.module('kibana.controllers', [])
|
||||
};
|
||||
};
|
||||
|
||||
$scope.row_style = function(row) {
|
||||
return { 'min-height': row.collapse ? '5px' : row.height }
|
||||
}
|
||||
|
||||
$scope.alert = function(title,text,severity,timeout) {
|
||||
var alert = {
|
||||
title: title,
|
||||
@ -70,6 +78,12 @@ angular.module('kibana.controllers', [])
|
||||
return 'panels/'+type+'/editor.html';
|
||||
}
|
||||
|
||||
// This is whoafully incomplete, but will do for now
|
||||
$scope.parse_error = function(data) {
|
||||
var _error = data.match("nested: (.*?);")
|
||||
return _.isNull(_error) ? data : _error[1];
|
||||
}
|
||||
|
||||
$scope.init();
|
||||
|
||||
})
|
||||
@ -86,7 +100,7 @@ angular.module('kibana.controllers', [])
|
||||
_.defaults($scope.row,_d)
|
||||
|
||||
|
||||
$scope.init = function(){
|
||||
$scope.init = function() {
|
||||
$scope.reset_panel();
|
||||
}
|
||||
|
||||
@ -94,13 +108,14 @@ angular.module('kibana.controllers', [])
|
||||
row.collapse = row.collapse ? false : true;
|
||||
if (!row.collapse) {
|
||||
$timeout(function() {
|
||||
$scope.send_render();
|
||||
$scope.$broadcast('render')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.send_render = function() {
|
||||
$scope.$broadcast('render');
|
||||
// This can be overridden by individual panel
|
||||
$scope.close_edit = function() {
|
||||
$scope.$broadcast('render')
|
||||
}
|
||||
|
||||
$scope.add_panel = function(row,panel) {
|
||||
@ -109,11 +124,11 @@ angular.module('kibana.controllers', [])
|
||||
|
||||
$scope.reset_panel = function() {
|
||||
$scope.panel = {
|
||||
loading: false,
|
||||
error: false,
|
||||
span: 3,
|
||||
loading : false,
|
||||
error : false,
|
||||
span : 3,
|
||||
editable: true,
|
||||
group: ['default'],
|
||||
group : ['default'],
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -67,6 +67,21 @@ angular.module('kibana.services', [])
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
/* Service: fields
|
||||
Provides a global list of all seen fields for use in editor panels
|
||||
*/
|
||||
.factory('fields', function($rootScope) {
|
||||
var fields = {
|
||||
list : []
|
||||
}
|
||||
|
||||
$rootScope.$on('fields', function(event,f) {
|
||||
fields.list = _.union(f.data.all,fields.list)
|
||||
})
|
||||
|
||||
return fields;
|
||||
|
||||
})
|
||||
.service('timer', function($timeout) {
|
||||
// This service really just tracks a list of $timeout promises to give us a
|
||||
|
@ -187,8 +187,9 @@ angular.module('kibana.dashcontrol', [])
|
||||
var results = request.query(
|
||||
$scope.ejs.QueryStringQuery(query || '*')
|
||||
).size($scope.panel.elasticsearch_size).doSearch();
|
||||
|
||||
results.then(function(results) {
|
||||
if(_.isUndefined(results)) {
|
||||
if(_.isUndefined(results.hits)) {
|
||||
return;
|
||||
}
|
||||
$scope.panel.error = false;
|
||||
|
@ -1,61 +1,73 @@
|
||||
<div class="row-fluid" ng-controller='histogram'>
|
||||
<div class="span3">
|
||||
<form style="margin-bottom: 0px">
|
||||
<h6>Label</h6>
|
||||
<input type="text" placeholder="New Label" style="width:70%" ng-model="newlabel">
|
||||
</form>
|
||||
<div ng-controller='histogram'>
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<form style="margin-bottom: 0px">
|
||||
<h6>Label</h6>
|
||||
<input type="text" placeholder="New Label" style="width:70%" ng-model="newlabel">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<form class="input-append" style="margin-bottom: 0px">
|
||||
<h6>Query</h6>
|
||||
<input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
|
||||
<button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery=''"><i class="icon-plus"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="span1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<form class="input-append" style="margin-bottom: 0px">
|
||||
<h6>Query</h6>
|
||||
<input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
|
||||
<button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery=''"><i class="icon-plus"></i></button>
|
||||
</form>
|
||||
<div class="row-fluid" ng-repeat="q in panel.query">
|
||||
<div class="span3">
|
||||
<form style="margin-bottom: 0px">
|
||||
<input type="text" style="width:70%" ng-model="q.label">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<form class="input-append" style="margin-bottom: 0px">
|
||||
<input type="text" style="width:80%" ng-model="q.query">
|
||||
<button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="span1">
|
||||
<i class="icon-remove pointer" ng-click="remove_query(q)"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid" ng-repeat="q in panel.query">
|
||||
<div class="span3">
|
||||
<form style="margin-bottom: 0px">
|
||||
<input type="text" style="width:70%" ng-model="q.label">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<form class="input-append" style="margin-bottom: 0px">
|
||||
<input type="text" style="width:80%" ng-model="q.query">
|
||||
<button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="span1">
|
||||
<i class="icon-remove pointer" ng-click="remove_query(q)"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<label class="small">Chart Options</label>
|
||||
<select ng-change="$emit('render')" multiple style="width:95%" ng-model="panel.show" ng-options="f for f in ['bars','points','stack','lines','legend','x-axis','y-axis']"></select>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<label class="small">Line Fill (1 - 10)</label>
|
||||
<input ng-change="$emit('render')" type="number" class="input-mini" ng-model="panel.fill">
|
||||
</div>
|
||||
<div class="span3">
|
||||
<label class="small">Time correction</label>
|
||||
<select ng-change="$emit('render')" ng-model="panel.timezone" class='input-small' ng-options="f for f in ['browser','utc']"></select>
|
||||
</div>
|
||||
<div class="span2">
|
||||
<label class="small">Zoom Links</label><input type="checkbox" ng-model="panel.zoomlinks" ng-checked="panel.zoomlinks">
|
||||
</div>
|
||||
</div>
|
||||
<h5>Panel Spy</h5>
|
||||
<div class="row-fluid">
|
||||
<div class="span2">
|
||||
<label class="small">Spyable</label><input type="checkbox" ng-model="panel.spyable" ng-checked="panel.spyable">
|
||||
</div>
|
||||
<div class="span9 small">
|
||||
The panel spy shows 'behind the scenes' information about a panel. It can
|
||||
be accessed by clicking the <i class='icon-eye-open'></i> in the top right
|
||||
of the panel.
|
||||
<h5>Chart Options</h5>
|
||||
<div class="row-fluid" style="margin-bottom:10px;">
|
||||
<div class="span1"> <label class="small">Bars</label><input ng-change="$emit('render')" type="checkbox" ng-model="panel.bars" ng-checked="panel.bars"></div>
|
||||
<div class="span1"> <label class="small">Lines</label><input ng-change="$emit('render')" type="checkbox" ng-model="panel.lines" ng-checked="panel.lines"></div>
|
||||
<div class="span1"> <label class="small">Points</label><input ng-change="$emit('render')" type="checkbox" ng-model="panel.points" ng-checked="panel.points"></div>
|
||||
<div class="span1"> <label class="small">Stack</label><input ng-change="$emit('render')" type="checkbox" ng-model="panel.stack" ng-checked="panel.stack"></div>
|
||||
<div class="span1"> <label class="small">Legend</label><input ng-change="$emit('render')" type="checkbox" ng-model="panel.legend" ng-checked="panel.legend"></div>
|
||||
<div class="span1"> <label class="small">xAxis</label><input ng-change="$emit('render')" type="checkbox" ng-model="panel['x-axis']" ng-checked="panel['x-axis']"></div>
|
||||
<div class="span1"> <label class="small">yAxis</label><input ng-change="$emit('render')" type="checkbox" ng-model="panel['y-axis']" ng-checked="panel['y-axis']"></div>
|
||||
<div class="span2" ng-show="panel.lines">
|
||||
<label class="small">Line Fill</label>
|
||||
<select ng-change="$emit('render')" class="input-mini" ng-model="panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]"></select>
|
||||
</div>
|
||||
<div class="span2" ng-show="panel.lines">
|
||||
<label class="small">Line Width</label>
|
||||
<select ng-change="$emit('render')" class="input-mini" ng-model="panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<label class="small">Time correction</label>
|
||||
<select ng-change="$emit('render')" ng-model="panel.timezone" class='input-small' ng-options="f for f in ['browser','utc']"></select>
|
||||
</div>
|
||||
<div class="span2">
|
||||
<label class="small">Zoom Links</label><input type="checkbox" ng-model="panel.zoomlinks" ng-checked="panel.zoomlinks">
|
||||
</div>
|
||||
</div>
|
||||
<h5>Panel Spy</h5>
|
||||
<div class="row-fluid">
|
||||
<div class="span2">
|
||||
<label class="small">Spyable</label><input type="checkbox" ng-model="panel.spyable" ng-checked="panel.spyable">
|
||||
</div>
|
||||
<div class="span9 small">
|
||||
The panel spy shows 'behind the scenes' information about a panel. It can
|
||||
be accessed by clicking the <i class='icon-eye-open'></i> in the top right
|
||||
of the panel.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,15 +2,16 @@
|
||||
<span ng-show="panel.spyable" style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
|
||||
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
|
||||
</span>
|
||||
<center ng-show='panel.zoomlinks && data'>
|
||||
<div>
|
||||
<span ng-show='panel.zoomlinks && data'>
|
||||
<a class='small' ng-click='zoom(0.5)'><i class='icon-zoom-in'></i> Zoom In</a>
|
||||
<a class='small' ng-click='zoom(2)'><i class='icon-zoom-out'></i> Zoom Out</a>
|
||||
</center>
|
||||
<div>
|
||||
<span ng-repeat='series in legend' style='display:inline-block;padding-right:5px'>
|
||||
<div style="display:inline-block;background:{{series.color}};height:10px;width:10px"></div>
|
||||
</span> |
|
||||
<span ng-show="panel.legend" ng-repeat='series in plot.getData()' style='display:inline-block;padding-right:5px'>
|
||||
<div style="display:inline-block;background:{{series.color}};height:10px;width:10px;border-radius:5px;"></div>
|
||||
<div class='small' style='display:inline-block'>{{series.label}} ({{series.hits}})</div>
|
||||
</span><span class="small"> per <strong>{{panel.interval}}</strong> | (<strong>{{hits}}</strong> total)</span>
|
||||
</div>
|
||||
<div histogram params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
|
||||
<center><img ng-show='panel.loading && _.isUndefined(data)' src="common/img/load_big.gif"></center>
|
||||
<div histogram-chart params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
|
||||
</kibana-panel>
|
@ -3,19 +3,28 @@ angular.module('kibana.histogram', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
group : "default",
|
||||
query : [ {query: "*", label:"Query"} ],
|
||||
interval : secondsToHms(calculate_interval($scope.from,$scope.to,40,0)/1000),
|
||||
show : ['bars','y-axis','x-axis','legend'],
|
||||
fill : 3,
|
||||
linewidth : 3,
|
||||
timezone : 'browser', // browser, utc or a standard timezone
|
||||
spyable : true,
|
||||
zoomlinks : true,
|
||||
group : "default",
|
||||
bars : true,
|
||||
stack : true,
|
||||
points : false,
|
||||
lines : false,
|
||||
legend : true,
|
||||
'x-axis' : true,
|
||||
'y-axis' : true,
|
||||
}
|
||||
_.defaults($scope.panel,_d)
|
||||
|
||||
$scope.init = function() {
|
||||
eventBus.register($scope,'time', function(event,time){$scope.set_time(time)});
|
||||
|
||||
// Consider eliminating the check for array, this should always be an array
|
||||
eventBus.register($scope,'query', function(event, query) {
|
||||
if(_.isArray(query)) {
|
||||
$scope.panel.query = _.map(query,function(q) {
|
||||
@ -26,6 +35,7 @@ angular.module('kibana.histogram', [])
|
||||
}
|
||||
$scope.get_data();
|
||||
});
|
||||
|
||||
// Now that we're all setup, request the time from our group if we don't
|
||||
// have it yet
|
||||
if(_.isUndefined($scope.time))
|
||||
@ -48,13 +58,13 @@ angular.module('kibana.histogram', [])
|
||||
}
|
||||
|
||||
$scope.get_data = function(segment,query_id) {
|
||||
delete $scope.panel.error
|
||||
// Make sure we have everything for the request to complete
|
||||
if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time))
|
||||
return
|
||||
|
||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
||||
|
||||
$scope.panel.loading = true;
|
||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
||||
var request = $scope.ejs.Request().indices($scope.panel.index[_segment]);
|
||||
|
||||
// Build the question part of the query
|
||||
@ -68,7 +78,7 @@ angular.module('kibana.histogram', [])
|
||||
)
|
||||
});
|
||||
|
||||
// Build the facet part
|
||||
// Build the facet part, injecting the query in as a facet filter
|
||||
_.each(queries, function(v) {
|
||||
request = request
|
||||
.facet($scope.ejs.DateHistogramFacet("chart"+_.indexOf(queries,v))
|
||||
@ -78,6 +88,7 @@ angular.module('kibana.histogram', [])
|
||||
).size(0)
|
||||
})
|
||||
|
||||
// Populate the inspector panel
|
||||
$scope.populate_modal(request);
|
||||
|
||||
// Then run it
|
||||
@ -92,16 +103,17 @@ angular.module('kibana.histogram', [])
|
||||
query_id = $scope.query_id = new Date().getTime();
|
||||
}
|
||||
|
||||
// Check for error and abort if found
|
||||
if(!(_.isUndefined(results.error))) {
|
||||
$scope.panel.error = $scope.parse_error(results.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we're still on the same query
|
||||
if($scope.query_id === query_id) {
|
||||
|
||||
var i = 0;
|
||||
_.each(results.facets, function(v, k) {
|
||||
// If this isn't a date histogram it must be a QueryFacet, get the
|
||||
// count and return
|
||||
if(v._type !== 'date_histogram') {
|
||||
//$scope.hits += v.count;
|
||||
return
|
||||
}
|
||||
|
||||
// Null values at each end of the time range ensure we see entire range
|
||||
if(_.isUndefined($scope.data[i]) || _segment == 0) {
|
||||
@ -116,14 +128,14 @@ angular.module('kibana.histogram', [])
|
||||
var segment_data = [];
|
||||
_.each(v.entries, function(v, k) {
|
||||
segment_data.push([v['time'],v['count']])
|
||||
hits += v['count'];
|
||||
$scope.hits += v['count'];
|
||||
hits += v['count']; // The series level hits counter
|
||||
$scope.hits += v['count']; // Entire dataset level hits counter
|
||||
});
|
||||
|
||||
data.splice.apply(data,[1,0].concat(segment_data))
|
||||
data.splice.apply(data,[1,0].concat(segment_data)) // Join histogram data
|
||||
|
||||
|
||||
// Create the flot series
|
||||
// Create the flot series object
|
||||
var series = {
|
||||
data: {
|
||||
label: $scope.panel.query[i].label || "query"+(parseInt(i)+1),
|
||||
@ -140,8 +152,10 @@ angular.module('kibana.histogram', [])
|
||||
i++;
|
||||
});
|
||||
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'hits',$scope.hits)
|
||||
// Tell the histogram directive to render.
|
||||
$scope.$emit('render')
|
||||
|
||||
// If we still have segments left, get them
|
||||
if(_segment < $scope.panel.index.length-1) {
|
||||
$scope.get_data(_segment+1,query_id)
|
||||
}
|
||||
@ -176,15 +190,13 @@ angular.module('kibana.histogram', [])
|
||||
}
|
||||
|
||||
})
|
||||
.directive('histogram', function(eventBus) {
|
||||
.directive('histogramChart', function(eventBus) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, elem, attrs, ctrl) {
|
||||
|
||||
var height = scope.panel.height || scope.row.height;
|
||||
|
||||
elem.html('<center><img src="common/img/load_big.gif"></center>')
|
||||
|
||||
// Receive render events
|
||||
scope.$on('render',function(){
|
||||
render_panel();
|
||||
@ -197,19 +209,6 @@ angular.module('kibana.histogram', [])
|
||||
|
||||
// Function for rendering panel
|
||||
function render_panel() {
|
||||
// Determine format
|
||||
var show = _.isUndefined(scope.panel.show) ? {
|
||||
bars: true, lines: false, points: false
|
||||
} : {
|
||||
lines: _.indexOf(scope.panel.show,'lines') < 0 ? false : true,
|
||||
bars: _.indexOf(scope.panel.show,'bars') < 0 ? false : true,
|
||||
points: _.indexOf(scope.panel.show,'points') < 0 ? false : true,
|
||||
stack: _.indexOf(scope.panel.show,'stack') < 0 ? null : true,
|
||||
legend: _.indexOf(scope.panel.show,'legend') < 0 ? false : true,
|
||||
'x-axis': _.indexOf(scope.panel.show,'x-axis') < 0 ? false : true,
|
||||
'y-axis': _.indexOf(scope.panel.show,'y-axis') < 0 ? false : true,
|
||||
}
|
||||
|
||||
// Set barwidth based on specified interval
|
||||
var barwidth = interval_to_seconds(scope.panel.interval)*1000
|
||||
|
||||
@ -221,31 +220,36 @@ angular.module('kibana.histogram', [])
|
||||
|
||||
// Populate element. Note that jvectormap appends, does not replace.
|
||||
scripts.wait(function(){
|
||||
var stack = scope.panel.stack ? true : null;
|
||||
|
||||
// Populate element
|
||||
try {
|
||||
var plot = $.plot(elem, scope.data, {
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
scope.plot = $.plot(elem, scope.data, {
|
||||
legend: { show: false },
|
||||
series: {
|
||||
stack: show.stack,
|
||||
lines: { show: show.lines, fill: scope.panel.fill/10 },
|
||||
bars: { show: show.bars, fill: 1, barWidth: barwidth/1.8 },
|
||||
points: { show: show.points, fill: 1, fillColor: false},
|
||||
stack: stack,
|
||||
lines: {
|
||||
show: scope.panel.lines,
|
||||
fill: scope.panel.fill/10,
|
||||
lineWidth: scope.panel.linewidth,
|
||||
steps: false
|
||||
},
|
||||
bars: { show: scope.panel.bars, fill: 1, barWidth: barwidth/1.8 },
|
||||
points: { show: scope.panel.points, fill: 1, fillColor: false, radius: 5},
|
||||
shadowSize: 1
|
||||
},
|
||||
yaxis: { show: show['y-axis'], min: 0, color: "#000" },
|
||||
yaxis: { show: scope.panel['y-axis'], min: 0, color: "#000" },
|
||||
xaxis: {
|
||||
timezone: scope.panel.timezone,
|
||||
show: show['x-axis'],
|
||||
show: scope.panel['x-axis'],
|
||||
mode: "time",
|
||||
timeformat: time_format(scope.panel.interval),
|
||||
label: "Datetime",
|
||||
color: "#000",
|
||||
},
|
||||
selection: {
|
||||
mode: "x"
|
||||
mode: "x",
|
||||
color: '#666'
|
||||
},
|
||||
grid: {
|
||||
backgroundColor: '#fff',
|
||||
@ -254,12 +258,13 @@ angular.module('kibana.histogram', [])
|
||||
color: "#eee",
|
||||
hoverable: true,
|
||||
},
|
||||
colors: ['#EB6841','#00A0B0','#6A4A3C','#EDC951','#CC333F']
|
||||
})
|
||||
|
||||
scope.legend = [];
|
||||
_.each(plot.getData(),function(series) {
|
||||
scope.legend.push(_.pick(series,'label','color','hits'))
|
||||
colors: ['#86B22D',
|
||||
'#BF6730',
|
||||
'#1D7373',
|
||||
'#BFB930',
|
||||
'#BF3030',
|
||||
'#77207D'
|
||||
]
|
||||
})
|
||||
|
||||
// Work around for missing legend at initialization
|
||||
@ -288,23 +293,25 @@ angular.module('kibana.histogram', [])
|
||||
var tooltip = $('#pie-tooltip').length ?
|
||||
$('#pie-tooltip') : $('<div id="pie-tooltip"></div>');
|
||||
//var tooltip = $('#pie-tooltip')
|
||||
tooltip.text(contents).css({
|
||||
tooltip.html(contents).css({
|
||||
position: 'absolute',
|
||||
top : y + 5,
|
||||
left : x + 5,
|
||||
color : "#FFF",
|
||||
border : '1px solid #FFF',
|
||||
padding : '2px',
|
||||
'font-size': '8pt',
|
||||
'background-color': '#000',
|
||||
color : "#000",
|
||||
border : '2px solid #000',
|
||||
padding : '10px',
|
||||
'font-size': '11pt',
|
||||
'font-weight' : 200,
|
||||
'background-color': '#FFF',
|
||||
'border-radius': '10px',
|
||||
}).appendTo("body");
|
||||
}
|
||||
|
||||
elem.bind("plothover", function (event, pos, item) {
|
||||
if (item) {
|
||||
var percent = parseFloat(item.series.percent).toFixed(1) + "%";
|
||||
tt(pos.pageX, pos.pageY,
|
||||
item.datapoint[1].toFixed(1) + " @ " +
|
||||
"<div style='vertical-align:middle;display:inline-block;background:"+item.series.color+";height:15px;width:15px;border-radius:10px;'></div> "+
|
||||
item.datapoint[1].toFixed(0) + " @ " +
|
||||
new Date(item.datapoint[0]).format('mm/dd HH:MM:ss'));
|
||||
} else {
|
||||
$("#pie-tooltip").remove();
|
||||
|
@ -1,23 +1,49 @@
|
||||
<div class="row-fluid" ng-controller="hits">
|
||||
<div ng-controller="hits">
|
||||
<div class="row-fluid">
|
||||
<div class="span2 "><label class="small">Font Size</label>
|
||||
<select class="input-mini" ng-model="panel.style['font-size']" ng-options="f for f in ['7pt','8pt','9pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span>
|
||||
</div>
|
||||
<div class="span2">
|
||||
<label class="small">Run Query</label><input type="checkbox" ng-model="panel.run_query" ng-checked="panel.run_query">
|
||||
<label class="small">Aggregate</label><input type="checkbox" ng-model="panel.aggregate" ng-checked="panel.aggregate">
|
||||
</div>
|
||||
<div class="span9" ng-show='!panel.run_query'>
|
||||
With query running disabled, this panel receives its hit count from a histogram panel. If multiple queries are running this <strong>will show the total of all queries</strong>.
|
||||
<div class="span3" ng-show="!panel.aggregate"><label class="small">Counter Style</label>
|
||||
<select class="input-small" ng-model="panel.arrangement" ng-options="f for f in ['none','horizontal','vertical']"></select></span>
|
||||
</div>
|
||||
<div class="span9" ng-show='panel.run_query'>
|
||||
This shows a simple count of how many records match your filtered query. If multiple queries are sent from a single panel the <strong>first query will be displayed</strong>
|
||||
<div class="span2" ng-show="!panel.aggregate">
|
||||
<label class="small">Chart</label><input type="checkbox" ng-model="panel.chart" ng-checked="panel.chart">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span9" ng-show='panel.run_query'>
|
||||
<form class="input-append">
|
||||
<h6>Query</h6>
|
||||
<input type="text" style="width:85%" ng-model="panel.query">
|
||||
<button class="btn" ng-click="get_data();"><i class="icon-search"></i></button>
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<form style="margin-bottom: 0px">
|
||||
<label class="small">Label</label>
|
||||
<input type="text" placeholder="New Label" style="width:70%" ng-model="newlabel">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span3"><h6>Font Size</h6>
|
||||
<select class="input-small" ng-model="panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span>
|
||||
<div class="span8">
|
||||
<form class="input-append" style="margin-bottom: 0px">
|
||||
<label class="small">Query</label>
|
||||
<input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
|
||||
<button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery=''"><i class="icon-plus"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="span1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid" ng-repeat="q in panel.query">
|
||||
<div class="span3">
|
||||
<form style="margin-bottom: 0px">
|
||||
<input type="text" style="width:70%" ng-model="q.label">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<form class="input-append" style="margin-bottom: 0px">
|
||||
<input type="text" style="width:80%" ng-model="q.query">
|
||||
<button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="span1">
|
||||
<i class="icon-remove pointer" ng-click="remove_query(q)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,3 +1,14 @@
|
||||
<kibana-panel ng-controller='hits' ng-init="init()">
|
||||
<p ng-style="panel.style">≥ {{hits}}</p>
|
||||
<div ng-show="panel.counters">
|
||||
<p ng-style="panel.style" ng-show="panel.aggregate">{{hits}}</p>
|
||||
<table ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'vertical'">
|
||||
<tr style="line-height:{{panel.style['font-size']}}" ng-repeat="query in plot.getData()">
|
||||
<td ng-show="panel.chart" style="background:{{query.color}};width:{{panel.style['font-size']}}"></td> <td style="padding-right:10px;padding-left:10px;">{{query.label}}</td><td>{{query.hits}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'horizontal'" ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;">
|
||||
<span ng-show='panel.chart'><div style="display:inline-block;border-radius:{{panel.style['font-size']}};background:{{query.color}};height:{{panel.style['font-size']}};width:{{panel.style['font-size']}}"></div></span> {{query.label}} ({{query.hits}}) <span ng-show="!$last">|</span>
|
||||
</div><br>
|
||||
</div><div style="clear:both"></div>
|
||||
<div ng-show='panel.chart && !panel.aggregate ' hits-chart params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
|
||||
</kibana-panel>
|
@ -5,64 +5,207 @@ angular.module('kibana.hits', [])
|
||||
var _d = {
|
||||
query : "*",
|
||||
group : "default",
|
||||
style : { "font-size": '36pt', "font-weight": "bold" },
|
||||
run_query : false
|
||||
style : { "font-size": '10pt'},
|
||||
aggregate : true,
|
||||
arrangement : 'vertical',
|
||||
chart : true,
|
||||
counters: true,
|
||||
count_pos: 'above'
|
||||
}
|
||||
_.defaults($scope.panel,_d)
|
||||
|
||||
$scope.init = function () {
|
||||
$scope.hits = 0;
|
||||
eventBus.register($scope,'time', function(event,time){
|
||||
if($scope.panel.run_query)
|
||||
set_time(time)
|
||||
set_time(time)
|
||||
});
|
||||
eventBus.register($scope,'query', function(event, query) {
|
||||
$scope.panel.query = _.isArray(query) ? query[0] : query;
|
||||
if($scope.panel.run_query)
|
||||
$scope.get_data();
|
||||
$scope.panel.query = _.map(query,function(q) {
|
||||
return {query: q, label: q};
|
||||
})
|
||||
$scope.get_data();
|
||||
});
|
||||
eventBus.register($scope,'hits', function(event, hits) {
|
||||
$scope.hits = hits;
|
||||
})
|
||||
// Now that we're all setup, request the time from our group
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'get_time')
|
||||
}
|
||||
|
||||
$scope.get_data = function() {
|
||||
$scope.get_data = function(segment,query_id) {
|
||||
delete $scope.panel.error
|
||||
$scope.panel.loading = true;
|
||||
|
||||
// Make sure we have everything for the request to complete
|
||||
if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time))
|
||||
return
|
||||
|
||||
$scope.panel.loading = true;
|
||||
var request = $scope.ejs.Request().indices($scope.panel.index);
|
||||
|
||||
var results = request
|
||||
.query(ejs.FilteredQuery(
|
||||
ejs.QueryStringQuery($scope.panel.query || '*'),
|
||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
||||
var request = $scope.ejs.Request().indices($scope.panel.index[_segment]);
|
||||
|
||||
// Build the question part of the query
|
||||
var queries = [];
|
||||
_.each($scope.panel.query, function(v) {
|
||||
queries.push($scope.ejs.FilteredQuery(
|
||||
ejs.QueryStringQuery(v.query || '*'),
|
||||
ejs.RangeFilter($scope.time.field)
|
||||
.from($scope.time.from)
|
||||
.to($scope.time.to)
|
||||
)
|
||||
.to($scope.time.to))
|
||||
)
|
||||
.size(0)
|
||||
.doSearch();
|
||||
});
|
||||
|
||||
// Build the facet part
|
||||
_.each(queries, function(v) {
|
||||
request = request
|
||||
.facet($scope.ejs.QueryFacet("query"+_.indexOf(queries,v))
|
||||
.query(v)
|
||||
).size(0)
|
||||
})
|
||||
|
||||
// TODO: Spy for hits panel
|
||||
//$scope.populate_modal(request);
|
||||
|
||||
// Then run it
|
||||
var results = request.doSearch();
|
||||
|
||||
// Populate scope when we have results
|
||||
results.then(function(results) {
|
||||
|
||||
$scope.panel.loading = false;
|
||||
if(_.isUndefined(results)) {
|
||||
$scope.panel.error = 'Your query was unsuccessful';
|
||||
if(_segment == 0) {
|
||||
$scope.hits = 0;
|
||||
$scope.data = [];
|
||||
query_id = $scope.query_id = new Date().getTime();
|
||||
}
|
||||
|
||||
// Check for error and abort if found
|
||||
if(!(_.isUndefined(results.error))) {
|
||||
$scope.panel.error = $scope.parse_error(results.error);
|
||||
return;
|
||||
}
|
||||
$scope.panel.error = false;
|
||||
$scope.hits = results.hits.total;
|
||||
if($scope.query_id === query_id) {
|
||||
var i = 0;
|
||||
_.each(results.facets, function(v, k) {
|
||||
var hits = _.isUndefined($scope.data[i]) || _segment == 0 ?
|
||||
v.count : $scope.data[i].hits+v.count
|
||||
$scope.hits += v.count
|
||||
|
||||
// Create series
|
||||
$scope.data[i] = {
|
||||
label: $scope.panel.query[i].label || "query"+(parseInt(i)+1),
|
||||
hits: hits,
|
||||
data: [[i,hits]]
|
||||
};
|
||||
|
||||
i++;
|
||||
});
|
||||
|
||||
$scope.$emit('render');
|
||||
if(_segment < $scope.panel.index.length-1)
|
||||
$scope.get_data(_segment+1,query_id)
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.remove_query = function(q) {
|
||||
$scope.panel.query = _.without($scope.panel.query,q);
|
||||
$scope.get_data();
|
||||
}
|
||||
|
||||
$scope.add_query = function(label,query) {
|
||||
$scope.panel.query.unshift({
|
||||
query: query,
|
||||
label: label,
|
||||
});
|
||||
$scope.get_data();
|
||||
}
|
||||
|
||||
function set_time(time) {
|
||||
$scope.time = time;
|
||||
$scope.panel.index = _.isUndefined(time.index) ? $scope.panel.index : time.index
|
||||
$scope.get_data();
|
||||
}
|
||||
|
||||
}).directive('hitsChart', function(eventBus) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, elem, attrs, ctrl) {
|
||||
|
||||
// Receive render events
|
||||
scope.$on('render',function(){
|
||||
render_panel();
|
||||
});
|
||||
|
||||
// Re-render if the window is resized
|
||||
angular.element(window).bind('resize', function(){
|
||||
render_panel();
|
||||
});
|
||||
|
||||
// Function for rendering panel
|
||||
function render_panel() {
|
||||
|
||||
var scripts = $LAB.script("common/lib/panels/jquery.flot.js")
|
||||
|
||||
// Populate element. Note that jvectormap appends, does not replace.
|
||||
scripts.wait(function(){
|
||||
// Populate element
|
||||
try {
|
||||
// Add plot to scope so we can build out own legend
|
||||
scope.plot = $.plot(elem, scope.data, {
|
||||
legend: { show: false },
|
||||
series: {
|
||||
lines: { show: false, },
|
||||
bars: { show: true, fill: 1, barWidth: 0.8, horizontal: false },
|
||||
shadowSize: 1
|
||||
},
|
||||
yaxis: { show: true, min: 0, color: "#000" },
|
||||
xaxis: { show: false },
|
||||
grid: {
|
||||
backgroundColor: '#fff',
|
||||
borderWidth: 0,
|
||||
borderColor: '#eee',
|
||||
color: "#eee",
|
||||
hoverable: true,
|
||||
},
|
||||
colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
|
||||
})
|
||||
|
||||
// Work around for missing legend at initialization
|
||||
if(!scope.$$phase)
|
||||
scope.$apply()
|
||||
|
||||
} catch(e) {
|
||||
elem.text(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function tt(x, y, contents) {
|
||||
var tooltip = $('#pie-tooltip').length ?
|
||||
$('#pie-tooltip') : $('<div id="pie-tooltip"></div>');
|
||||
//var tooltip = $('#pie-tooltip')
|
||||
tooltip.html(contents).css({
|
||||
position: 'absolute',
|
||||
top : y + 5,
|
||||
left : x + 5,
|
||||
color : "#000",
|
||||
border : '2px solid #000',
|
||||
padding : '10px',
|
||||
'font-size': '11pt',
|
||||
'font-weight' : 200,
|
||||
'background-color': '#FFF',
|
||||
'border-radius': '10px',
|
||||
}).appendTo("body");
|
||||
}
|
||||
|
||||
elem.bind("plothover", function (event, pos, item) {
|
||||
if (item) {
|
||||
tt(pos.pageX, pos.pageY,
|
||||
"<div style='vertical-align:middle;border-radius:10px;display:inline-block;background:"+item.series.color+";height:20px;width:20px'></div> "+
|
||||
item.datapoint[1].toFixed(0))
|
||||
} else {
|
||||
$("#pie-tooltip").remove();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
})
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class="span3">
|
||||
<form>
|
||||
<h6>Field</h6>
|
||||
<input type="text" class="input-small" ng-model="panel.field">
|
||||
<input bs-typeahead="fields.list" type="text" class="input-small" ng-model="panel.field">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span6">
|
||||
|
@ -128,12 +128,12 @@ angular.module('kibana.map', [])
|
||||
$('.jvectormap-label').css({
|
||||
"position" : "absolute",
|
||||
"display" : "none",
|
||||
"border" : "solid 1px #CDCDCD",
|
||||
"background" : "#292929",
|
||||
"color" : "white",
|
||||
"font-family" : "sans-serif, Verdana",
|
||||
"font-size" : "smaller",
|
||||
"padding" : "3px"
|
||||
"border" : "solid 2px #000",
|
||||
"background" : "#FFF",
|
||||
"font-weight" : 200,
|
||||
"border-radius": "5px",
|
||||
"color" : "#000",
|
||||
"padding" : "5px"
|
||||
})
|
||||
var count = _.isUndefined(scope.data[code]) ? 0 : scope.data[code];
|
||||
$('.jvectormap-label').text(label.text() + ": " + count);
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div class="span4">
|
||||
<form style="margin-bottom: 0px">
|
||||
<h6> Field</h6>
|
||||
<input type="text" style="width:90%" ng-model="panel.query.field">
|
||||
<input type="text" style="width:90%" bs-typeahead="fields.list" ng-model="panel.query.field">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span8">
|
||||
|
@ -2,6 +2,11 @@
|
||||
<span ng-show='panel.spyable' style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
|
||||
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
|
||||
</span>
|
||||
|
||||
<span ng-show="panel.legend" ng-repeat='series in legend' style='padding-right:5px'>
|
||||
<div style='white-space:nowrap;display:table-cell'>
|
||||
<div style="display:inline-block;background:{{series.color}};height:10px;width:10px;border-radius:5px;"></div>
|
||||
<div class='small' style='display:inline-block'>{{series.label}} ({{series.percent}}%)</div>
|
||||
</div>
|
||||
</span>
|
||||
<div pie params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
|
||||
</kibana-panel>
|
@ -268,14 +268,21 @@ angular.module('kibana.pie', [])
|
||||
},
|
||||
//grid: { hoverable: true, clickable: true },
|
||||
grid: { hoverable: true, clickable: true },
|
||||
legend: { show: scope.panel.legend },
|
||||
colors: ['#EB6841','#00A0B0','#6A4A3C','#EDC951','#CC333F']
|
||||
legend: { show: false },
|
||||
colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
|
||||
};
|
||||
|
||||
// Populate element
|
||||
if(elem.is(":visible")){
|
||||
scripts.wait(function(){
|
||||
$.plot(elem, scope.data, pie);
|
||||
var plot = $.plot(elem, scope.data, pie);
|
||||
scope.legend = [];
|
||||
_.each(plot.getData(),function(series) {
|
||||
var item = _.pick(series,'label','color','percent')
|
||||
item.percent = parseFloat(item.percent).toFixed(1)
|
||||
scope.legend.push(item)
|
||||
})
|
||||
console.log(scope.legend)
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -283,15 +290,16 @@ angular.module('kibana.pie', [])
|
||||
function piett(x, y, contents) {
|
||||
var tooltip = $('#pie-tooltip').length ?
|
||||
$('#pie-tooltip') : $('<div id="pie-tooltip"></div>');
|
||||
tooltip.text(contents).css({
|
||||
tooltip.html(contents).css({
|
||||
position: 'absolute',
|
||||
top : y + 10,
|
||||
left : x + 10,
|
||||
color : "#FFF",
|
||||
border : '1px solid #FFF',
|
||||
padding : '2px',
|
||||
'font-size': '8pt',
|
||||
'background-color': '#000',
|
||||
color : "#000",
|
||||
'font-weight': 200,
|
||||
'border-radius': '5px',
|
||||
border : '2px solid #000',
|
||||
padding : '10px',
|
||||
'background-color': '#FFF',
|
||||
}).appendTo("body");
|
||||
}
|
||||
|
||||
@ -305,7 +313,8 @@ angular.module('kibana.pie', [])
|
||||
elem.bind("plothover", function (event, pos, item) {
|
||||
if (item) {
|
||||
var percent = parseFloat(item.series.percent).toFixed(1) + "%";
|
||||
piett(pos.pageX, pos.pageY, percent + " " + (item.series.label||""));
|
||||
piett(pos.pageX, pos.pageY, "<div style='vertical-align:middle;display:inline-block;background:"+item.series.color+";height:15px;width:15px;border-radius:10px;'></div> " +
|
||||
(item.series.label||"")+ " " + percent);
|
||||
} else {
|
||||
$("#pie-tooltip").remove();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class='row-fluid' ng-show="panel.multi && panel.multi_arrange == 'horizontal'">
|
||||
<form class="form-inline" style="width:100%;" >
|
||||
<form class="form-inline" style="width:100%;margin:0px" >
|
||||
<span ng-repeat="q in panel.query">
|
||||
<span class="input-append" style="margin-bottom:0px;margin-right:5px">
|
||||
<button class="btn btn-danger" type="submit" style="width:50px;margin-left:-50px;visibility:hidden"></button>
|
||||
@ -31,7 +31,7 @@
|
||||
</span>
|
||||
</form>
|
||||
<button type="submit" class="btn btn-info" ng-click="send_query(panel.query)"><i class="icon-search"></i> Search</button>
|
||||
<button type="submit" class="btn" ng-click="send_query(panel.query);add_query();"><i class="icon-plus"></i> Add Query</button>
|
||||
<button type="submit" class="btn" ng-click="add_query();"><i class="icon-plus"></i> Add Query</button>
|
||||
</div>
|
||||
<div ng-show="panel.multi && panel.multi_arrange == 'vertical'">
|
||||
<form>
|
||||
|
@ -11,7 +11,7 @@
|
||||
<div class="span4">
|
||||
<form class="input-append">
|
||||
<h6>Add field</h6>
|
||||
<input bs-typeahead="all_fields" type="text" class="input-small" ng-model='newfield'>
|
||||
<input bs-typeahead="fields.list" type="text" class="input-small" ng-model='newfield'>
|
||||
<button class="btn" ng-click="toggle_field(newfield);newfield=''"><i class="icon-plus"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
angular.module('kibana.table', [])
|
||||
.controller('table', function($scope, eventBus) {
|
||||
.controller('table', function($scope, eventBus, fields) {
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
@ -76,6 +76,8 @@ angular.module('kibana.table', [])
|
||||
}
|
||||
|
||||
$scope.get_data = function(segment,query_id) {
|
||||
$scope.panel.error = false;
|
||||
|
||||
// Make sure we have everything for the request to complete
|
||||
if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time))
|
||||
return
|
||||
@ -98,7 +100,7 @@ angular.module('kibana.table', [])
|
||||
|
||||
$scope.populate_modal(request)
|
||||
|
||||
var results = request.doSearch();
|
||||
var results = request.doSearch()
|
||||
|
||||
// Populate scope when we have results
|
||||
results.then(function(results) {
|
||||
@ -110,11 +112,11 @@ angular.module('kibana.table', [])
|
||||
query_id = $scope.query_id = new Date().getTime()
|
||||
}
|
||||
|
||||
if(_.isUndefined(results)) {
|
||||
$scope.panel.error = 'Your query was unsuccessful';
|
||||
// Check for error and abort if found
|
||||
if(!(_.isUndefined(results.error))) {
|
||||
$scope.panel.error = $scope.parse_error(results.error);
|
||||
return;
|
||||
}
|
||||
$scope.panel.error = false;
|
||||
|
||||
// Check that we're still on the same query, if not stop
|
||||
if($scope.query_id === query_id) {
|
||||
@ -142,7 +144,6 @@ angular.module('kibana.table', [])
|
||||
|
||||
// This breaks, use $scope.data for this
|
||||
$scope.all_fields = get_all_fields($scope.data);
|
||||
|
||||
broadcast_results();
|
||||
|
||||
// If we're not sorting in reverse chrono order, query every index for
|
||||
|
@ -23,7 +23,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="since">
|
||||
<div class="span10">
|
||||
<div class="span5">
|
||||
<form class="nomargin">
|
||||
<label><small>Since</small></label>
|
||||
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker>
|
||||
|
@ -111,10 +111,6 @@ angular.module('kibana.timepicker', [])
|
||||
}
|
||||
$scope.time_apply();
|
||||
});
|
||||
|
||||
$scope.$on('render', function (){
|
||||
$scope.time_apply();
|
||||
});
|
||||
}
|
||||
|
||||
$scope.set_interval = function (refresh_interval) {
|
||||
@ -167,6 +163,10 @@ angular.module('kibana.timepicker', [])
|
||||
$scope.time_apply();
|
||||
}
|
||||
|
||||
$scope.close_edit = function() {
|
||||
$scope.time_apply();
|
||||
}
|
||||
|
||||
$scope.time_check = function(){
|
||||
|
||||
// If time picker is defined (on initialization)
|
||||
|
@ -1,17 +1,21 @@
|
||||
|
||||
<div class="row-fluid container">
|
||||
<div class="row-fluid container" style="margin-top:10px">
|
||||
<!-- Rows -->
|
||||
<div ng-controller="dashcontrol" ng-init="init()"></div>
|
||||
<div class="row-fluid" ng-controller="RowCtrl" ng-repeat="(row_name, row) in dashboards.rows">
|
||||
<div class="span12">
|
||||
<div class="row-fluid kibana-row" ng-controller="RowCtrl" ng-repeat="(row_name, row) in dashboards.rows" ng-style="row_style(row)">
|
||||
<div class="row-control">
|
||||
<div class="row-fluid row-header" style="padding:0px;margin:0px;height:0px">
|
||||
<div class="span12" style="min-height:5px;vertical-align:bottom">
|
||||
<i ng-show="row.editable" class="icon-edit pointer editlink" bs-modal="'partials/roweditor.html'"></i>
|
||||
<span ng-show="row.collapsable" ng-click="toggle_row(row)" class="pointer"><i class="pointer" ng-class="{'icon-caret-down': !row.collapse,'icon-caret-right': row.collapse}"></i> <small>{{row.title}}</small></span>
|
||||
<small ng-hide="row.collapsable">{{row.title}}</small>
|
||||
<div style="vertical-align:bottom">
|
||||
<div ng-show="row.collapsable">
|
||||
<div ng-class="{'row-open': !row.collapse, 'row-close': row.collapse}" style="position:absolute;margin-left:-60px;">
|
||||
<span class='pointer' ng-click="toggle_row(row)">{{row.title}}</span>
|
||||
<i ng-show="row.editable" class="icon-edit pointer editlink" bs-modal="'partials/roweditor.html'"></i>
|
||||
</div>
|
||||
</div>
|
||||
<small ng-hide="row.collapsable" class="rotated">{{row.title}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid" style="padding-top:10px" ng-hide="row.collapse">
|
||||
<div class="row-fluid" style="padding-top:0px" ng-hide="row.collapse">
|
||||
<!-- Panels -->
|
||||
<div ng-repeat="(name, panel) in row.panels" ng-hide="panel.span == 0 || panel.hide" class="span{{panel.span}} panel" style="min-height:{{row.height}}; position:relative">
|
||||
<!-- Error Panel -->
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>{{panel.title}} <small>editor</small></h3>
|
||||
<h3>{{panel.title}} Editor</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
@ -13,5 +13,5 @@
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-success" ng-click="dismiss();send_render()">Close</button>
|
||||
<button type="button" class="btn btn-success" ng-click="dismiss();close_edit()">Close</button>
|
||||
</div>
|
@ -56,5 +56,5 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-success" ng-click="dismiss();reset_panel();send_render()">Close</button>
|
||||
<button type="button" class="btn btn-success" ng-click="dismiss();reset_panel();close_edit()">Close</button>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user