kibana-sinatra 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/kibana-sinatra.gemspec +1 -0
  4. data/lib/kibana/assets/app/app.js +8 -3
  5. data/lib/kibana/assets/app/components/kbn.js +45 -10
  6. data/lib/kibana/assets/app/components/{underscore.extended.js → lodash.extended.js} +2 -4
  7. data/lib/kibana/assets/app/components/require.config.js +5 -6
  8. data/lib/kibana/assets/app/components/settings.js +1 -1
  9. data/lib/kibana/assets/app/controllers/dash.js +10 -5
  10. data/lib/kibana/assets/app/controllers/dashLoader.js +1 -1
  11. data/lib/kibana/assets/app/controllers/pulldown.js +1 -1
  12. data/lib/kibana/assets/app/controllers/row.js +1 -1
  13. data/lib/kibana/assets/app/dashboards/default.json +1 -1
  14. data/lib/kibana/assets/app/dashboards/logstash.js +4 -4
  15. data/lib/kibana/assets/app/dashboards/logstash.json +1 -1
  16. data/lib/kibana/assets/app/directives/addPanel.js +1 -1
  17. data/lib/kibana/assets/app/directives/arrayJoin.js +1 -1
  18. data/lib/kibana/assets/app/directives/configModal.js +23 -5
  19. data/lib/kibana/assets/app/directives/kibanaPanel.js +70 -50
  20. data/lib/kibana/assets/app/directives/kibanaSimplePanel.js +1 -1
  21. data/lib/kibana/assets/app/factories/store.js +59 -0
  22. data/lib/kibana/assets/app/filters/all.js +6 -13
  23. data/lib/kibana/assets/app/panels/bettermap/module.html +5 -0
  24. data/lib/kibana/assets/app/panels/bettermap/module.js +1 -1
  25. data/lib/kibana/assets/app/panels/column/editor.html +1 -1
  26. data/lib/kibana/assets/app/panels/column/module.js +7 -6
  27. data/lib/kibana/assets/app/panels/dashcontrol/module.js +1 -1
  28. data/lib/kibana/assets/app/panels/derivequeries/module.js +1 -1
  29. data/lib/kibana/assets/app/panels/fields/module.js +1 -1
  30. data/lib/kibana/assets/app/panels/filtering/module.html +10 -17
  31. data/lib/kibana/assets/app/panels/filtering/module.js +19 -1
  32. data/lib/kibana/assets/app/panels/histogram/module.html +4 -4
  33. data/lib/kibana/assets/app/panels/histogram/module.js +62 -12
  34. data/lib/kibana/assets/app/panels/histogram/timeSeries.js +6 -3
  35. data/lib/kibana/assets/app/panels/hits/module.js +1 -1
  36. data/lib/kibana/assets/app/panels/map/module.js +1 -1
  37. data/lib/kibana/assets/app/panels/pie/editor.html +1 -1
  38. data/lib/kibana/assets/app/panels/pie/module.js +1 -1
  39. data/lib/kibana/assets/app/panels/query/meta.html +1 -1
  40. data/lib/kibana/assets/app/panels/query/module.html +1 -1
  41. data/lib/kibana/assets/app/panels/query/module.js +2 -7
  42. data/lib/kibana/assets/app/panels/query/query.css +9 -7
  43. data/lib/kibana/assets/app/panels/sparklines/module.js +2 -2
  44. data/lib/kibana/assets/app/panels/sparklines/timeSeries.js +3 -3
  45. data/lib/kibana/assets/app/panels/stats/editor.html +36 -0
  46. data/lib/kibana/assets/app/panels/stats/module.html +15 -0
  47. data/lib/kibana/assets/app/panels/stats/module.js +199 -0
  48. data/lib/kibana/assets/app/panels/table/editor.html +23 -27
  49. data/lib/kibana/assets/app/panels/table/micropanel.html +3 -1
  50. data/lib/kibana/assets/app/panels/table/module.js +7 -1
  51. data/lib/kibana/assets/app/panels/terms/editor.html +16 -3
  52. data/lib/kibana/assets/app/panels/terms/module.html +14 -5
  53. data/lib/kibana/assets/app/panels/terms/module.js +66 -18
  54. data/lib/kibana/assets/app/panels/text/module.js +1 -1
  55. data/lib/kibana/assets/app/panels/timepicker/editor.html +14 -12
  56. data/lib/kibana/assets/app/panels/timepicker/module.html +3 -8
  57. data/lib/kibana/assets/app/panels/timepicker/module.js +1 -1
  58. data/lib/kibana/assets/app/panels/trends/module.js +1 -1
  59. data/lib/kibana/assets/app/partials/dashLoader.html +10 -10
  60. data/lib/kibana/assets/app/partials/dashboard.html +35 -44
  61. data/lib/kibana/assets/app/partials/dasheditor.html +7 -5
  62. data/lib/kibana/assets/app/partials/paneleditor.html +2 -1
  63. data/lib/kibana/assets/app/partials/panelgeneral.html +1 -1
  64. data/lib/kibana/assets/app/partials/roweditor.html +11 -9
  65. data/lib/kibana/assets/app/services/alertSrv.js +1 -1
  66. data/lib/kibana/assets/app/services/dashboard.js +27 -14
  67. data/lib/kibana/assets/app/services/esVersion.js +70 -31
  68. data/lib/kibana/assets/app/services/fields.js +14 -37
  69. data/lib/kibana/assets/app/services/filterSrv.js +7 -11
  70. data/lib/kibana/assets/app/services/kbnIndex.js +24 -15
  71. data/lib/kibana/assets/app/services/panelMove.js +1 -1
  72. data/lib/kibana/assets/app/services/querySrv.js +20 -6
  73. data/lib/kibana/assets/app/services/timer.js +1 -1
  74. data/lib/kibana/assets/css/bootstrap.dark.min.css +1 -1
  75. data/lib/kibana/assets/css/bootstrap.light.min.css +1 -1
  76. data/lib/kibana/assets/img/cubes.png +0 -0
  77. data/lib/kibana/assets/img/light.png +0 -0
  78. data/lib/kibana/assets/index.html +3 -2
  79. data/lib/kibana/assets/vendor/LICENSE.json +90 -0
  80. data/lib/kibana/assets/vendor/angular/angular-cookies.js +185 -0
  81. data/lib/kibana/assets/vendor/angular/angular-dragdrop.js +33 -4
  82. data/lib/kibana/assets/vendor/blob.js +178 -0
  83. data/lib/kibana/assets/vendor/bootstrap/bootstrap.js +6 -1
  84. data/lib/kibana/assets/vendor/bootstrap/less/bak/bootswatch.dark.less +555 -0
  85. data/lib/kibana/assets/vendor/bootstrap/less/bak/variables.dark.less +304 -0
  86. data/lib/kibana/assets/vendor/bootstrap/less/bootswatch.dark.less +349 -327
  87. data/lib/kibana/assets/vendor/bootstrap/less/bootswatch.light.less +590 -7
  88. data/lib/kibana/assets/vendor/bootstrap/less/modals.less +1 -1
  89. data/lib/kibana/assets/vendor/bootstrap/less/overrides.less +191 -75
  90. data/lib/kibana/assets/vendor/bootstrap/less/variables.dark.less +96 -97
  91. data/lib/kibana/assets/vendor/bootstrap/less/variables.light.less +84 -81
  92. data/lib/kibana/assets/vendor/jquery/jquery.flot.events.js +39 -51
  93. data/lib/kibana/assets/vendor/lodash.js +6785 -0
  94. data/lib/kibana/assets/vendor/numeral.js +565 -0
  95. data/lib/kibana/sinatra/version.rb +1 -1
  96. data/lib/kibana/views/config.erb +1 -0
  97. data/test/sinatra_test.rb +2 -2
  98. metadata +30 -4
  99. data/lib/kibana/assets/vendor/underscore.js +0 -1246
