kibana-sinatra 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (239) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/kibana-sinatra.gemspec +24 -0
  8. data/lib/kibana/assets/app/app.js +140 -0
  9. data/lib/kibana/assets/app/components/extend-jquery.js +46 -0
  10. data/lib/kibana/assets/app/components/kbn.js +332 -0
  11. data/lib/kibana/assets/app/components/require.config.js +90 -0
  12. data/lib/kibana/assets/app/components/settings.js +27 -0
  13. data/lib/kibana/assets/app/components/underscore.extended.js +32 -0
  14. data/lib/kibana/assets/app/controllers/all.js +5 -0
  15. data/lib/kibana/assets/app/controllers/dash.js +91 -0
  16. data/lib/kibana/assets/app/controllers/dashLoader.js +123 -0
  17. data/lib/kibana/assets/app/controllers/row.js +76 -0
  18. data/lib/kibana/assets/app/dashboards/blank.json +42 -0
  19. data/lib/kibana/assets/app/dashboards/default.json +89 -0
  20. data/lib/kibana/assets/app/dashboards/guided.json +274 -0
  21. data/lib/kibana/assets/app/dashboards/logstash.js +181 -0
  22. data/lib/kibana/assets/app/dashboards/logstash.json +222 -0
  23. data/lib/kibana/assets/app/dashboards/noted.json +202 -0
  24. data/lib/kibana/assets/app/directives/addPanel.js +30 -0
  25. data/lib/kibana/assets/app/directives/all.js +10 -0
  26. data/lib/kibana/assets/app/directives/arrayJoin.js +34 -0
  27. data/lib/kibana/assets/app/directives/confirmClick.js +26 -0
  28. data/lib/kibana/assets/app/directives/dashUpload.js +37 -0
  29. data/lib/kibana/assets/app/directives/kibanaPanel.js +103 -0
  30. data/lib/kibana/assets/app/directives/ngBlur.js +20 -0
  31. data/lib/kibana/assets/app/directives/ngModelOnBlur.js +25 -0
  32. data/lib/kibana/assets/app/directives/tip.js +20 -0
  33. data/lib/kibana/assets/app/filters/all.js +110 -0
  34. data/lib/kibana/assets/app/panels/bettermap/editor.html +17 -0
  35. data/lib/kibana/assets/app/panels/bettermap/leaflet/images/layers-2x.png +0 -0
  36. data/lib/kibana/assets/app/panels/bettermap/leaflet/images/layers.png +0 -0
  37. data/lib/kibana/assets/app/panels/bettermap/leaflet/images/marker-icon-2x.png +0 -0
  38. data/lib/kibana/assets/app/panels/bettermap/leaflet/images/marker-icon.png +0 -0
  39. data/lib/kibana/assets/app/panels/bettermap/leaflet/images/marker-shadow.png +0 -0
  40. data/lib/kibana/assets/app/panels/bettermap/leaflet/leaflet-src.js +8724 -0
  41. data/lib/kibana/assets/app/panels/bettermap/leaflet/leaflet.css +463 -0
  42. data/lib/kibana/assets/app/panels/bettermap/leaflet/leaflet.ie.css +51 -0
  43. data/lib/kibana/assets/app/panels/bettermap/leaflet/leaflet.js +8 -0
  44. data/lib/kibana/assets/app/panels/bettermap/leaflet/plugins.css +75 -0
  45. data/lib/kibana/assets/app/panels/bettermap/leaflet/plugins.js +16 -0
  46. data/lib/kibana/assets/app/panels/bettermap/module.css +4 -0
  47. data/lib/kibana/assets/app/panels/bettermap/module.html +6 -0
  48. data/lib/kibana/assets/app/panels/bettermap/module.js +232 -0
  49. data/lib/kibana/assets/app/panels/column/editor.html +36 -0
  50. data/lib/kibana/assets/app/panels/column/module.html +16 -0
  51. data/lib/kibana/assets/app/panels/column/module.js +105 -0
  52. data/lib/kibana/assets/app/panels/column/panelgeneral.html +11 -0
  53. data/lib/kibana/assets/app/panels/dashcontrol/editor.html +44 -0
  54. data/lib/kibana/assets/app/panels/dashcontrol/load.html +40 -0
  55. data/lib/kibana/assets/app/panels/dashcontrol/module.html +6 -0
  56. data/lib/kibana/assets/app/panels/dashcontrol/module.js +198 -0
  57. data/lib/kibana/assets/app/panels/dashcontrol/save.html +30 -0
  58. data/lib/kibana/assets/app/panels/dashcontrol/share.html +11 -0
  59. data/lib/kibana/assets/app/panels/derivequeries/editor.html +23 -0
  60. data/lib/kibana/assets/app/panels/derivequeries/module.html +33 -0
  61. data/lib/kibana/assets/app/panels/derivequeries/module.js +160 -0
  62. data/lib/kibana/assets/app/panels/fields/editor.html +10 -0
  63. data/lib/kibana/assets/app/panels/fields/micropanel.html +25 -0
  64. data/lib/kibana/assets/app/panels/fields/module.html +3 -0
  65. data/lib/kibana/assets/app/panels/fields/module.js +37 -0
  66. data/lib/kibana/assets/app/panels/filtering/editor.html +7 -0
  67. data/lib/kibana/assets/app/panels/filtering/meta.html +15 -0
  68. data/lib/kibana/assets/app/panels/filtering/module.html +78 -0
  69. data/lib/kibana/assets/app/panels/filtering/module.js +66 -0
  70. data/lib/kibana/assets/app/panels/histogram/editor.html +74 -0
  71. data/lib/kibana/assets/app/panels/histogram/interval.js +57 -0
  72. data/lib/kibana/assets/app/panels/histogram/module.html +91 -0
  73. data/lib/kibana/assets/app/panels/histogram/module.js +511 -0
  74. data/lib/kibana/assets/app/panels/histogram/timeSeries.js +179 -0
  75. data/lib/kibana/assets/app/panels/hits/editor.html +29 -0
  76. data/lib/kibana/assets/app/panels/hits/module.html +44 -0
  77. data/lib/kibana/assets/app/panels/hits/module.js +270 -0
  78. data/lib/kibana/assets/app/panels/map/editor.html +15 -0
  79. data/lib/kibana/assets/app/panels/map/lib/jquery.jvectormap.min.js +8 -0
  80. data/lib/kibana/assets/app/panels/map/lib/map.europe.js +1 -0
  81. data/lib/kibana/assets/app/panels/map/lib/map.usa.js +1 -0
  82. data/lib/kibana/assets/app/panels/map/lib/map.world.js +1 -0
  83. data/lib/kibana/assets/app/panels/map/module.html +63 -0
  84. data/lib/kibana/assets/app/panels/map/module.js +185 -0
  85. data/lib/kibana/assets/app/panels/pie/editor.html +49 -0
  86. data/lib/kibana/assets/app/panels/pie/module.html +12 -0
  87. data/lib/kibana/assets/app/panels/pie/module.js +297 -0
  88. data/lib/kibana/assets/app/panels/query/editor.html +7 -0
  89. data/lib/kibana/assets/app/panels/query/meta.html +21 -0
  90. data/lib/kibana/assets/app/panels/query/module.html +25 -0
  91. data/lib/kibana/assets/app/panels/query/module.js +69 -0
  92. data/lib/kibana/assets/app/panels/query/query.css +39 -0
  93. data/lib/kibana/assets/app/panels/table/editor.html +48 -0
  94. data/lib/kibana/assets/app/panels/table/micropanel.html +44 -0
  95. data/lib/kibana/assets/app/panels/table/module.html +104 -0
  96. data/lib/kibana/assets/app/panels/table/module.js +389 -0
  97. data/lib/kibana/assets/app/panels/table/pagination.html +27 -0
  98. data/lib/kibana/assets/app/panels/terms/editor.html +51 -0
  99. data/lib/kibana/assets/app/panels/terms/module.html +55 -0
  100. data/lib/kibana/assets/app/panels/terms/module.js +307 -0
  101. data/lib/kibana/assets/app/panels/text/editor.html +16 -0
  102. data/lib/kibana/assets/app/panels/text/lib/showdown.js +1454 -0
  103. data/lib/kibana/assets/app/panels/text/module.html +10 -0
  104. data/lib/kibana/assets/app/panels/text/module.js +85 -0
  105. data/lib/kibana/assets/app/panels/timepicker/editor.html +34 -0
  106. data/lib/kibana/assets/app/panels/timepicker/module.html +73 -0
  107. data/lib/kibana/assets/app/panels/timepicker/module.js +268 -0
  108. data/lib/kibana/assets/app/panels/timepicker/refreshctrl.html +5 -0
  109. data/lib/kibana/assets/app/panels/trends/editor.html +20 -0
  110. data/lib/kibana/assets/app/panels/trends/module.html +11 -0
  111. data/lib/kibana/assets/app/panels/trends/module.js +232 -0
  112. data/lib/kibana/assets/app/partials/dashLoader.html +78 -0
  113. data/lib/kibana/assets/app/partials/dashLoaderShare.html +11 -0
  114. data/lib/kibana/assets/app/partials/dashboard.html +77 -0
  115. data/lib/kibana/assets/app/partials/dasheditor.html +151 -0
  116. data/lib/kibana/assets/app/partials/inspector.html +15 -0
  117. data/lib/kibana/assets/app/partials/load.html +4 -0
  118. data/lib/kibana/assets/app/partials/modal.html +12 -0
  119. data/lib/kibana/assets/app/partials/paneladd.html +6 -0
  120. data/lib/kibana/assets/app/partials/paneleditor.html +23 -0
  121. data/lib/kibana/assets/app/partials/panelgeneral.html +22 -0
  122. data/lib/kibana/assets/app/partials/querySelect.html +24 -0
  123. data/lib/kibana/assets/app/partials/roweditor.html +65 -0
  124. data/lib/kibana/assets/app/services/alertSrv.js +49 -0
  125. data/lib/kibana/assets/app/services/all.js +11 -0
  126. data/lib/kibana/assets/app/services/dashboard.js +417 -0
  127. data/lib/kibana/assets/app/services/fields.js +96 -0
  128. data/lib/kibana/assets/app/services/filterSrv.js +200 -0
  129. data/lib/kibana/assets/app/services/kbnIndex.js +101 -0
  130. data/lib/kibana/assets/app/services/panelMove.js +83 -0
  131. data/lib/kibana/assets/app/services/querySrv.js +147 -0
  132. data/lib/kibana/assets/app/services/timer.js +34 -0
  133. data/lib/kibana/assets/css/animate.min.css +3270 -0
  134. data/lib/kibana/assets/css/bootstrap-responsive.min.css +9 -0
  135. data/lib/kibana/assets/css/bootstrap.dark.min.css +9 -0
  136. data/lib/kibana/assets/css/bootstrap.light.min.css +9 -0
  137. data/lib/kibana/assets/css/font-awesome.min.css +403 -0
  138. data/lib/kibana/assets/css/main.css +193 -0
  139. data/lib/kibana/assets/css/normalize.min.css +1 -0
  140. data/lib/kibana/assets/css/timepicker.css +423 -0
  141. data/lib/kibana/assets/font/FontAwesome.otf +0 -0
  142. data/lib/kibana/assets/font/fontawesome-webfont.eot +0 -0
  143. data/lib/kibana/assets/font/fontawesome-webfont.svg +399 -0
  144. data/lib/kibana/assets/font/fontawesome-webfont.ttf +0 -0
  145. data/lib/kibana/assets/font/fontawesome-webfont.woff +0 -0
  146. data/lib/kibana/assets/img/glyphicons-halflings-white.png +0 -0
  147. data/lib/kibana/assets/img/glyphicons-halflings.png +0 -0
  148. data/lib/kibana/assets/img/kibana.png +0 -0
  149. data/lib/kibana/assets/img/load.gif +0 -0
  150. data/lib/kibana/assets/img/load_big.gif +0 -0
  151. data/lib/kibana/assets/index.html +49 -0
  152. data/lib/kibana/assets/vendor/angular/angular-dragdrop.js +304 -0
  153. data/lib/kibana/assets/vendor/angular/angular-sanitize.js +556 -0
  154. data/lib/kibana/assets/vendor/angular/angular-strap.js +875 -0
  155. data/lib/kibana/assets/vendor/angular/angular.js +15158 -0
  156. data/lib/kibana/assets/vendor/angular/datepicker.js +1046 -0
  157. data/lib/kibana/assets/vendor/angular/timepicker.js +888 -0
  158. data/lib/kibana/assets/vendor/bootstrap/bootstrap.js +2280 -0
  159. data/lib/kibana/assets/vendor/bootstrap/less/accordion.less +34 -0
  160. data/lib/kibana/assets/vendor/bootstrap/less/alerts.less +79 -0
  161. data/lib/kibana/assets/vendor/bootstrap/less/bootstrap.dark.less +4 -0
  162. data/lib/kibana/assets/vendor/bootstrap/less/bootstrap.less +63 -0
  163. data/lib/kibana/assets/vendor/bootstrap/less/bootstrap.light.less +4 -0
  164. data/lib/kibana/assets/vendor/bootstrap/less/bootswatch.dark.less +554 -0
  165. data/lib/kibana/assets/vendor/bootstrap/less/bootswatch.light.less +9 -0
  166. data/lib/kibana/assets/vendor/bootstrap/less/breadcrumbs.less +24 -0
  167. data/lib/kibana/assets/vendor/bootstrap/less/button-groups.less +229 -0
  168. data/lib/kibana/assets/vendor/bootstrap/less/buttons.less +228 -0
  169. data/lib/kibana/assets/vendor/bootstrap/less/carousel.less +158 -0
  170. data/lib/kibana/assets/vendor/bootstrap/less/close.less +32 -0
  171. data/lib/kibana/assets/vendor/bootstrap/less/code.less +61 -0
  172. data/lib/kibana/assets/vendor/bootstrap/less/component-animations.less +22 -0
  173. data/lib/kibana/assets/vendor/bootstrap/less/dropdowns.less +248 -0
  174. data/lib/kibana/assets/vendor/bootstrap/less/forms.less +690 -0
  175. data/lib/kibana/assets/vendor/bootstrap/less/grid.less +21 -0
  176. data/lib/kibana/assets/vendor/bootstrap/less/hero-unit.less +25 -0
  177. data/lib/kibana/assets/vendor/bootstrap/less/labels-badges.less +84 -0
  178. data/lib/kibana/assets/vendor/bootstrap/less/layouts.less +16 -0
  179. data/lib/kibana/assets/vendor/bootstrap/less/media.less +55 -0
  180. data/lib/kibana/assets/vendor/bootstrap/less/mixins.less +702 -0
  181. data/lib/kibana/assets/vendor/bootstrap/less/modals.less +95 -0
  182. data/lib/kibana/assets/vendor/bootstrap/less/navbar.less +497 -0
  183. data/lib/kibana/assets/vendor/bootstrap/less/navs.less +409 -0
  184. data/lib/kibana/assets/vendor/bootstrap/less/overrides.less +237 -0
  185. data/lib/kibana/assets/vendor/bootstrap/less/pager.less +43 -0
  186. data/lib/kibana/assets/vendor/bootstrap/less/pagination.less +123 -0
  187. data/lib/kibana/assets/vendor/bootstrap/less/popovers.less +133 -0
  188. data/lib/kibana/assets/vendor/bootstrap/less/progress-bars.less +122 -0
  189. data/lib/kibana/assets/vendor/bootstrap/less/reset.less +216 -0
  190. data/lib/kibana/assets/vendor/bootstrap/less/responsive-1200px-min.less +28 -0
  191. data/lib/kibana/assets/vendor/bootstrap/less/responsive-767px-max.less +193 -0
  192. data/lib/kibana/assets/vendor/bootstrap/less/responsive-768px-979px.less +19 -0
  193. data/lib/kibana/assets/vendor/bootstrap/less/responsive-navbar.less +189 -0
  194. data/lib/kibana/assets/vendor/bootstrap/less/responsive-utilities.less +59 -0
  195. data/lib/kibana/assets/vendor/bootstrap/less/responsive.less +48 -0
  196. data/lib/kibana/assets/vendor/bootstrap/less/scaffolding.less +53 -0
  197. data/lib/kibana/assets/vendor/bootstrap/less/sprites.less +197 -0
  198. data/lib/kibana/assets/vendor/bootstrap/less/tables.less +244 -0
  199. data/lib/kibana/assets/vendor/bootstrap/less/tests/buttons.html +139 -0
  200. data/lib/kibana/assets/vendor/bootstrap/less/tests/css-tests.css +150 -0
  201. data/lib/kibana/assets/vendor/bootstrap/less/tests/css-tests.html +1399 -0
  202. data/lib/kibana/assets/vendor/bootstrap/less/tests/forms-responsive.html +71 -0
  203. data/lib/kibana/assets/vendor/bootstrap/less/tests/forms.html +179 -0
  204. data/lib/kibana/assets/vendor/bootstrap/less/tests/navbar-fixed-top.html +104 -0
  205. data/lib/kibana/assets/vendor/bootstrap/less/tests/navbar-static-top.html +107 -0
  206. data/lib/kibana/assets/vendor/bootstrap/less/tests/navbar.html +107 -0
  207. data/lib/kibana/assets/vendor/bootstrap/less/thumbnails.less +53 -0
  208. data/lib/kibana/assets/vendor/bootstrap/less/tooltip.less +70 -0
  209. data/lib/kibana/assets/vendor/bootstrap/less/type.less +247 -0
  210. data/lib/kibana/assets/vendor/bootstrap/less/utilities.less +30 -0
  211. data/lib/kibana/assets/vendor/bootstrap/less/variables.dark.less +304 -0
  212. data/lib/kibana/assets/vendor/bootstrap/less/variables.less +301 -0
  213. data/lib/kibana/assets/vendor/bootstrap/less/variables.light.less +301 -0
  214. data/lib/kibana/assets/vendor/bootstrap/less/wells.less +29 -0
  215. data/lib/kibana/assets/vendor/elasticjs/elastic-angular-client.js +81 -0
  216. data/lib/kibana/assets/vendor/elasticjs/elastic.js +19993 -0
  217. data/lib/kibana/assets/vendor/filesaver.js +216 -0
  218. data/lib/kibana/assets/vendor/jquery/jquery-1.8.0.js +2 -0
  219. data/lib/kibana/assets/vendor/jquery/jquery-ui-1.10.3.js +5253 -0
  220. data/lib/kibana/assets/vendor/jquery/jquery.flot.js +3060 -0
  221. data/lib/kibana/assets/vendor/jquery/jquery.flot.pie.js +817 -0
  222. data/lib/kibana/assets/vendor/jquery/jquery.flot.selection.js +360 -0
  223. data/lib/kibana/assets/vendor/jquery/jquery.flot.stack.js +188 -0
  224. data/lib/kibana/assets/vendor/jquery/jquery.flot.stackpercent.js +126 -0
  225. data/lib/kibana/assets/vendor/jquery/jquery.flot.time.js +431 -0
  226. data/lib/kibana/assets/vendor/modernizr-2.6.1.js +4 -0
  227. data/lib/kibana/assets/vendor/moment.js +1662 -0
  228. data/lib/kibana/assets/vendor/require/css-build.js +78 -0
  229. data/lib/kibana/assets/vendor/require/css.js +23 -0
  230. data/lib/kibana/assets/vendor/require/require.js +2024 -0
  231. data/lib/kibana/assets/vendor/require/text.js +386 -0
  232. data/lib/kibana/assets/vendor/require/tmpl.js +17 -0
  233. data/lib/kibana/assets/vendor/timezone.js +993 -0
  234. data/lib/kibana/assets/vendor/underscore.js +1246 -0
  235. data/lib/kibana/sinatra.rb +3 -0
  236. data/lib/kibana/sinatra/version.rb +5 -0
  237. data/lib/kibana/sinatra/web.rb +28 -0
  238. data/lib/kibana/views/config.erb +54 -0
  239. metadata +325 -0
@@ -0,0 +1,74 @@
1
+ <div class="row-fluid">
2
+ <div class="span2">
3
+ <label class="small">Mode</label>
4
+ <select ng-change="set_refresh(true)" class="input-small" ng-model="panel.mode" ng-options="f for f in ['count','min','mean','max','total']"></select>
5
+ </div>
6
+ <div class="span2">
7
+ <label class="small">Time Field</label>
8
+ <input ng-change="set_refresh(true)" placeholder="Start typing" bs-typeahead="fields.list" type="text" class="input-small" ng-model="panel.time_field">
9
+ </div>
10
+ <div class="span2" ng-show="panel.mode != 'count'">
11
+ <label class="small">Value Field</label>
12
+ <input ng-change="set_refresh(true)" placeholder="Start typing" bs-typeahead="fields.list" type="text" class="input-small" ng-model="panel.value_field">
13
+ </div>
14
+ <div class="span3" ng-show="panel.mode != 'count'">
15
+ <label class="small">Note</label><small> In <strong>{{panel.mode}}</strong> mode the configured field <strong>must</strong> be a numeric type</small>
16
+ </div>
17
+ </div>
18
+ <h5>Chart Settings</h5>
19
+ <div class="row-fluid" style="text-align:center;margin-bottom:10px;">
20
+ <div class="span1"> <label class="small">Bars</label><input type="checkbox" ng-model="panel.bars" ng-checked="panel.bars"></div>
21
+ <div class="span1"> <label class="small">Lines</label><input type="checkbox" ng-model="panel.lines" ng-checked="panel.lines"></div>
22
+ <div class="span1"> <label class="small">Points</label><input type="checkbox" ng-model="panel.points" ng-checked="panel.points"></div>
23
+ <div class="span1"> <label class="small">Stack</label><input type="checkbox" ng-model="panel.stack" ng-checked="panel.stack"></div>
24
+ <div class="span1" ng-show="panel.stack">
25
+ <label style="white-space:nowrap" class="small">Percent <tip>Stack as a percentage of total</tip></label>
26
+ <input type="checkbox" ng-model="panel.percentage" ng-checked="panel.percentage">
27
+ </div>
28
+ <div class="span1"> <label class="small">Legend</label><input type="checkbox" ng-model="panel.legend" ng-checked="panel.legend"></div>
29
+ <div class="span1"> <label class="small">xAxis</label><input type="checkbox" ng-model="panel['x-axis']" ng-checked="panel['x-axis']"></div>
30
+ <div class="span1"> <label class="small">yAxis</label><input type="checkbox" ng-model="panel['y-axis']" ng-checked="panel['y-axis']"></div>
31
+ <div class="span2" ng-show="panel.lines">
32
+ <label class="small">Line Fill</label>
33
+ <select 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>
34
+ </div>
35
+ <div class="span2" ng-show="panel.lines">
36
+ <label class="small">Line Width</label>
37
+ <select 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>
38
+ </div>
39
+ </div>
40
+ <div class="row-fluid">
41
+ <div class="span2">
42
+ <label class="small">Time correction</label>
43
+ <select ng-model="panel.timezone" class='input-small' ng-options="f for f in ['browser','utc']"></select>
44
+ </div>
45
+ <div class="span1"> <label class="small">Selectable</label><input type="checkbox" ng-model="panel.interactive" ng-checked="panel.interactive"></div>
46
+ <div class="span2">
47
+ <label class="small">Zoom Links</label><input type="checkbox" ng-model="panel.zoomlinks" ng-checked="panel.zoomlinks" />
48
+ </div>
49
+ <div class="span2">
50
+ <label class="small">View Options</label><input type="checkbox" ng-model="panel.options" ng-checked="panel.options" />
51
+ </div>
52
+ <div class="span2">
53
+ <label class="small">Auto-interval</label><input type="checkbox" ng-model="panel.auto_int" ng-checked="panel.auto_int" />
54
+ </div>
55
+ <div class="span2" ng-show='panel.auto_int'>
56
+ <label class="small">Resolution <tip>Shoot for this many data points, rounding to sane intervals</tip></label>
57
+ <input type="number" class='input-mini' ng-model="panel.resolution" ng-change='set_refresh(true)'/>
58
+ </div>
59
+ <div class="span2" ng-hide='panel.auto_int'>
60
+ <label class="small">Interval <tip>Use Elasticsearch date math format (eg 1m, 5m, 1d, 2w, 1y)</tip></label>
61
+ <input type="text" class='input-mini' ng-model="panel.interval" ng-change='set_refresh(true)'/>
62
+ </div>
63
+ </div>
64
+ <h5>Tooltip Settings</h5>
65
+ <div class="row-fluid" style="margin-bottom:10px;">
66
+ <div class="span3">
67
+ <label class="small">Stacked Values <tip>How should the values in stacked charts to be calculated?</tip></label>
68
+ <select class="input-medium" ng-model="panel.tooltip.value_type" ng-options="f for f in ['cumulative','individual']"></select>
69
+ </div>
70
+ <div class="span3">
71
+ <label class="small">Display Query <tip>If an alias is set, it will be shown in the tooltip. If not, should it show the query?</tip></label>
72
+ <input type="checkbox" ng-model="panel.tooltip.query_as_alias" />
73
+ </div>
74
+ </div>
@@ -0,0 +1,57 @@
1
+ define([
2
+ 'kbn'
3
+ ],
4
+ function (kbn) {
5
+ 'use strict';
6
+
7
+ /**
8
+ * manages the interval logic
9
+ * @param {[type]} interval_string An interval string in the format '1m', '1y', etc
10
+ */
11
+ function Interval(interval_string) {
12
+ this.string = interval_string;
13
+
14
+ var info = kbn.describe_interval(interval_string);
15
+ this.type = info.type;
16
+ this.ms = info.sec * 1000 * info.count;
17
+
18
+ // does the length of the interval change based on the current time?
19
+ if (this.type === 'y' || this.type === 'M') {
20
+ // we will just modify this time object rather that create a new one constantly
21
+ this.get = this.get_complex;
22
+ this.date = new Date(0);
23
+ } else {
24
+ this.get = this.get_simple;
25
+ }
26
+ }
27
+
28
+ Interval.prototype = {
29
+ toString: function () {
30
+ return this.string;
31
+ },
32
+ after: function(current_ms) {
33
+ return this.get(current_ms, 1);
34
+ },
35
+ before: function (current_ms) {
36
+ return this.get(current_ms, -1);
37
+ },
38
+ get_complex: function (current, delta) {
39
+ this.date.setTime(current);
40
+ switch(this.type) {
41
+ case 'M':
42
+ this.date.setUTCMonth(this.date.getUTCMonth() + delta);
43
+ break;
44
+ case 'y':
45
+ this.date.setUTCFullYear(this.date.getUTCFullYear() + delta);
46
+ break;
47
+ }
48
+ return this.date.getTime();
49
+ },
50
+ get_simple: function (current, delta) {
51
+ return current + (delta * this.ms);
52
+ }
53
+ };
54
+
55
+ return Interval;
56
+
57
+ });
@@ -0,0 +1,91 @@
1
+ <div ng-controller='histogram' ng-init="init()" style="min-height:{{panel.height || row.height}}">
2
+ <style>
3
+ .histogram-legend {
4
+ display:inline-block;
5
+ padding-right:5px
6
+ }
7
+ .histogram-legend-dot {
8
+ display:inline-block;
9
+ height:10px;
10
+ width:10px;
11
+ border-radius:5px;
12
+ }
13
+ .histogram-legend-item {
14
+ display:inline-block;
15
+ }
16
+ .histogram-chart {
17
+ position:relative;
18
+ }
19
+ .histogram-options {
20
+ padding: 5px;
21
+ margin-right: 15px;
22
+ margin-bottom: 0px;
23
+ }
24
+ .histogram-options label {
25
+ margin: 0px 0px 0px 10px !important;
26
+ }
27
+ .histogram-options span {
28
+ white-space: nowrap;
29
+ }
30
+
31
+ /* this is actually should be in bootstrap */
32
+ .form-inline .checkbox {
33
+ display: inline-block;
34
+ }
35
+ </style>
36
+ <div>
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
40
+ </a> |&nbsp
41
+ </span>
42
+ <span ng-show='panel.zoomlinks && data'>
43
+ <!--<a class='small' ng-click='zoom(0.5)'><i class='icon-zoom-in'></i> Zoom In</a>-->
44
+ <a class='small' ng-click='zoom(2)'><i class='icon-zoom-out'></i> Zoom Out</a> |&nbsp
45
+ </span>
46
+ <span ng-show="panel.legend" ng-repeat='series in data' class="histogram-legend">
47
+ <i class='icon-circle' ng-style="{color: series.info.color}"></i>
48
+ <span class='small histogram-legend-item'>{{series.info.alias}} ({{series.hits}})</span>
49
+ </span>
50
+ <span ng-show="panel.legend" class="small"><span ng-show="panel.value_field && panel.mode != 'count'">{{panel.value_field}}</span> {{panel.mode}} per <strong>{{panel.interval}}</strong> | (<strong>{{hits}}</strong> hits)</span>
51
+ </div>
52
+ <form class="form-inline bordered histogram-options" ng-show="options">
53
+ <div class="checkbox">
54
+ <label class="small">
55
+ <input type="checkbox" ng-model="panel.bars" ng-checked="panel.bars" ng-change="render()">
56
+ Bars
57
+ </label>
58
+ </div>
59
+ <div class="checkbox">
60
+ <label class="small">
61
+ <input type="checkbox" ng-model="panel.lines" ng-checked="panel.lines" ng-change="render()">
62
+ Lines
63
+ </label>
64
+ </div>
65
+ <div class="checkbox">
66
+ <label class="small">
67
+ <input type="checkbox" ng-model="panel.points" ng-checked="panel.points" ng-change="render()">
68
+ Points
69
+ </label>
70
+ </div>
71
+ <div class="checkbox">
72
+ <label class="small">
73
+ <input type="checkbox" ng-model="panel.stack" ng-checked="panel.stack" ng-change="render()">
74
+ Stack
75
+ </label>
76
+ </div>
77
+ <span ng-show="panel.stack">
78
+ <div class="checkbox">
79
+ <label style="white-space:nowrap" class="small">
80
+ <input type="checkbox" ng-model="panel.percentage" ng-checked="panel.percentage" ng-change="render()">
81
+ Percent
82
+ </label>
83
+ </div>
84
+ </span>
85
+ <span>
86
+ <label class="small">Interval</label> <select ng-change="set_interval(panel.interval);get_data();" class="input-small" ng-model="panel.interval" ng-options="interval_label(time) for time in _.union([panel.interval],panel.intervals)"></select>
87
+ </span>
88
+ </form>
89
+ <center><img ng-show='panel.loading && _.isUndefined(data)' src="img/load_big.gif"></center>
90
+ <div histogram-chart class="pointer histogram-chart" params="{{panel}}"></div>
91
+ </div>
@@ -0,0 +1,511 @@
1
+ /*
2
+
3
+ ## Histogram
4
+
5
+ ### Parameters
6
+ * auto_int :: Auto calculate data point interval?
7
+ * resolution :: If auto_int is enables, shoot for this many data points, rounding to
8
+ sane intervals
9
+ * interval :: Datapoint interval in elasticsearch date math format (eg 1d, 1w, 1y, 5y)
10
+ * fill :: Only applies to line charts. Level of area shading from 0-10
11
+ * linewidth :: Only applies to line charts. How thick the line should be in pixels
12
+ While the editor only exposes 0-10, this can be any numeric value.
13
+ Set to 0 and you'll get something like a scatter plot
14
+ * timezone :: This isn't totally functional yet. Currently only supports browser and utc.
15
+ browser will adjust the x-axis labels to match the timezone of the user's
16
+ browser
17
+ * spyable :: Dislay the 'eye' icon that show the last elasticsearch query
18
+ * zoomlinks :: Show the zoom links?
19
+ * bars :: Show bars in the chart
20
+ * stack :: Stack multiple queries. This generally a crappy way to represent things.
21
+ You probably should just use a line chart without stacking
22
+ * points :: Should circles at the data points on the chart
23
+ * lines :: Line chart? Sweet.
24
+ * legend :: Show the legend?
25
+ * x-axis :: Show x-axis labels and grid lines
26
+ * y-axis :: Show y-axis labels and grid lines
27
+ * interactive :: Allow drag to select time range
28
+
29
+ */
30
+ define([
31
+ 'angular',
32
+ 'app',
33
+ 'jquery',
34
+ 'underscore',
35
+ 'kbn',
36
+ 'moment',
37
+ './timeSeries',
38
+
39
+ 'jquery.flot',
40
+ 'jquery.flot.pie',
41
+ 'jquery.flot.selection',
42
+ 'jquery.flot.time',
43
+ 'jquery.flot.stack',
44
+ 'jquery.flot.stackpercent'
45
+ ],
46
+ function (angular, app, $, _, kbn, moment, timeSeries) {
47
+
48
+ 'use strict';
49
+
50
+ var module = angular.module('kibana.panels.histogram', []);
51
+ app.useModule(module);
52
+
53
+ module.controller('histogram', function($scope, querySrv, dashboard, filterSrv) {
54
+ $scope.panelMeta = {
55
+ modals : [
56
+ {
57
+ description: "Inspect",
58
+ icon: "icon-info-sign",
59
+ partial: "app/partials/inspector.html",
60
+ show: $scope.panel.spyable
61
+ }
62
+ ],
63
+ editorTabs : [
64
+ {
65
+ title:'Queries',
66
+ src:'app/partials/querySelect.html'
67
+ }
68
+ ],
69
+ status : "Stable",
70
+ description : "A bucketed time series chart of the current query or queries. Uses the "+
71
+ "Elasticsearch date_histogram facet. If using time stamped indices this panel will query"+
72
+ " them sequentially to attempt to apply the lighest possible load to your Elasticsearch cluster"
73
+ };
74
+
75
+ // Set and populate defaults
76
+ var _d = {
77
+ mode : 'count',
78
+ time_field : '@timestamp',
79
+ queries : {
80
+ mode : 'all',
81
+ ids : []
82
+ },
83
+ value_field : null,
84
+ auto_int : true,
85
+ resolution : 100,
86
+ interval : '5m',
87
+ intervals : ['auto','1s','1m','5m','10m','30m','1h','3h','12h','1d','1w','1M','1y'],
88
+ fill : 0,
89
+ linewidth : 3,
90
+ timezone : 'browser', // browser, utc or a standard timezone
91
+ spyable : true,
92
+ zoomlinks : true,
93
+ bars : true,
94
+ stack : true,
95
+ points : false,
96
+ lines : false,
97
+ legend : true,
98
+ 'x-axis' : true,
99
+ 'y-axis' : true,
100
+ percentage : false,
101
+ interactive : true,
102
+ options : true,
103
+ tooltip : {
104
+ value_type: 'cumulative',
105
+ query_as_alias: false
106
+ }
107
+ };
108
+
109
+ _.defaults($scope.panel,_d);
110
+
111
+ $scope.init = function() {
112
+ // Hide view options by default
113
+ $scope.options = false;
114
+ $scope.$on('refresh',function(){
115
+ $scope.get_data();
116
+ });
117
+
118
+ $scope.get_data();
119
+
120
+ };
121
+
122
+ $scope.set_interval = function(interval) {
123
+ if(interval !== 'auto') {
124
+ $scope.panel.auto_int = false;
125
+ $scope.panel.interval = interval;
126
+ } else {
127
+ $scope.panel.auto_int = true;
128
+ }
129
+ };
130
+
131
+ $scope.interval_label = function(interval) {
132
+ return $scope.panel.auto_int && interval === $scope.panel.interval ? interval+" (auto)" : interval;
133
+ };
134
+
135
+ /**
136
+ * The time range effecting the panel
137
+ * @return {[type]} [description]
138
+ */
139
+ $scope.get_time_range = function () {
140
+ var range = $scope.range = filterSrv.timeRange('min');
141
+ return range;
142
+ };
143
+
144
+ $scope.get_interval = function () {
145
+ var interval = $scope.panel.interval,
146
+ range;
147
+ if ($scope.panel.auto_int) {
148
+ range = $scope.get_time_range();
149
+ if (range) {
150
+ interval = kbn.secondsToHms(
151
+ kbn.calculate_interval(range.from, range.to, $scope.panel.resolution, 0) / 1000
152
+ );
153
+ }
154
+ }
155
+ $scope.panel.interval = interval || '10m';
156
+ return $scope.panel.interval;
157
+ };
158
+
159
+ /**
160
+ * Fetch the data for a chunk of a queries results. Multiple segments occur when several indicies
161
+ * need to be consulted (like timestamped logstash indicies)
162
+ *
163
+ * The results of this function are stored on the scope's data property. This property will be an
164
+ * array of objects with the properties info, time_series, and hits. These objects are used in the
165
+ * render_panel function to create the historgram.
166
+ *
167
+ * @param {number} segment The segment count, (0 based)
168
+ * @param {number} query_id The id of the query, generated on the first run and passed back when
169
+ * this call is made recursively for more segments
170
+ */
171
+ $scope.get_data = function(segment, query_id) {
172
+ if (_.isUndefined(segment)) {
173
+ segment = 0;
174
+ }
175
+ delete $scope.panel.error;
176
+
177
+ // Make sure we have everything for the request to complete
178
+ if(dashboard.indices.length === 0) {
179
+ return;
180
+ }
181
+ var _range = $scope.get_time_range();
182
+ var _interval = $scope.get_interval(_range);
183
+
184
+ if ($scope.panel.auto_int) {
185
+ $scope.panel.interval = kbn.secondsToHms(
186
+ kbn.calculate_interval(_range.from,_range.to,$scope.panel.resolution,0)/1000);
187
+ }
188
+
189
+ $scope.panelMeta.loading = true;
190
+ var request = $scope.ejs.Request().indices(dashboard.indices[segment]);
191
+
192
+ $scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
193
+ // Build the query
194
+ _.each($scope.panel.queries.ids, function(id) {
195
+ var query = $scope.ejs.FilteredQuery(
196
+ querySrv.getEjsObj(id),
197
+ filterSrv.getBoolFilter(filterSrv.ids)
198
+ );
199
+
200
+ var facet = $scope.ejs.DateHistogramFacet(id);
201
+
202
+ if($scope.panel.mode === 'count') {
203
+ facet = facet.field($scope.panel.time_field);
204
+ } else {
205
+ if(_.isNull($scope.panel.value_field)) {
206
+ $scope.panel.error = "In " + $scope.panel.mode + " mode a field must be specified";
207
+ return;
208
+ }
209
+ facet = facet.keyField($scope.panel.time_field).valueField($scope.panel.value_field);
210
+ }
211
+ facet = facet.interval(_interval).facetFilter($scope.ejs.QueryFilter(query));
212
+ request = request.facet(facet).size(0);
213
+ });
214
+
215
+ // Populate the inspector panel
216
+ $scope.populate_modal(request);
217
+
218
+ // Then run it
219
+ var results = request.doSearch();
220
+
221
+ // Populate scope when we have results
222
+ results.then(function(results) {
223
+ $scope.panelMeta.loading = false;
224
+ if(segment === 0) {
225
+ $scope.hits = 0;
226
+ $scope.data = [];
227
+ query_id = $scope.query_id = new Date().getTime();
228
+ }
229
+
230
+ // Check for error and abort if found
231
+ if(!(_.isUndefined(results.error))) {
232
+ $scope.panel.error = $scope.parse_error(results.error);
233
+ return;
234
+ }
235
+
236
+ // Convert facet ids to numbers
237
+ var facetIds = _.map(_.keys(results.facets),function(k){return parseInt(k, 10);});
238
+
239
+ // Make sure we're still on the same query/queries
240
+ if($scope.query_id === query_id && _.difference(facetIds, $scope.panel.queries.ids).length === 0) {
241
+
242
+ var i = 0,
243
+ time_series,
244
+ hits;
245
+
246
+ _.each($scope.panel.queries.ids, function(id) {
247
+ var query_results = results.facets[id];
248
+ // we need to initialize the data variable on the first run,
249
+ // and when we are working on the first segment of the data.
250
+ if(_.isUndefined($scope.data[i]) || segment === 0) {
251
+ time_series = new timeSeries.ZeroFilled({
252
+ interval: _interval,
253
+ start_date: _range && _range.from,
254
+ end_date: _range && _range.to,
255
+ fill_style: 'minimal'
256
+ });
257
+ hits = 0;
258
+ } else {
259
+ time_series = $scope.data[i].time_series;
260
+ hits = $scope.data[i].hits;
261
+ }
262
+
263
+ // push each entry into the time series, while incrementing counters
264
+ _.each(query_results.entries, function(entry) {
265
+ time_series.addValue(entry.time, entry[$scope.panel.mode]);
266
+ hits += entry.count; // The series level hits counter
267
+ $scope.hits += entry.count; // Entire dataset level hits counter
268
+ });
269
+ $scope.data[i] = {
270
+ info: querySrv.list[id],
271
+ time_series: time_series,
272
+ hits: hits
273
+ };
274
+
275
+ i++;
276
+ });
277
+
278
+ // Tell the histogram directive to render.
279
+ $scope.$emit('render');
280
+
281
+ // If we still have segments left, get them
282
+ if(segment < dashboard.indices.length-1) {
283
+ $scope.get_data(segment+1,query_id);
284
+ }
285
+ }
286
+ });
287
+ };
288
+
289
+ // function $scope.zoom
290
+ // factor :: Zoom factor, so 0.5 = cuts timespan in half, 2 doubles timespan
291
+ $scope.zoom = function(factor) {
292
+ var _range = filterSrv.timeRange('min');
293
+ var _timespan = (_range.to.valueOf() - _range.from.valueOf());
294
+ var _center = _range.to.valueOf() - _timespan/2;
295
+
296
+ var _to = (_center + (_timespan*factor)/2);
297
+ var _from = (_center - (_timespan*factor)/2);
298
+
299
+ // If we're not already looking into the future, don't.
300
+ if(_to > Date.now() && _range.to < Date.now()) {
301
+ var _offset = _to - Date.now();
302
+ _from = _from - _offset;
303
+ _to = Date.now();
304
+ }
305
+
306
+ if(factor > 1) {
307
+ filterSrv.removeByType('time');
308
+ }
309
+ filterSrv.set({
310
+ type:'time',
311
+ from:moment.utc(_from),
312
+ to:moment.utc(_to),
313
+ field:$scope.panel.time_field
314
+ });
315
+
316
+ dashboard.refresh();
317
+
318
+ };
319
+
320
+ // I really don't like this function, too much dom manip. Break out into directive?
321
+ $scope.populate_modal = function(request) {
322
+ $scope.inspector = angular.toJson(JSON.parse(request.toString()),true);
323
+ };
324
+
325
+ $scope.set_refresh = function (state) {
326
+ $scope.refresh = state;
327
+ };
328
+
329
+ $scope.close_edit = function() {
330
+ if($scope.refresh) {
331
+ $scope.get_data();
332
+ }
333
+ $scope.refresh = false;
334
+ $scope.$emit('render');
335
+ };
336
+
337
+ $scope.render = function() {
338
+ $scope.$emit('render');
339
+ };
340
+
341
+ });
342
+
343
+ module.directive('histogramChart', function(dashboard, filterSrv) {
344
+ return {
345
+ restrict: 'A',
346
+ template: '<div></div>',
347
+ link: function(scope, elem) {
348
+
349
+ // Receive render events
350
+ scope.$on('render',function(){
351
+ render_panel();
352
+ });
353
+
354
+ // Re-render if the window is resized
355
+ angular.element(window).bind('resize', function(){
356
+ render_panel();
357
+ });
358
+
359
+ // Function for rendering panel
360
+ function render_panel() {
361
+ // IE doesn't work without this
362
+ elem.css({height:scope.panel.height || scope.row.height});
363
+
364
+ // Populate from the query service
365
+ try {
366
+ _.each(scope.data, function(series) {
367
+ series.label = series.info.alias;
368
+ series.color = series.info.color;
369
+ });
370
+ } catch(e) {return;}
371
+
372
+ // Set barwidth based on specified interval
373
+ var barwidth = kbn.interval_to_ms(scope.panel.interval);
374
+
375
+ var stack = scope.panel.stack ? true : null;
376
+
377
+ // Populate element
378
+ try {
379
+ var options = {
380
+ legend: { show: false },
381
+ series: {
382
+ stackpercent: scope.panel.stack ? scope.panel.percentage : false,
383
+ stack: scope.panel.percentage ? null : stack,
384
+ lines: {
385
+ show: scope.panel.lines,
386
+ // Silly, but fixes bug in stacked percentages
387
+ fill: scope.panel.fill === 0 ? 0.001 : scope.panel.fill/10,
388
+ lineWidth: scope.panel.linewidth,
389
+ steps: false
390
+ },
391
+ bars: {
392
+ show: scope.panel.bars,
393
+ fill: 1,
394
+ barWidth: barwidth/1.8,
395
+ zero: false,
396
+ lineWidth: 0
397
+ },
398
+ points: {
399
+ show: scope.panel.points,
400
+ fill: 1,
401
+ fillColor: false,
402
+ radius: 5
403
+ },
404
+ shadowSize: 1
405
+ },
406
+ yaxis: {
407
+ show: scope.panel['y-axis'],
408
+ min: 0,
409
+ max: scope.panel.percentage && scope.panel.stack ? 100 : null,
410
+ },
411
+ xaxis: {
412
+ timezone: scope.panel.timezone,
413
+ show: scope.panel['x-axis'],
414
+ mode: "time",
415
+ min: _.isUndefined(scope.range.from) ? null : scope.range.from.getTime(),
416
+ max: _.isUndefined(scope.range.to) ? null : scope.range.to.getTime(),
417
+ timeformat: time_format(scope.panel.interval),
418
+ label: "Datetime",
419
+ },
420
+ grid: {
421
+ backgroundColor: null,
422
+ borderWidth: 0,
423
+ hoverable: true,
424
+ color: '#c8c8c8'
425
+ }
426
+ };
427
+
428
+ if(scope.panel.interactive) {
429
+ options.selection = { mode: "x", color: '#666' };
430
+ }
431
+
432
+ // when rendering stacked bars, we need to ensure each point that has data is zero-filled
433
+ // so that the stacking happens in the proper order
434
+ var required_times = [];
435
+ if (scope.data.length > 1) {
436
+ required_times = Array.prototype.concat.apply([], _.map(scope.data, function (query) {
437
+ return query.time_series.getOrderedTimes();
438
+ }));
439
+ required_times = _.uniq(required_times.sort(function (a, b) {
440
+ // decending numeric sort
441
+ return a-b;
442
+ }), true);
443
+ }
444
+
445
+ for (var i = 0; i < scope.data.length; i++) {
446
+ scope.data[i].data = scope.data[i].time_series.getFlotPairs(required_times);
447
+ }
448
+
449
+ scope.plot = $.plot(elem, scope.data, options);
450
+
451
+ } catch(e) {
452
+ console.log(e);
453
+ }
454
+ }
455
+
456
+ function time_format(interval) {
457
+ var _int = kbn.interval_to_seconds(interval);
458
+ if(_int >= 2628000) {
459
+ return "%m/%y";
460
+ }
461
+ if(_int >= 86400) {
462
+ return "%m/%d/%y";
463
+ }
464
+ if(_int >= 60) {
465
+ return "%H:%M<br>%m/%d";
466
+ }
467
+
468
+ return "%H:%M:%S";
469
+ }
470
+
471
+ var $tooltip = $('<div>');
472
+ elem.bind("plothover", function (event, pos, item) {
473
+ var group, value;
474
+ if (item) {
475
+ if (item.series.info.alias || scope.panel.tooltip.query_as_alias) {
476
+ group = '<small style="font-size:0.9em;">' +
477
+ '<i class="icon-circle" style="color:'+item.series.color+';"></i>' + ' ' +
478
+ (item.series.info.alias || item.series.info.query)+
479
+ '</small><br>';
480
+ } else {
481
+ group = kbn.query_color_dot(item.series.color, 15) + ' ';
482
+ }
483
+ if (scope.panel.stack && scope.panel.tooltip.value_type === 'individual') {
484
+ value = item.datapoint[1] - item.datapoint[2];
485
+ } else {
486
+ value = item.datapoint[1];
487
+ }
488
+ $tooltip
489
+ .html(
490
+ group + value + " @ " + moment(item.datapoint[0]).format('MM/DD HH:mm:ss')
491
+ )
492
+ .place_tt(pos.pageX, pos.pageY);
493
+ } else {
494
+ $tooltip.detach();
495
+ }
496
+ });
497
+
498
+ elem.bind("plotselected", function (event, ranges) {
499
+ filterSrv.set({
500
+ type : 'time',
501
+ from : moment.utc(ranges.xaxis.from),
502
+ to : moment.utc(ranges.xaxis.to),
503
+ field : scope.panel.time_field
504
+ });
505
+ dashboard.refresh();
506
+ });
507
+ }
508
+ };
509
+ });
510
+
511
+ });