@@ -1,6 +1,6 @@
1
1
  define([
2
2
  'angular',
3
- 'underscore'
3
+ 'lodash'
4
4
  ],
5
5
  function (angular, _) {
6
6
  'use strict';
@@ -0,0 +1,59 @@
1
+ define([
2
+ 'angular',
3
+ 'lodash'
4
+ ],
5
+ function (angular, _) {
6
+ 'use strict';
7
+
8
+ var module = angular.module('kibana.factories');
9
+ module.factory('storeFactory', function() {
10
+
11
+ return function storeFactory($scope, name, defaults) {
12
+ if (!_.isFunction($scope.$watch)) {
13
+ throw new TypeError('Invalid scope.');
14
+ }
15
+ if (!_.isString(name)) {
16
+ throw new TypeError('Invalid name, expected a string that the is unique to this store.');
17
+ }
18
+ if (defaults && !_.isPlainObject(defaults)) {
19
+ throw new TypeError('Invalid defaults, expected a simple object or nothing');
20
+ }
21
+
22
+ defaults = defaults || {};
23
+
24
+ // get the current value, parse if it exists
25
+ var current = localStorage.getItem(name);
26
+ if (current != null) {
27
+ try {
28
+ current = JSON.parse(current);
29
+ } catch (e) {
30
+ current = null;
31
+ }
32
+ }
33
+
34
+ if (current == null) {
35
+ current = _.clone(defaults);
36
+ } else if (_.isPlainObject(current)) {
37
+ _.defaults(current, defaults);
38
+ } else {
39
+ throw new TypeError('Invalid store value' + current);
40
+ }
41
+
42
+ $scope[name] = current;
43
+
44
+ // listen for changes and store them in localStorage.
45
+ // delete the value to reset to the defaults, ie. `delete $scope[name]` -> digest cycle -> `$scope[name] == defaults`
46
+ $scope.$watch(name, function (val) {
47
+ if (val === void 0) {
48
+ localStorage.removeItem(name);
49
+ $scope[name] = _.clone(defaults);
50
+ } else {
51
+ localStorage.setItem(name, JSON.stringify(val));
52
+ }
53
+ }, true);
54
+
55
+ return current;
56
+ };
57
+ });
58
+
59
+ });
@@ -1,4 +1,9 @@
1
- define(['angular', 'jquery', 'underscore', 'moment'], function (angular, $, _, moment) {
1
+ define([
2
+ 'angular',
3
+ 'jquery',
4
+ 'lodash',
5
+ 'moment'
6
+ ], function (angular, $, _, moment) {
2
7
  'use strict';
3
8
 
4
9
  var module = angular.module('kibana.filters');
@@ -24,18 +29,6 @@ define(['angular', 'jquery', 'underscore', 'moment'], function (angular, $, _, m
24
29
  };
25
30
  });
26
31
 
27
- /*
28
- Filter an array of objects by elasticsearch version requirements
29
- */
30
- module.filter('esVersion', function(esVersion) {
31
- return function(items, require) {
32
- var ret = _.filter(items,function(qt) {
33
- return esVersion.is(qt[require]) ? true : false;
34
- });
35
- return ret;
36
- };
37
- });
38
-
39
32
  module.filter('slice', function() {
40
33
  return function(arr, start, end) {
41
34
  if(!_.isUndefined(arr)) {
@@ -1,4 +1,9 @@
1
1
  <div ng-controller='bettermap' ng-init="init()">
2
+ <style>
3
+ .leaflet-label {
4
+ color: #fff;
5
+ }
6
+ </style>
2
7
  <!-- This solution might work well for other panels that have trouble with heights -->
3
8
  <div style="padding-right:10px;padding-top:10px;height:{{panel.height|| row.height}};overflow:hidden">
4
9
  <div bettermap id='bettermap' params="{{panel}}" style="height:100%"></div>
@@ -19,7 +19,7 @@
19
19
  define([
20
20
  'angular',
21
21
  'app',
22
- 'underscore',
22
+ 'lodash',
23
23
  './leaflet/leaflet-src',
24
24
  'require',
25
25
 
@@ -5,7 +5,7 @@
5
5
  <small>Select Type</small>
6
6
  <div ng-show="!(_.isUndefined(new_panel.type))">
7
7
  <div column-edit panel="new_panel" config="config" row="row" dashboards="dashboards" type="new_panel.type"></div>
8
- <button ng-click="add_panel(new_panel); reset_panel();" class="btn btn-primary">Create Panel</button><br>
8
+ <button ng-click="add_panel(panel,new_panel); reset_panel();" class="btn btn-primary">Create Panel</button><br>
9
9
  </div>
10
10
  </div>
11
11
  <div class="row-fluid">
@@ -14,7 +14,7 @@
14
14
  define([
15
15
  'angular',
16
16
  'app',
17
- 'underscore',
17
+ 'lodash',
18
18
  'config'
19
19
  ],
20
20
  function (angular, app, _, config) {
@@ -59,8 +59,8 @@ function (angular, app, _, config) {
59
59
  $scope.$broadcast('render');
60
60
  };
61
61
 
62
- $scope.add_panel = function(panel) {
63
- $scope.panel.panels.push(panel);
62
+ $scope.add_panel = function(panel,newPanel) {
63
+ panel.panels.push(newPanel);
64
64
  };
65
65
 
66
66
  $scope.reset_panel = function(type) {
@@ -68,11 +68,12 @@ function (angular, app, _, config) {
68
68
  loading: false,
69
69
  error: false,
70
70
  sizeable: false,
71
- span: 12,
71
+ draggable: false,
72
+ removable: false,
73
+ span: 10,
72
74
  height: "150px",
73
75
  editable: true,
74
- type: type,
75
- draggable: false
76
+ type: type
76
77
  };
77
78
  };
78
79
 
@@ -19,7 +19,7 @@
19
19
  define([
20
20
  'angular',
21
21
  'app',
22
- 'underscore'
22
+ 'lodash'
23
23
  ],
24
24
  function(angular, app, _) {
25
25
  'use strict';
@@ -14,7 +14,7 @@
14
14
  define([
15
15
  'angular',
16
16
  'app',
17
- 'underscore'
17
+ 'lodash'
18
18
  ],
19
19
  function (angular, app, _) {
20
20
  'use strict';
@@ -4,7 +4,7 @@
4
4
  define([
5
5
  'angular',
6
6
  'app',
7
- 'underscore'
7
+ 'lodash'
8
8
  ],
9
9
  function (angular, app, _) {
10
10
  'use strict';
@@ -8,23 +8,13 @@
8
8
  vertical-align: top;
9
9
  width: 220px;
10
10
  padding: 5px 5px 0px 5px;
11
- border: #555 1px solid;
12
11
  margin: 5px 5px 5px 0px;
12
+ color: #fff;
13
+ background-color: #444;
13
14
  }
14
15
  .filter-panel-filter ul {
15
16
  margin-bottom: 3px;
16
17
  }
17
-
18
-
19
- .filter-must {
20
- border-top: #7EB26D 3px solid;
21
- }
22
- .filter-mustNot {
23
- border-top: #E24D42 3px solid;
24
- }
25
- .filter-either {
26
- border-top: #EF843C 3px solid;
27
- }
28
18
  .filter-deselected {
29
19
  opacity: 0.5;
30
20
  }
@@ -39,7 +29,6 @@
39
29
  }
40
30
  .filter-apply {
41
31
  float:right;
42
- margin-bottom: 5px;
43
32
  }
44
33
  </style>
45
34
 
@@ -47,7 +36,7 @@
47
36
  <span ng-show="filterSrv.ids.length == 0">
48
37
  <h5>No filters available</h5>
49
38
  </span>
50
- <div ng-repeat="id in filterSrv.ids" class="small filter-panel-filter filter-{{filterSrv.list[id].mandate}}" ng-class="{'filter-deselected': !filterSrv.list[id].active}">
39
+ <div ng-repeat="id in filterSrv.ids" class="small filter-panel-filter">
51
40
  <div>
52
41
  <strong>{{filterSrv.list[id].type}}</strong>
53
42
  <span ng-show="!filterSrv.list[id].editing && isEditable(filterSrv.list[id])" class="filter-mandate" ng-click="filterSrv.list[id].editing = true">
@@ -57,6 +46,8 @@
57
46
  {{filterSrv.list[id].mandate}}
58
47
  </span>
59
48
 
49
+ <i ng-class="getFilterClass(filterSrv.list[id])" class="icon-circle"></i>
50
+
60
51
  <span ng-show="filterSrv.list[id].editing">
61
52
  <select class="input-small" ng-model="filterSrv.list[id].mandate" ng-options="f for f in ['must','mustNot','either']"></select>
62
53
  </span>
@@ -80,11 +71,13 @@
80
71
  </li>
81
72
  </ul>
82
73
  <div>
83
- <input type="submit" value="Apply" ng-click="filterSrv.list[id].editing=undefined;refresh()" class="filter-apply btn btn-success btn-mini" bs-tooltip="'Save and refresh'"/>
84
- <button ng-click="filterSrv.list[id].editing=undefined" class="filter-apply btn btn-mini" bs-tooltip="'Save without refresh'">Save</button>
74
+
75
+ <button type="submit" ng-click="filterSrv.list[id].editing=undefined;refresh()" class="filter-apply btn btn-mini btn-success" bs-tooltip="'Save and refresh'">Apply</button>
76
+
77
+ <button ng-click="filterSrv.list[id].editing=undefined" class="filter-apply btn-mini btn" bs-tooltip="'Save without refresh'">Save</button>
85
78
  </div>
86
79
  </form>
87
80
  </div>
88
- <i class="link icon-plus-sign" ng-click="add()" bs-tooltip="'Add a query filter'" data-placement="right"></i>
81
+ <i class="pointer icon-plus-sign" ng-click="add()" bs-tooltip="'Add a query filter'" data-placement="right"></i>
89
82
  </div>
90
83
  </div>
@@ -6,7 +6,7 @@
6
6
  define([
7
7
  'angular',
8
8
  'app',
9
- 'underscore'
9
+ 'lodash'
10
10
  ],
11
11
  function (angular, app, _) {
12
12
  'use strict';
@@ -67,6 +67,24 @@ function (angular, app, _) {
67
67
  return !_.contains(['type','id','alias','mandate','active','editing'],key);
68
68
  };
69
69
 
70
+ $scope.getFilterClass = function(filter) {
71
+ if(filter.active !== true) {
72
+ return 'muted';
73
+ } else {
74
+ switch (filter.mandate)
75
+ {
76
+ case 'must':
77
+ return 'text-success';
78
+ case 'mustNot':
79
+ return 'text-error';
80
+ case 'either':
81
+ return 'text-warning';
82
+ default:
83
+ return 'text-info';
84
+ }
85
+ }
86
+ };
87
+
70
88
  $scope.isEditable = function(filter) {
71
89
  var uneditable = ['time'];
72
90
  if(_.contains(uneditable,filter.type)) {
@@ -35,11 +35,11 @@
35
35
  </style>
36
36
  <div>
37
37
  <span ng-show='panel.options'>
38
- <a class="link underline small" ng-show='panel.options' ng-click="options=!options">
39
- <i ng-show="!options" class="icon-caret-right"></i><i ng-show="options" class="icon-caret-down"></i> View
38
+ <a class="link small" ng-show='panel.options' ng-click="options=!options">
39
+ View <i ng-show="!options" class="icon-caret-right"></i><i ng-show="options" class="icon-caret-down"></i>
40
40
  </a> |&nbsp
41
41
  </span>
42
- <span ng-show='panel.zoomlinks && data'>
42
+ <span ng-show='panel.zoomlinks && !_.isUndefined(data)'>
43
43
  <!--<a class='small' ng-click='zoom(0.5)'><i class='icon-zoom-in'></i> Zoom In</a>-->
44
44
  <a class='small' ng-click='zoom(2)'><i class='icon-zoom-out'></i> Zoom Out</a> |&nbsp
45
45
  </span>
@@ -51,7 +51,7 @@
51
51
  <span ng-show="panel.legend_counts"> ({{series.hits}})</span>
52
52
  </span>
53
53
  </span>
54
- <span ng-show="panel.legend" class="small"><span ng-show="panel.derivative">change in </span><span class="strong" ng-show="panel.value_field && panel.mode != 'count'">{{panel.value_field}}</span> {{panel.mode}} per <strong ng-hide="panel.scaleSeconds">{{panel.interval}}</strong><strong ng-show="panel.scaleSeconds">1s</strong> | (<strong>{{hits}}</strong> hits)</span>
54
+ <span ng-show="panel.legend" class="small"><span ng-show="panel.derivative"> change in </span><span class="strong" ng-show="panel.value_field && panel.mode != 'count'">{{panel.value_field}}</span> {{panel.mode}} per <strong ng-hide="panel.scaleSeconds">{{panel.interval}}</strong><strong ng-show="panel.scaleSeconds">1s</strong> | (<strong>{{hits}}</strong> hits)</span>
55
55
  </div>
56
56
  <form class="form-inline bordered histogram-options" ng-show="options">
57
57
  <span>
@@ -15,10 +15,11 @@ define([
15
15
  'angular',
16
16
  'app',
17
17
  'jquery',
18
- 'underscore',
18
+ 'lodash',
19
19
  'kbn',
20
20
  'moment',
21
21
  './timeSeries',
22
+ 'numeral',
22
23
  'jquery.flot',
23
24
  'jquery.flot.events',
24
25
  'jquery.flot.selection',
@@ -27,7 +28,7 @@ define([
27
28
  'jquery.flot.stack',
28
29
  'jquery.flot.stackpercent'
29
30
  ],
30
- function (angular, app, $, _, kbn, moment, timeSeries) {
31
+ function (angular, app, $, _, kbn, moment, timeSeries, numeral) {
31
32
 
32
33
  'use strict';
33
34
 
@@ -327,6 +328,9 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
327
328
 
328
329
  $scope.panelMeta.loading = true;
329
330
  request = $scope.ejs.Request().indices(dashboard.indices[segment]);
331
+ if (!$scope.panel.annotate.enable) {
332
+ request.searchType("count");
333
+ }
330
334
 
331
335
  $scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
332
336
 
@@ -398,7 +402,8 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
398
402
 
399
403
  var i = 0,
400
404
  time_series,
401
- hits;
405
+ hits,
406
+ counters; // Stores the bucketed hit counts.
402
407
 
403
408
  _.each(queries, function(q) {
404
409
  var query_results = results.facets[q.id];
@@ -413,16 +418,46 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
413
418
  };
414
419
  time_series = new timeSeries.ZeroFilled(tsOpts);
415
420
  hits = 0;
421
+ counters = {};
416
422
  } else {
417
423
  time_series = data[i].time_series;
418
424
  hits = data[i].hits;
425
+ counters = data[i].counters;
419
426
  }
420
427
 
421
428
  // push each entry into the time series, while incrementing counters
422
429
  _.each(query_results.entries, function(entry) {
423
- time_series.addValue(entry.time, entry[$scope.panel.mode]);
430
+ var value;
431
+
424
432
  hits += entry.count; // The series level hits counter
425
433
  $scope.hits += entry.count; // Entire dataset level hits counter
434
+ counters[entry.time] = (counters[entry.time] || 0) + entry.count;
435
+
436
+ if($scope.panel.mode === 'count') {
437
+ value = (time_series._data[entry.time] || 0) + entry.count;
438
+ } else if ($scope.panel.mode === 'mean') {
439
+ // Compute the ongoing mean by
440
+ // multiplying the existing mean by the existing hits
441
+ // plus the new mean multiplied by the new hits
442
+ // divided by the total hits
443
+ value = (((time_series._data[entry.time] || 0)*(counters[entry.time]-entry.count)) +
444
+ entry.mean*entry.count)/(counters[entry.time]);
445
+ } else if ($scope.panel.mode === 'min'){
446
+ if(_.isUndefined(time_series._data[entry.time])) {
447
+ value = entry.min;
448
+ } else {
449
+ value = time_series._data[entry.time] < entry.min ? time_series._data[entry.time] : entry.min;
450
+ }
451
+ } else if ($scope.panel.mode === 'max'){
452
+ if(_.isUndefined(time_series._data[entry.time])) {
453
+ value = entry.max;
454
+ } else {
455
+ value = time_series._data[entry.time] > entry.max ? time_series._data[entry.time] : entry.max;
456
+ }
457
+ } else if ($scope.panel.mode === 'total'){
458
+ value = (time_series._data[entry.time] || 0) + entry.total;
459
+ }
460
+ time_series.addValue(entry.time, value);
426
461
  });
427
462
 
428
463
  $scope.legend[i] = {query:q,hits:hits};
@@ -430,7 +465,8 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
430
465
  data[i] = {
431
466
  info: q,
432
467
  time_series: time_series,
433
- hits: hits
468
+ hits: hits,
469
+ counters: counters
434
470
  };
435
471
 
436
472
  i++;
@@ -539,6 +575,10 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
539
575
  render_panel(data);
540
576
  });
541
577
 
578
+ scope.$watch('panel.span', function(){
579
+ render_panel(data);
580
+ });
581
+
542
582
  // Re-render if the window is resized
543
583
  angular.element(window).bind('resize', function(){
544
584
  render_panel(data);
@@ -571,7 +611,9 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
571
611
  // Function for rendering panel
572
612
  function render_panel(data) {
573
613
  // IE doesn't work without this
574
- elem.css({height:scope.panel.height || scope.row.height});
614
+ try {
615
+ elem.css({height:scope.panel.height || scope.row.height});
616
+ } catch(e) {return;}
575
617
 
576
618
  // Populate from the query service
577
619
  try {
@@ -638,18 +680,22 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
638
680
  }
639
681
  };
640
682
 
641
- if(scope.panel.y_format === 'bytes') {
683
+ if (scope.panel.y_format === 'bytes') {
642
684
  options.yaxis.mode = "byte";
685
+ options.yaxis.tickFormatter = function (val, axis) {
686
+ return kbn.byteFormat(val, 0, axis.tickSize);
687
+ };
643
688
  }
644
689
 
645
- if(scope.panel.y_format === 'short') {
646
- options.yaxis.tickFormatter = function(val) {
647
- return kbn.shortFormat(val,0);
690
+ if (scope.panel.y_format === 'short') {
691
+ options.yaxis.tickFormatter = function (val, axis) {
692
+ return kbn.shortFormat(val, 0, axis.tickSize);
648
693
  };
649
694
  }
650
695
 
651
696
  if(scope.panel.annotate.enable) {
652
697
  options.events = {
698
+ clustering: true,
653
699
  levels: 1,
654
700
  data: scope.annotations,
655
701
  types: {
@@ -723,7 +769,9 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
723
769
 
724
770
  var $tooltip = $('<div>');
725
771
  elem.bind("plothover", function (event, pos, item) {
726
- var group, value, timestamp;
772
+ var group, value, timestamp, interval;
773
+ interval = scope.panel.legend ?
774
+ "" : " per " + (scope.panel.scaleSeconds ? '1s' : scope.panel.interval);
727
775
  if (item) {
728
776
  if (item.series.info.alias || scope.panel.tooltip.query_as_alias) {
729
777
  group = '<small style="font-size:0.9em;">' +
@@ -741,13 +789,15 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
741
789
  }
742
790
  if(scope.panel.y_format === 'short') {
743
791
  value = kbn.shortFormat(value,2);
792
+ } else {
793
+ value = numeral(value).format('0,0[.]000');
744
794
  }
745
795
  timestamp = scope.panel.timezone === 'browser' ?
746
796
  moment(item.datapoint[0]).format('YYYY-MM-DD HH:mm:ss') :
747
797
  moment.utc(item.datapoint[0]).format('YYYY-MM-DD HH:mm:ss');
748
798
  $tooltip
749
799
  .html(
750
- group + value + " @ " + timestamp
800
+ group + value + interval + " @ " + timestamp
751
801
  )
752
802
  .place_tt(pos.pageX, pos.pageY);
753
803
  } else {