riemann-dash 0.2.12 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c6101ce9bb7b5d9c11c24673be2a5b3c0399f2a3
4
+ data.tar.gz: e19a97d12f65736cb9137fef3f1dc6b4bcfb59e7
5
+ SHA512:
6
+ metadata.gz: b762f4b990ec0375e49eab17659ad17ecc03e11c6f3a009aa5045390cff70aafdf60f0a26dca9ed0617b78ed254ad50728445e617060ab9e1964678e385f6c9c
7
+ data.tar.gz: 7ed47f5330e26204182463aafdadb2371c6d74bbeb51a2c9882259f6aa594f69a3a67d94ea3c572a9a4669a97a092d2a30978df9e01df783566d72eee2b253a0
@@ -1,70 +1,35 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- riemann-dash (0.2.8)
4
+ riemann-dash (0.2.13)
5
5
  erubis (>= 2.7.0)
6
- fog
7
6
  multi_json (= 1.3.6)
8
- riemann-client (>= 0.0.7)
9
7
  sass (>= 3.1.14)
10
- sinatra (>= 1.3.2)
11
- thin (>= 1.3.1)
8
+ sinatra (~> 1.4.5)
9
+ webrick (~> 1.3.1)
12
10
 
13
11
  GEM
14
12
  remote: https://rubygems.org/
15
13
  specs:
16
- beefcake (0.5.0)
17
- builder (3.2.2)
18
14
  coderay (1.0.9)
19
- daemons (1.1.9)
20
15
  erubis (2.7.0)
21
- eventmachine (1.0.3)
22
- excon (0.31.0)
23
- fog (1.19.0)
24
- builder
25
- excon (~> 0.31.0)
26
- formatador (~> 0.2.0)
27
- mime-types
28
- multi_json (~> 1.0)
29
- net-scp (~> 1.1)
30
- net-ssh (>= 2.1.3)
31
- nokogiri (~> 1.5)
32
- ruby-hmac
33
- formatador (0.2.4)
34
16
  method_source (0.8.1)
35
- mime-types (2.0)
36
- mini_portile (0.5.2)
37
- mtrc (0.0.4)
38
17
  multi_json (1.3.6)
39
- net-scp (1.1.2)
40
- net-ssh (>= 2.6.5)
41
- net-ssh (2.7.0)
42
- nokogiri (1.6.1)
43
- mini_portile (~> 0.5.0)
44
18
  pry (0.9.12)
45
19
  coderay (~> 1.0.5)
46
20
  method_source (~> 0.8)
47
21
  slop (~> 3.4)
48
- rack (1.5.2)
49
- rack-protection (1.5.2)
22
+ rack (1.6.4)
23
+ rack-protection (1.5.3)
50
24
  rack
51
- riemann-client (0.2.2)
52
- beefcake (>= 0.3.5)
53
- mtrc (>= 0.0.4)
54
- trollop (>= 1.16.2)
55
- ruby-hmac (0.4.0)
56
- sass (3.3.2)
57
- sinatra (1.4.4)
58
- rack (~> 1.4)
25
+ sass (3.4.22)
26
+ sinatra (1.4.7)
27
+ rack (~> 1.5)
59
28
  rack-protection (~> 1.4)
60
- tilt (~> 1.3, >= 1.3.4)
29
+ tilt (>= 1.3, < 3)
61
30
  slop (3.4.3)
62
- thin (1.6.2)
63
- daemons (>= 1.0.9)
64
- eventmachine (>= 1.0.0)
65
- rack (>= 1.0.0)
66
- tilt (1.4.1)
67
- trollop (2.0)
31
+ tilt (2.0.5)
32
+ webrick (1.3.1)
68
33
 
69
34
  PLATFORMS
70
35
  ruby
@@ -72,3 +37,6 @@ PLATFORMS
72
37
  DEPENDENCIES
73
38
  pry
74
39
  riemann-dash!
40
+
41
+ BUNDLED WITH
42
+ 1.10.6
@@ -56,7 +56,7 @@ example rackup app is found in "example/config.ru".
56
56
  Development
57
57
  ===========
58
58
 
59
- $ git clone git://github.com/aphyr/riemann-dash.git
59
+ $ git clone git://github.com/riemann/riemann-dash.git
60
60
  $ cd riemann-dash
61
61
  $ bundle
62
62
 
@@ -3,6 +3,14 @@ var toolbar = (function() {
3
3
  var toolbar = $('#toolbar');
4
4
  var form = $('<form/>');
5
5
  toolbar.append(form);
6
+
7
+ // Method to adjust the position of the view div
8
+ var sizeAdjust = function() {
9
+ $('#view').css('top', toolbar.height() + "px");
10
+ };
11
+ $( window ).resize(function() {
12
+ sizeAdjust();
13
+ });
6
14
 
7
15
  var pager = $('<div class="pager">');
8
16
  var load = $('<div class="load"><div class="bar load1" /><div class="bar load5" /><span title="1- and 5-second subscription manager load averages">Load</span></div>');
@@ -134,6 +142,7 @@ var toolbar = (function() {
134
142
  });
135
143
 
136
144
  pager.append(add);
145
+ sizeAdjust();
137
146
  };
138
147
 
139
148
  // Returns a tile for a workspace.
@@ -7,8 +7,9 @@
7
7
  * @author Augusto Pascutti
8
8
  */
9
9
  var QueueItem = function(v, p) {
10
- this.value = v;
11
- this.priority = p;
10
+ this.value = v;
11
+ this.priority = p;
12
+ this.value_JSON = JSON.stringify(v);
12
13
  };
13
14
 
14
15
  /**
@@ -64,8 +65,9 @@ PriorityQueue.prototype = {
64
65
  known = false;
65
66
  idx = 0;
66
67
 
68
+ var value_JSON = JSON.stringify(value);
67
69
  this._queue.forEach(function() {
68
- if (JSON.stringify(this._queue[idx].value) === JSON.stringify(value)) {
70
+ if (this._queue[idx].value_JSON === value_JSON) {
69
71
  this._queue[idx].priority = priority;
70
72
  known = true;
71
73
  return;
@@ -0,0 +1,601 @@
1
+ /*
2
+ * jquery.flot.tooltip
3
+ *
4
+ * description: easy-to-use tooltips for Flot charts
5
+ * version: 0.8.6
6
+ * authors: Krzysztof Urbas @krzysu [myviews.pl],Evan Steinkerchner @Roundaround
7
+ * website: https://github.com/krzysu/flot.tooltip
8
+ *
9
+ * build on 2016-02-25
10
+ * released under MIT License, 2012
11
+ */
12
+ (function ($) {
13
+ // plugin options, default values
14
+ var defaultOptions = {
15
+ tooltip: {
16
+ show: false,
17
+ cssClass: "flotTip",
18
+ content: "%s | X: %x | Y: %y",
19
+ // allowed templates are:
20
+ // %s -> series label,
21
+ // %c -> series color,
22
+ // %lx -> x axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels),
23
+ // %ly -> y axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels),
24
+ // %x -> X value,
25
+ // %y -> Y value,
26
+ // %x.2 -> precision of X value,
27
+ // %p -> percent
28
+ // %n -> value (not percent) of pie chart
29
+ xDateFormat: null,
30
+ yDateFormat: null,
31
+ monthNames: null,
32
+ dayNames: null,
33
+ shifts: {
34
+ x: 10,
35
+ y: 20
36
+ },
37
+ defaultTheme: true,
38
+ snap: true,
39
+ lines: false,
40
+ clickTips: false,
41
+
42
+ // callbacks
43
+ onHover: function (flotItem, $tooltipEl) {},
44
+
45
+ $compat: false
46
+ }
47
+ };
48
+
49
+ // dummy default options object for legacy code (<0.8.5) - is deleted later
50
+ defaultOptions.tooltipOpts = defaultOptions.tooltip;
51
+
52
+ // object
53
+ var FlotTooltip = function (plot) {
54
+ // variables
55
+ this.tipPosition = {x: 0, y: 0};
56
+
57
+ this.init(plot);
58
+ };
59
+
60
+ // main plugin function
61
+ FlotTooltip.prototype.init = function (plot) {
62
+ var that = this;
63
+
64
+ // detect other flot plugins
65
+ var plotPluginsLength = $.plot.plugins.length;
66
+ this.plotPlugins = [];
67
+
68
+ if (plotPluginsLength) {
69
+ for (var p = 0; p < plotPluginsLength; p++) {
70
+ this.plotPlugins.push($.plot.plugins[p].name);
71
+ }
72
+ }
73
+
74
+ plot.hooks.bindEvents.push(function (plot, eventHolder) {
75
+
76
+ // get plot options
77
+ that.plotOptions = plot.getOptions();
78
+
79
+ // for legacy (<0.8.5) implementations
80
+ if (typeof(that.plotOptions.tooltip) === 'boolean') {
81
+ that.plotOptions.tooltipOpts.show = that.plotOptions.tooltip;
82
+ that.plotOptions.tooltip = that.plotOptions.tooltipOpts;
83
+ delete that.plotOptions.tooltipOpts;
84
+ }
85
+
86
+ // if not enabled return
87
+ if (that.plotOptions.tooltip.show === false || typeof that.plotOptions.tooltip.show === 'undefined') return;
88
+
89
+ // shortcut to access tooltip options
90
+ that.tooltipOptions = that.plotOptions.tooltip;
91
+
92
+ if (that.tooltipOptions.$compat) {
93
+ that.wfunc = 'width';
94
+ that.hfunc = 'height';
95
+ } else {
96
+ that.wfunc = 'innerWidth';
97
+ that.hfunc = 'innerHeight';
98
+ }
99
+
100
+ // create tooltip DOM element
101
+ var $tip = that.getDomElement();
102
+
103
+ // bind event
104
+ $( plot.getPlaceholder() ).bind("plothover", plothover);
105
+ if (that.tooltipOptions.clickTips) {
106
+ $( plot.getPlaceholder() ).bind("plotclick", plotclick);
107
+ }
108
+ that.clickmode = false;
109
+
110
+ $(eventHolder).bind('mousemove', mouseMove);
111
+ });
112
+
113
+ plot.hooks.shutdown.push(function (plot, eventHolder){
114
+ $(plot.getPlaceholder()).unbind("plothover", plothover);
115
+ $(plot.getPlaceholder()).unbind("plotclick", plotclick);
116
+ plot.removeTooltip();
117
+ $(eventHolder).unbind("mousemove", mouseMove);
118
+ });
119
+
120
+ function mouseMove(e){
121
+ var pos = {};
122
+ pos.x = e.pageX;
123
+ pos.y = e.pageY;
124
+ plot.setTooltipPosition(pos);
125
+ }
126
+
127
+ /**
128
+ * open the tooltip (if not already open) and freeze it on the current position till the next click
129
+ */
130
+ function plotclick(event, pos, item) {
131
+ if (! that.clickmode) {
132
+ // it is the click activating the clicktip
133
+ plothover(event, pos, item);
134
+ if (that.getDomElement().is(":visible")) {
135
+ $(plot.getPlaceholder()).unbind("plothover", plothover);
136
+ that.clickmode = true;
137
+ }
138
+ } else {
139
+ // it is the click deactivating the clicktip
140
+ $( plot.getPlaceholder() ).bind("plothover", plothover);
141
+ plot.hideTooltip();
142
+ that.clickmode = false;
143
+ }
144
+ }
145
+
146
+ function plothover(event, pos, item) {
147
+ // Simple distance formula.
148
+ var lineDistance = function (p1x, p1y, p2x, p2y) {
149
+ return Math.sqrt((p2x - p1x) * (p2x - p1x) + (p2y - p1y) * (p2y - p1y));
150
+ };
151
+
152
+ // Here is some voodoo magic for determining the distance to a line form a given point {x, y}.
153
+ var dotLineLength = function (x, y, x0, y0, x1, y1, o) {
154
+ if (o && !(o =
155
+ function (x, y, x0, y0, x1, y1) {
156
+ if (typeof x0 !== 'undefined') return { x: x0, y: y };
157
+ else if (typeof y0 !== 'undefined') return { x: x, y: y0 };
158
+
159
+ var left,
160
+ tg = -1 / ((y1 - y0) / (x1 - x0));
161
+
162
+ return {
163
+ x: left = (x1 * (x * tg - y + y0) + x0 * (x * -tg + y - y1)) / (tg * (x1 - x0) + y0 - y1),
164
+ y: tg * left - tg * x + y
165
+ };
166
+ } (x, y, x0, y0, x1, y1),
167
+ o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1))
168
+ ) {
169
+ var l1 = lineDistance(x, y, x0, y0), l2 = lineDistance(x, y, x1, y1);
170
+ return l1 > l2 ? l2 : l1;
171
+ } else {
172
+ var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1;
173
+ return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
174
+ }
175
+ };
176
+
177
+ if (item) {
178
+ plot.showTooltip(item, that.tooltipOptions.snap ? item : pos);
179
+ } else if (that.plotOptions.series.lines.show && that.tooltipOptions.lines === true) {
180
+ var maxDistance = that.plotOptions.grid.mouseActiveRadius;
181
+
182
+ var closestTrace = {
183
+ distance: maxDistance + 1
184
+ };
185
+
186
+ var ttPos = pos;
187
+
188
+ $.each(plot.getData(), function (i, series) {
189
+ var xBeforeIndex = 0,
190
+ xAfterIndex = -1;
191
+
192
+ // Our search here assumes our data is sorted via the x-axis.
193
+ // TODO: Improve efficiency somehow - search smaller sets of data.
194
+ for (var j = 1; j < series.data.length; j++) {
195
+ if (series.data[j - 1][0] <= pos.x && series.data[j][0] >= pos.x) {
196
+ xBeforeIndex = j - 1;
197
+ xAfterIndex = j;
198
+ }
199
+ }
200
+
201
+ if (xAfterIndex === -1) {
202
+ plot.hideTooltip();
203
+ return;
204
+ }
205
+
206
+ var pointPrev = { x: series.data[xBeforeIndex][0], y: series.data[xBeforeIndex][1] },
207
+ pointNext = { x: series.data[xAfterIndex][0], y: series.data[xAfterIndex][1] };
208
+
209
+ var distToLine = dotLineLength(series.xaxis.p2c(pos.x), series.yaxis.p2c(pos.y), series.xaxis.p2c(pointPrev.x),
210
+ series.yaxis.p2c(pointPrev.y), series.xaxis.p2c(pointNext.x), series.yaxis.p2c(pointNext.y), false);
211
+
212
+ if (distToLine < closestTrace.distance) {
213
+
214
+ var closestIndex = lineDistance(pointPrev.x, pointPrev.y, pos.x, pos.y) <
215
+ lineDistance(pos.x, pos.y, pointNext.x, pointNext.y) ? xBeforeIndex : xAfterIndex;
216
+
217
+ var pointSize = series.datapoints.pointsize;
218
+
219
+ // Calculate the point on the line vertically closest to our cursor.
220
+ var pointOnLine = [
221
+ pos.x,
222
+ pointPrev.y + ((pointNext.y - pointPrev.y) * ((pos.x - pointPrev.x) / (pointNext.x - pointPrev.x)))
223
+ ];
224
+
225
+ var item = {
226
+ datapoint: pointOnLine,
227
+ dataIndex: closestIndex,
228
+ series: series,
229
+ seriesIndex: i
230
+ };
231
+
232
+ closestTrace = {
233
+ distance: distToLine,
234
+ item: item
235
+ };
236
+
237
+ if (that.tooltipOptions.snap) {
238
+ ttPos = {
239
+ pageX: series.xaxis.p2c(pointOnLine[0]),
240
+ pageY: series.yaxis.p2c(pointOnLine[1])
241
+ };
242
+ }
243
+ }
244
+ });
245
+
246
+ if (closestTrace.distance < maxDistance + 1)
247
+ plot.showTooltip(closestTrace.item, ttPos);
248
+ else
249
+ plot.hideTooltip();
250
+ } else {
251
+ plot.hideTooltip();
252
+ }
253
+ }
254
+
255
+ // Quick little function for setting the tooltip position.
256
+ plot.setTooltipPosition = function (pos) {
257
+ var $tip = that.getDomElement();
258
+
259
+ var totalTipWidth = $tip.outerWidth() + that.tooltipOptions.shifts.x;
260
+ var totalTipHeight = $tip.outerHeight() + that.tooltipOptions.shifts.y;
261
+ if ((pos.x - $(window).scrollLeft()) > ($(window)[that.wfunc]() - totalTipWidth)) {
262
+ pos.x -= totalTipWidth;
263
+ }
264
+ if ((pos.y - $(window).scrollTop()) > ($(window)[that.hfunc]() - totalTipHeight)) {
265
+ pos.y -= totalTipHeight;
266
+ }
267
+
268
+ /*
269
+ The section applies the new positioning ONLY if pos.x and pos.y
270
+ are numbers. If they are undefined or not a number, use the last
271
+ known numerical position. This hack fixes a bug that kept pie
272
+ charts from keeping their tooltip positioning.
273
+ */
274
+
275
+ if (isNaN(pos.x)) {
276
+ that.tipPosition.x = that.tipPosition.xPrev;
277
+ }
278
+ else {
279
+ that.tipPosition.x = pos.x;
280
+ that.tipPosition.xPrev = pos.x;
281
+ }
282
+ if (isNaN(pos.y)) {
283
+ that.tipPosition.y = that.tipPosition.yPrev;
284
+ }
285
+ else {
286
+ that.tipPosition.y = pos.y;
287
+ that.tipPosition.yPrev = pos.y;
288
+ }
289
+
290
+ };
291
+
292
+ // Quick little function for showing the tooltip.
293
+ plot.showTooltip = function (target, position, targetPosition) {
294
+ var $tip = that.getDomElement();
295
+
296
+ // convert tooltip content template to real tipText
297
+ var tipText = that.stringFormat(that.tooltipOptions.content, target);
298
+ if (tipText === '')
299
+ return;
300
+
301
+ $tip.html(tipText);
302
+ plot.setTooltipPosition({ x: position.pageX, y: position.pageY });
303
+ $tip.css({
304
+ left: that.tipPosition.x + that.tooltipOptions.shifts.x,
305
+ top: that.tipPosition.y + that.tooltipOptions.shifts.y
306
+ }).show();
307
+
308
+ // run callback
309
+ if (typeof that.tooltipOptions.onHover === 'function') {
310
+ that.tooltipOptions.onHover(target, $tip);
311
+ }
312
+ };
313
+
314
+ // Quick little function for hiding the tooltip.
315
+ plot.hideTooltip = function () {
316
+ that.getDomElement().hide().html('');
317
+ };
318
+
319
+ plot.removeTooltip = function() {
320
+ that.getDomElement().remove();
321
+ };
322
+ };
323
+
324
+ /**
325
+ * get or create tooltip DOM element
326
+ * @return jQuery object
327
+ */
328
+ FlotTooltip.prototype.getDomElement = function () {
329
+ var $tip = $('.' + this.tooltipOptions.cssClass);
330
+
331
+ if( $tip.length === 0 ){
332
+ $tip = $('<div />').addClass(this.tooltipOptions.cssClass);
333
+ $tip.appendTo('body').hide().css({position: 'absolute'});
334
+
335
+ if(this.tooltipOptions.defaultTheme) {
336
+ $tip.css({
337
+ 'background': '#fff',
338
+ 'z-index': '1040',
339
+ 'padding': '0.4em 0.6em',
340
+ 'border-radius': '0.5em',
341
+ 'font-size': '0.8em',
342
+ 'border': '1px solid #111',
343
+ 'display': 'none',
344
+ 'white-space': 'nowrap'
345
+ });
346
+ }
347
+ }
348
+
349
+ return $tip;
350
+ };
351
+
352
+ /**
353
+ * core function, create tooltip content
354
+ * @param {string} content - template with tooltip content
355
+ * @param {object} item - Flot item
356
+ * @return {string} real tooltip content for current item
357
+ */
358
+ FlotTooltip.prototype.stringFormat = function (content, item) {
359
+ var percentPattern = /%p\.{0,1}(\d{0,})/;
360
+ var seriesPattern = /%s/;
361
+ var colorPattern = /%c/;
362
+ var xLabelPattern = /%lx/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded
363
+ var yLabelPattern = /%ly/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded
364
+ var xPattern = /%x\.{0,1}(\d{0,})/;
365
+ var yPattern = /%y\.{0,1}(\d{0,})/;
366
+ var xPatternWithoutPrecision = "%x";
367
+ var yPatternWithoutPrecision = "%y";
368
+ var customTextPattern = "%ct";
369
+ var nPiePattern = "%n";
370
+
371
+ var x, y, customText, p, n;
372
+
373
+ // for threshold plugin we need to read data from different place
374
+ if (typeof item.series.threshold !== "undefined") {
375
+ x = item.datapoint[0];
376
+ y = item.datapoint[1];
377
+ customText = item.datapoint[2];
378
+ }
379
+
380
+ // for CurvedLines plugin we need to read data from different place
381
+ else if (typeof item.series.curvedLines !== "undefined") {
382
+ x = item.datapoint[0];
383
+ y = item.datapoint[1];
384
+ }
385
+
386
+ else if (typeof item.series.lines !== "undefined" && item.series.lines.steps) {
387
+ x = item.series.datapoints.points[item.dataIndex * 2];
388
+ y = item.series.datapoints.points[item.dataIndex * 2 + 1];
389
+ // TODO: where to find custom text in this variant?
390
+ customText = "";
391
+ } else {
392
+ x = item.series.data[item.dataIndex][0];
393
+ y = item.series.data[item.dataIndex][1];
394
+ customText = item.series.data[item.dataIndex][2];
395
+ }
396
+
397
+ // I think this is only in case of threshold plugin
398
+ if (item.series.label === null && item.series.originSeries) {
399
+ item.series.label = item.series.originSeries.label;
400
+ }
401
+
402
+ // if it is a function callback get the content string
403
+ if (typeof(content) === 'function') {
404
+ content = content(item.series.label, x, y, item);
405
+ }
406
+
407
+ // the case where the passed content is equal to false
408
+ if (typeof(content) === 'boolean' && !content) {
409
+ return '';
410
+ }
411
+
412
+ /* replacement of %ct and other multi-character templates must
413
+ precede the replacement of single-character templates
414
+ to avoid conflict between '%c' and '%ct' and similar substrings
415
+ */
416
+ if (customText)
417
+ content = content.replace(customTextPattern, customText);
418
+
419
+ // percent match for pie charts and stacked percent
420
+ if (typeof (item.series.percent) !== 'undefined') {
421
+ p = item.series.percent;
422
+ } else if (typeof (item.series.percents) !== 'undefined') {
423
+ p = item.series.percents[item.dataIndex];
424
+ }
425
+ if (typeof p === 'number') {
426
+ content = this.adjustValPrecision(percentPattern, content, p);
427
+ }
428
+
429
+ // replace %n with number of items represented by slice in pie charts
430
+ if (item.series.hasOwnProperty('pie')) {
431
+ if (typeof (item.series.data[0][1] !== 'undefined')) {
432
+ n = item.series.data[0][1];
433
+ }
434
+ }
435
+ if (typeof n === 'number') {
436
+ content = content.replace(nPiePattern, n);
437
+ }
438
+
439
+ // series match
440
+ if (typeof(item.series.label) !== 'undefined') {
441
+ content = content.replace(seriesPattern, item.series.label);
442
+ } else {
443
+ //remove %s if label is undefined
444
+ content = content.replace(seriesPattern, "");
445
+ }
446
+
447
+ // color match
448
+ if (typeof(item.series.color) !== 'undefined') {
449
+ content = content.replace(colorPattern, item.series.color);
450
+ } else {
451
+ //remove %s if color is undefined
452
+ content = content.replace(colorPattern, "");
453
+ }
454
+
455
+ // x axis label match
456
+ if (this.hasAxisLabel('xaxis', item)) {
457
+ content = content.replace(xLabelPattern, item.series.xaxis.options.axisLabel);
458
+ } else {
459
+ //remove %lx if axis label is undefined or axislabels plugin not present
460
+ content = content.replace(xLabelPattern, "");
461
+ }
462
+
463
+ // y axis label match
464
+ if (this.hasAxisLabel('yaxis', item)) {
465
+ content = content.replace(yLabelPattern, item.series.yaxis.options.axisLabel);
466
+ } else {
467
+ //remove %ly if axis label is undefined or axislabels plugin not present
468
+ content = content.replace(yLabelPattern, "");
469
+ }
470
+
471
+ // time mode axes with custom dateFormat
472
+ if (this.isTimeMode('xaxis', item) && this.isXDateFormat(item)) {
473
+ content = content.replace(xPattern, this.timestampToDate(x, this.tooltipOptions.xDateFormat, item.series.xaxis.options));
474
+ }
475
+ if (this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) {
476
+ content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat, item.series.yaxis.options));
477
+ }
478
+
479
+ // set precision if defined
480
+ if (typeof x === 'number') {
481
+ content = this.adjustValPrecision(xPattern, content, x);
482
+ }
483
+ if (typeof y === 'number') {
484
+ content = this.adjustValPrecision(yPattern, content, y);
485
+ }
486
+
487
+ // change x from number to given label, if given
488
+ if (typeof item.series.xaxis.ticks !== 'undefined') {
489
+
490
+ var ticks;
491
+ if (this.hasRotatedXAxisTicks(item)) {
492
+ // xaxis.ticks will be an empty array if tickRotor is being used, but the values are available in rotatedTicks
493
+ ticks = 'rotatedTicks';
494
+ } else {
495
+ ticks = 'ticks';
496
+ }
497
+
498
+ // see https://github.com/krzysu/flot.tooltip/issues/65
499
+ var tickIndex = item.dataIndex + item.seriesIndex;
500
+
501
+ for (var xIndex in item.series.xaxis[ticks]) {
502
+ if (item.series.xaxis[ticks].hasOwnProperty(tickIndex) && !this.isTimeMode('xaxis', item)) {
503
+ var valueX = (this.isCategoriesMode('xaxis', item)) ? item.series.xaxis[ticks][tickIndex].label : item.series.xaxis[ticks][tickIndex].v;
504
+ if (valueX === x) {
505
+ content = content.replace(xPattern, item.series.xaxis[ticks][tickIndex].label.replace(/\$/g, '$$$$'));
506
+ }
507
+ }
508
+ }
509
+ }
510
+
511
+ // change y from number to given label, if given
512
+ if (typeof item.series.yaxis.ticks !== 'undefined') {
513
+ for (var yIndex in item.series.yaxis.ticks) {
514
+ if (item.series.yaxis.ticks.hasOwnProperty(yIndex)) {
515
+ var valueY = (this.isCategoriesMode('yaxis', item)) ? item.series.yaxis.ticks[yIndex].label : item.series.yaxis.ticks[yIndex].v;
516
+ if (valueY === y) {
517
+ content = content.replace(yPattern, item.series.yaxis.ticks[yIndex].label.replace(/\$/g, '$$$$'));
518
+ }
519
+ }
520
+ }
521
+ }
522
+
523
+ // if no value customization, use tickFormatter by default
524
+ if (typeof item.series.xaxis.tickFormatter !== 'undefined') {
525
+ //escape dollar
526
+ content = content.replace(xPatternWithoutPrecision, item.series.xaxis.tickFormatter(x, item.series.xaxis).replace(/\$/g, '$$'));
527
+ }
528
+ if (typeof item.series.yaxis.tickFormatter !== 'undefined') {
529
+ //escape dollar
530
+ content = content.replace(yPatternWithoutPrecision, item.series.yaxis.tickFormatter(y, item.series.yaxis).replace(/\$/g, '$$'));
531
+ }
532
+
533
+ return content;
534
+ };
535
+
536
+ // helpers just for readability
537
+ FlotTooltip.prototype.isTimeMode = function (axisName, item) {
538
+ return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'time');
539
+ };
540
+
541
+ FlotTooltip.prototype.isXDateFormat = function (item) {
542
+ return (typeof this.tooltipOptions.xDateFormat !== 'undefined' && this.tooltipOptions.xDateFormat !== null);
543
+ };
544
+
545
+ FlotTooltip.prototype.isYDateFormat = function (item) {
546
+ return (typeof this.tooltipOptions.yDateFormat !== 'undefined' && this.tooltipOptions.yDateFormat !== null);
547
+ };
548
+
549
+ FlotTooltip.prototype.isCategoriesMode = function (axisName, item) {
550
+ return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'categories');
551
+ };
552
+
553
+ //
554
+ FlotTooltip.prototype.timestampToDate = function (tmst, dateFormat, options) {
555
+ var theDate = $.plot.dateGenerator(tmst, options);
556
+ return $.plot.formatDate(theDate, dateFormat, this.tooltipOptions.monthNames, this.tooltipOptions.dayNames);
557
+ };
558
+
559
+ //
560
+ FlotTooltip.prototype.adjustValPrecision = function (pattern, content, value) {
561
+
562
+ var precision;
563
+ var matchResult = content.match(pattern);
564
+ if( matchResult !== null ) {
565
+ if(RegExp.$1 !== '') {
566
+ precision = RegExp.$1;
567
+ value = value.toFixed(precision);
568
+
569
+ // only replace content if precision exists, in other case use thickformater
570
+ content = content.replace(pattern, value);
571
+ }
572
+ }
573
+ return content;
574
+ };
575
+
576
+ // other plugins detection below
577
+
578
+ // check if flot-axislabels plugin (https://github.com/markrcote/flot-axislabels) is used and that an axis label is given
579
+ FlotTooltip.prototype.hasAxisLabel = function (axisName, item) {
580
+ return ($.inArray('axisLabels', this.plotPlugins) !== -1 && typeof item.series[axisName].options.axisLabel !== 'undefined' && item.series[axisName].options.axisLabel.length > 0);
581
+ };
582
+
583
+ // check whether flot-tickRotor, a plugin which allows rotation of X-axis ticks, is being used
584
+ FlotTooltip.prototype.hasRotatedXAxisTicks = function (item) {
585
+ return ($.inArray('tickRotor',this.plotPlugins) !== -1 && typeof item.series.xaxis.rotatedTicks !== 'undefined');
586
+ };
587
+
588
+ //
589
+ var init = function (plot) {
590
+ new FlotTooltip(plot);
591
+ };
592
+
593
+ // define Flot plugin
594
+ $.plot.plugins.push({
595
+ init: init,
596
+ options: defaultOptions,
597
+ name: 'tooltip',
598
+ version: '0.8.5'
599
+ });
600
+
601
+ })(jQuery);
@@ -0,0 +1,12 @@
1
+ /*
2
+ * jquery.flot.tooltip
3
+ *
4
+ * description: easy-to-use tooltips for Flot charts
5
+ * version: 0.8.6
6
+ * authors: Krzysztof Urbas @krzysu [myviews.pl],Evan Steinkerchner @Roundaround
7
+ * website: https://github.com/krzysu/flot.tooltip
8
+ *
9
+ * build on 2016-02-25
10
+ * released under MIT License, 2012
11
+ */
12
+ !function(a){var b={tooltip:{show:!1,cssClass:"flotTip",content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,monthNames:null,dayNames:null,shifts:{x:10,y:20},defaultTheme:!0,snap:!0,lines:!1,clickTips:!1,onHover:function(a,b){},$compat:!1}};b.tooltipOpts=b.tooltip;var c=function(a){this.tipPosition={x:0,y:0},this.init(a)};c.prototype.init=function(b){function c(a){var c={};c.x=a.pageX,c.y=a.pageY,b.setTooltipPosition(c)}function d(c,d,g){f.clickmode?(a(b.getPlaceholder()).bind("plothover",e),b.hideTooltip(),f.clickmode=!1):(e(c,d,g),f.getDomElement().is(":visible")&&(a(b.getPlaceholder()).unbind("plothover",e),f.clickmode=!0))}function e(c,d,e){var g=function(a,b,c,d){return Math.sqrt((c-a)*(c-a)+(d-b)*(d-b))},h=function(a,b,c,d,e,f,h){if(!h||(h=function(a,b,c,d,e,f){if("undefined"!=typeof c)return{x:c,y:b};if("undefined"!=typeof d)return{x:a,y:d};var g,h=-1/((f-d)/(e-c));return{x:g=(e*(a*h-b+d)+c*(a*-h+b-f))/(h*(e-c)+d-f),y:h*g-h*a+b}}(a,b,c,d,e,f),h.x>=Math.min(c,e)&&h.x<=Math.max(c,e)&&h.y>=Math.min(d,f)&&h.y<=Math.max(d,f))){var i=d-f,j=e-c,k=c*f-d*e;return Math.abs(i*a+j*b+k)/Math.sqrt(i*i+j*j)}var l=g(a,b,c,d),m=g(a,b,e,f);return l>m?m:l};if(e)b.showTooltip(e,f.tooltipOptions.snap?e:d);else if(f.plotOptions.series.lines.show&&f.tooltipOptions.lines===!0){var i=f.plotOptions.grid.mouseActiveRadius,j={distance:i+1},k=d;a.each(b.getData(),function(a,c){for(var e=0,i=-1,l=1;l<c.data.length;l++)c.data[l-1][0]<=d.x&&c.data[l][0]>=d.x&&(e=l-1,i=l);if(-1===i)return void b.hideTooltip();var m={x:c.data[e][0],y:c.data[e][1]},n={x:c.data[i][0],y:c.data[i][1]},o=h(c.xaxis.p2c(d.x),c.yaxis.p2c(d.y),c.xaxis.p2c(m.x),c.yaxis.p2c(m.y),c.xaxis.p2c(n.x),c.yaxis.p2c(n.y),!1);if(o<j.distance){var p=g(m.x,m.y,d.x,d.y)<g(d.x,d.y,n.x,n.y)?e:i,q=(c.datapoints.pointsize,[d.x,m.y+(n.y-m.y)*((d.x-m.x)/(n.x-m.x))]),r={datapoint:q,dataIndex:p,series:c,seriesIndex:a};j={distance:o,item:r},f.tooltipOptions.snap&&(k={pageX:c.xaxis.p2c(q[0]),pageY:c.yaxis.p2c(q[1])})}}),j.distance<i+1?b.showTooltip(j.item,k):b.hideTooltip()}else b.hideTooltip()}var f=this,g=a.plot.plugins.length;if(this.plotPlugins=[],g)for(var h=0;g>h;h++)this.plotPlugins.push(a.plot.plugins[h].name);b.hooks.bindEvents.push(function(b,g){if(f.plotOptions=b.getOptions(),"boolean"==typeof f.plotOptions.tooltip&&(f.plotOptions.tooltipOpts.show=f.plotOptions.tooltip,f.plotOptions.tooltip=f.plotOptions.tooltipOpts,delete f.plotOptions.tooltipOpts),f.plotOptions.tooltip.show!==!1&&"undefined"!=typeof f.plotOptions.tooltip.show){f.tooltipOptions=f.plotOptions.tooltip,f.tooltipOptions.$compat?(f.wfunc="width",f.hfunc="height"):(f.wfunc="innerWidth",f.hfunc="innerHeight");f.getDomElement();a(b.getPlaceholder()).bind("plothover",e),f.tooltipOptions.clickTips&&a(b.getPlaceholder()).bind("plotclick",d),f.clickmode=!1,a(g).bind("mousemove",c)}}),b.hooks.shutdown.push(function(b,f){a(b.getPlaceholder()).unbind("plothover",e),a(b.getPlaceholder()).unbind("plotclick",d),b.removeTooltip(),a(f).unbind("mousemove",c)}),b.setTooltipPosition=function(b){var c=f.getDomElement(),d=c.outerWidth()+f.tooltipOptions.shifts.x,e=c.outerHeight()+f.tooltipOptions.shifts.y;b.x-a(window).scrollLeft()>a(window)[f.wfunc]()-d&&(b.x-=d),b.y-a(window).scrollTop()>a(window)[f.hfunc]()-e&&(b.y-=e),isNaN(b.x)?f.tipPosition.x=f.tipPosition.xPrev:(f.tipPosition.x=b.x,f.tipPosition.xPrev=b.x),isNaN(b.y)?f.tipPosition.y=f.tipPosition.yPrev:(f.tipPosition.y=b.y,f.tipPosition.yPrev=b.y)},b.showTooltip=function(a,c,d){var e=f.getDomElement(),g=f.stringFormat(f.tooltipOptions.content,a);""!==g&&(e.html(g),b.setTooltipPosition({x:c.pageX,y:c.pageY}),e.css({left:f.tipPosition.x+f.tooltipOptions.shifts.x,top:f.tipPosition.y+f.tooltipOptions.shifts.y}).show(),"function"==typeof f.tooltipOptions.onHover&&f.tooltipOptions.onHover(a,e))},b.hideTooltip=function(){f.getDomElement().hide().html("")},b.removeTooltip=function(){f.getDomElement().remove()}},c.prototype.getDomElement=function(){var b=a("."+this.tooltipOptions.cssClass);return 0===b.length&&(b=a("<div />").addClass(this.tooltipOptions.cssClass),b.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&b.css({background:"#fff","z-index":"1040",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),b},c.prototype.stringFormat=function(a,b){var c,d,e,f,g,h=/%p\.{0,1}(\d{0,})/,i=/%s/,j=/%c/,k=/%lx/,l=/%ly/,m=/%x\.{0,1}(\d{0,})/,n=/%y\.{0,1}(\d{0,})/,o="%x",p="%y",q="%ct",r="%n";if("undefined"!=typeof b.series.threshold?(c=b.datapoint[0],d=b.datapoint[1],e=b.datapoint[2]):"undefined"!=typeof b.series.curvedLines?(c=b.datapoint[0],d=b.datapoint[1]):"undefined"!=typeof b.series.lines&&b.series.lines.steps?(c=b.series.datapoints.points[2*b.dataIndex],d=b.series.datapoints.points[2*b.dataIndex+1],e=""):(c=b.series.data[b.dataIndex][0],d=b.series.data[b.dataIndex][1],e=b.series.data[b.dataIndex][2]),null===b.series.label&&b.series.originSeries&&(b.series.label=b.series.originSeries.label),"function"==typeof a&&(a=a(b.series.label,c,d,b)),"boolean"==typeof a&&!a)return"";if(e&&(a=a.replace(q,e)),"undefined"!=typeof b.series.percent?f=b.series.percent:"undefined"!=typeof b.series.percents&&(f=b.series.percents[b.dataIndex]),"number"==typeof f&&(a=this.adjustValPrecision(h,a,f)),b.series.hasOwnProperty("pie")&&(g=b.series.data[0][1]),"number"==typeof g&&(a=a.replace(r,g)),a="undefined"!=typeof b.series.label?a.replace(i,b.series.label):a.replace(i,""),a="undefined"!=typeof b.series.color?a.replace(j,b.series.color):a.replace(j,""),a=this.hasAxisLabel("xaxis",b)?a.replace(k,b.series.xaxis.options.axisLabel):a.replace(k,""),a=this.hasAxisLabel("yaxis",b)?a.replace(l,b.series.yaxis.options.axisLabel):a.replace(l,""),this.isTimeMode("xaxis",b)&&this.isXDateFormat(b)&&(a=a.replace(m,this.timestampToDate(c,this.tooltipOptions.xDateFormat,b.series.xaxis.options))),this.isTimeMode("yaxis",b)&&this.isYDateFormat(b)&&(a=a.replace(n,this.timestampToDate(d,this.tooltipOptions.yDateFormat,b.series.yaxis.options))),"number"==typeof c&&(a=this.adjustValPrecision(m,a,c)),"number"==typeof d&&(a=this.adjustValPrecision(n,a,d)),"undefined"!=typeof b.series.xaxis.ticks){var s;s=this.hasRotatedXAxisTicks(b)?"rotatedTicks":"ticks";var t=b.dataIndex+b.seriesIndex;for(var u in b.series.xaxis[s])if(b.series.xaxis[s].hasOwnProperty(t)&&!this.isTimeMode("xaxis",b)){var v=this.isCategoriesMode("xaxis",b)?b.series.xaxis[s][t].label:b.series.xaxis[s][t].v;v===c&&(a=a.replace(m,b.series.xaxis[s][t].label.replace(/\$/g,"$$$$")))}}if("undefined"!=typeof b.series.yaxis.ticks)for(var w in b.series.yaxis.ticks)if(b.series.yaxis.ticks.hasOwnProperty(w)){var x=this.isCategoriesMode("yaxis",b)?b.series.yaxis.ticks[w].label:b.series.yaxis.ticks[w].v;x===d&&(a=a.replace(n,b.series.yaxis.ticks[w].label.replace(/\$/g,"$$$$")))}return"undefined"!=typeof b.series.xaxis.tickFormatter&&(a=a.replace(o,b.series.xaxis.tickFormatter(c,b.series.xaxis).replace(/\$/g,"$$"))),"undefined"!=typeof b.series.yaxis.tickFormatter&&(a=a.replace(p,b.series.yaxis.tickFormatter(d,b.series.yaxis).replace(/\$/g,"$$"))),a},c.prototype.isTimeMode=function(a,b){return"undefined"!=typeof b.series[a].options.mode&&"time"===b.series[a].options.mode},c.prototype.isXDateFormat=function(a){return"undefined"!=typeof this.tooltipOptions.xDateFormat&&null!==this.tooltipOptions.xDateFormat},c.prototype.isYDateFormat=function(a){return"undefined"!=typeof this.tooltipOptions.yDateFormat&&null!==this.tooltipOptions.yDateFormat},c.prototype.isCategoriesMode=function(a,b){return"undefined"!=typeof b.series[a].options.mode&&"categories"===b.series[a].options.mode},c.prototype.timestampToDate=function(b,c,d){var e=a.plot.dateGenerator(b,d);return a.plot.formatDate(e,c,this.tooltipOptions.monthNames,this.tooltipOptions.dayNames)},c.prototype.adjustValPrecision=function(a,b,c){var d,e=b.match(a);return null!==e&&""!==RegExp.$1&&(d=RegExp.$1,c=c.toFixed(d),b=b.replace(a,c)),b},c.prototype.hasAxisLabel=function(b,c){return-1!==a.inArray("axisLabels",this.plotPlugins)&&"undefined"!=typeof c.series[b].options.axisLabel&&c.series[b].options.axisLabel.length>0},c.prototype.hasRotatedXAxisTicks=function(b){return-1!==a.inArray("tickRotor",this.plotPlugins)&&"undefined"!=typeof b.series.xaxis.rotatedTicks};var d=function(a){new c(a)};a.plot.plugins.push({init:d,options:b,name:"tooltip",version:"0.8.5"})}(jQuery);
@@ -10,6 +10,7 @@
10
10
  this.graphType = json.graphType || 'line';
11
11
  this.stackMode = json.stackMode || 'false';
12
12
  this.lineWidth = json.lineWidth || 1;
13
+ this.tooltips = json.tooltips || 'metric';
13
14
  this.timeRange = (json.timeRange * 1000) || 300000;
14
15
 
15
16
  this.font = {
@@ -82,7 +83,7 @@
82
83
 
83
84
  // Initialize Flot
84
85
  this.container.empty();
85
- this.graph = $.plot(this.container, this.data, {
86
+ var plotOptions = {
86
87
  legend: {
87
88
  position: "nw",
88
89
  backgroundOpacity: 0.7,
@@ -91,7 +92,7 @@
91
92
  borderWidth: 1,
92
93
  borderColor: "#aaa",
93
94
  color: "#444",
94
- backgroundColor: '#fff'
95
+ backgroundColor: '#fff',
95
96
  },
96
97
  yaxis: {
97
98
  font: this.font,
@@ -104,7 +105,36 @@
104
105
  min: t - this.timeRange,
105
106
  max: t
106
107
  }
107
- });
108
+ };
109
+
110
+ var tooltipCommon = {
111
+ grid: {
112
+ hoverable: true,
113
+ autoHighlight: true,
114
+ }
115
+ };
116
+
117
+ var tooltipOption = {
118
+ metric: {
119
+ tooltip: {
120
+ show: true,
121
+ content: "<b>%s</b><br />%x<br />%y",
122
+ }
123
+ },
124
+ simple: {
125
+ tooltip: {
126
+ show: true,
127
+ content: "<b>%s</b>",
128
+ }
129
+ }
130
+ };
131
+
132
+ if (this.tooltips != 'false') {
133
+ _.merge(plotOptions, tooltipCommon);
134
+ _.merge(plotOptions, tooltipOption[this.tooltips]);
135
+ }
136
+
137
+ this.graph = $.plot(this.container, this.data, plotOptions);
108
138
  };
109
139
 
110
140
  // Called as the clock advances to new times.
@@ -246,7 +276,8 @@
246
276
  max: this.max,
247
277
  timeRange: this.timeRange / 1000,
248
278
  graphType: this.graphType,
249
- stackMode: this.stackMode
279
+ stackMode: this.stackMode,
280
+ tooltips: this.tooltips,
250
281
  });
251
282
  };
252
283
 
@@ -263,7 +294,15 @@
263
294
  '<select name="stackMode">' +
264
295
  '<option value="true" {% if(stackMode == \'true\') print(\'selected\') %}>Stacked</option>' +
265
296
  '<option value="false" {% if(stackMode == \'false\') print(\'selected\') %}>Normal</option>' +
266
- '</select><br />' +
297
+ '</select>' +
298
+ '<br />' +
299
+ '<label for="tooltips">Tooltips</label>' +
300
+ '<select name="tooltips">' +
301
+ '<option value="metric" {% if(tooltips == \'metric\') print(\'selected\') %}>With metric</option>' +
302
+ '<option value="simple" {% if(tooltips == \'simple\') print(\'selected\') %}>Simple</option>' +
303
+ '<option value="false" {% if(tooltips == \'false\') print(\'selected\') %}>Disabled</option>' +
304
+ '</select>' +
305
+ '<br />' +
267
306
  '<label for="query">query</label>' +
268
307
  '<textarea type="text" class="query" name="query">{{ query }}</textarea><br />' +
269
308
  '<label for="timeRange">Time range (s)</label>' +
@@ -0,0 +1,151 @@
1
+ var GlobalAudioContext = new (window.AudioContext || window.webkitAudioContext)();
2
+
3
+ (function() {
4
+ var Geiger = function(json) {
5
+ // Init
6
+ view.View.call(this, json);
7
+
8
+ this.clickFocusable = true;
9
+ this.selfid = Math.floor(Math.random() * 255);
10
+
11
+ var self = this;
12
+
13
+ // Config
14
+ this.title = json.title;
15
+ this.query = json.query;
16
+ this.muted = json.muted || false;
17
+ this.volume = parseFloat(json.volume || 0.2);
18
+ this.sound = json.sound || 'sounds/geiger.wav';
19
+ this.muted = json.muted || false;
20
+
21
+ // State
22
+ this.currentEvent = null;
23
+ this.shouldPlay = false;
24
+ this.soundBuffer = null;
25
+
26
+ // HTML
27
+ this.el.append(
28
+ '<div class="box">' +
29
+ '<h2 class="quickfit"></h2>' +
30
+ '<button class="sound-mute" type="button">Mute</button><br />' +
31
+ '</div>'
32
+ );
33
+
34
+ this.box = this.el.find('.box');
35
+ this.el.find('h2').text(this.title);
36
+
37
+ this.mute_button = this.el.find('.sound-mute');
38
+ this.mute_button.text(this.muted ? 'Unmute' : 'Mute');
39
+ this.mute_button.click(function () {
40
+ self.muted = !self.muted;
41
+ self.mute_button.text(self.muted ? 'Unmute' : 'Mute');
42
+ });
43
+
44
+ if (!json.virtual) {
45
+ // Virtual instance of the geiger counter should not produce any sounds.
46
+ // Moreover, to save resources, I will not create audio nodes and will
47
+ // not load data.
48
+ this.gainer = GlobalAudioContext.createGain();
49
+
50
+ this.gainer.gain.value = Math.pow(this.volume, 2);
51
+ this.gainer.connect(GlobalAudioContext.destination);
52
+
53
+ this.compressor = GlobalAudioContext.createDynamicsCompressor();
54
+ this.compressor.threshold.value = 0;
55
+ this.compressor.knee.value = 0;
56
+ this.compressor.ratio.value = 20;
57
+ this.compressor.attack.value = 0;
58
+ this.compressor.release.value = 2;
59
+ this.compressor.connect(this.gainer);
60
+
61
+ this.request = new XMLHttpRequest();
62
+ this.request.open('GET', this.sound, true);
63
+ this.request.responseType = 'arraybuffer';
64
+
65
+ this.request.onload = function () {
66
+ if (this.status != 200) {
67
+ toastr.warning ("Could not load sound " + self.sound + ", HTTP status " + this.status);
68
+ }
69
+
70
+ GlobalAudioContext.decodeAudioData(this.response, function (buffer) {
71
+ self.soundBuffer = buffer;
72
+ self.shouldPlay = true;
73
+ });
74
+ };
75
+
76
+ this.request.onerror = function () {
77
+ toastr.warning ("Could not load sound " + self.sound + ", general error");
78
+ }
79
+
80
+ this.request.send();
81
+
82
+ if (this.query) {
83
+ var me = this;
84
+ this.sub = subs.subscribe(this.query, function(e) {
85
+ self.playSound();
86
+ self.currentEvent = e;
87
+ });
88
+ }
89
+ }
90
+ }
91
+
92
+ view.inherit(view.View, Geiger);
93
+ view.Geiger = Geiger;
94
+ view.types.Geiger = Geiger;
95
+
96
+ Geiger.prototype.json = function() {
97
+ return $.extend(view.View.prototype.json.call(this), {
98
+ type: 'Geiger',
99
+ title: this.title,
100
+ query: this.query,
101
+ volume: this.volume,
102
+ sound: this.sound,
103
+ muted: this.muted
104
+ });
105
+ }
106
+
107
+ Geiger.prototype.playSound = function() {
108
+ if (!this.shouldPlay || this.muted) {
109
+ return;
110
+ }
111
+
112
+ source = GlobalAudioContext.createBufferSource();
113
+ source.buffer = this.soundBuffer;
114
+ source.connect(this.compressor);
115
+ source.start();
116
+ }
117
+
118
+
119
+ var editTemplate = _.template(
120
+ "<label for='title'>Title</label>" +
121
+ "<input type='text' name='title' value='{{title}}' /><br />" +
122
+ "<label for='query'>Query</label>" +
123
+ '<textarea type="text" name="query" class="query">{{query}}</textarea>' +
124
+ "<label for='sound'>Sound</label>" +
125
+ "<input type='text' name='sound' value='{{sound}}' /><br />" +
126
+ "<label for='volume'>Volume</label>" +
127
+ "<input type='range' name='volume' min='0' max='1' step='0.05' value='{{volume}}' />" );
128
+
129
+ Geiger.prototype.editForm = function() {
130
+ return editTemplate(this);
131
+ }
132
+
133
+ Geiger.prototype.shutdownSound = function() {
134
+ this.shouldPlay = false;
135
+ this.gainer.disconnect();
136
+ this.compressor.disconnect();
137
+ this.gainer = null;
138
+ this.compressor = null;
139
+
140
+ this.soundBuffer = null;
141
+ }
142
+
143
+ Geiger.prototype.delete = function() {
144
+ if (this.sub) {
145
+ subs.unsubscribe(this.sub);
146
+ }
147
+
148
+ this.shutdownSound();
149
+ return view.View.prototype.delete.call(this);
150
+ }
151
+ })();
@@ -5,8 +5,9 @@
5
5
  this.el.addClass("help");
6
6
  this.el.append('<div class="box">' +
7
7
  "<p>Welcome to Riemann-Dash.</p>" +
8
- "<p>Need a refresher on the query language? See the <a href=\"https://github.com/aphyr/riemann/blob/master/test/riemann/query_test.clj\">query tests</a> for examples, or read the <a href=\"https://github.com/aphyr/riemann/blob/master/src/riemann/Query.g\">spec</a>.</p>" +
9
- "<p>Press <b>Control/Meta+click</b> to select a view. Escape unfocuses. Use the arrow keys to move a view. Use Control+arrow to <i>split</i> a view in the given direction.</p>" +
8
+ "<p>Need a refresher on the query language? See the <a href=\"https://github.com/riemann/riemann/blob/master/test/riemann/query_test.clj\">query tests</a> for examples, or read the <a href=\"https://github.com/riemann/riemann/blob/master/resources/query.g4\">spec</a>.</p>" +
9
+ "<p>Double-click a workspace to rename it.</p>" +
10
+ "<p>Press <b>Control/Meta+click</b> to select a view (<b>Option+Command+click</b> on a Mac). Escape unfocuses. Use the arrow keys to move a view. Use Control+arrow to <i>split</i> a view in the given direction.</p>" +
10
11
  "<p>To edit a view, hit e. Use enter, or click 'apply', to apply your changes. Escape cancels.</p>" +
11
12
  "<p>To save your changes to the server, press s. To display the configuration, press c.</p>" +
12
13
  "<p>You can refresh the page, or press r to reload.</p>" +
@@ -24,7 +24,7 @@
24
24
  this.log = this.el.find('tbody');
25
25
 
26
26
  // Line template
27
- this.lineTemplate = _.template("<tr><td>{{host}}</td><td>{{service}}</td><td>{{state}}</td><td>{{metric}}</td><td>{{description}}</td></tr>");
27
+ this.lineTemplate = _.template("<tr><td>{{-host}}</td><td>{{-service}}</td><td>{{-state}}</td><td>{{-metric}}</td><td>{{-description}}</td></tr>");
28
28
 
29
29
  // When scrolling occurs, toggle tracking state.
30
30
  this.scroll.scroll(function(e) {
@@ -1,4 +1,4 @@
1
1
  module Riemann; end
2
2
  module Riemann::Dash
3
- VERSION = '0.2.12'
3
+ VERSION = '0.2.13'
4
4
  end
@@ -45,7 +45,7 @@ html,table {
45
45
  }
46
46
 
47
47
  #toolbar {
48
- height: 28px;
48
+ height: auto;
49
49
  overflow: hidden;
50
50
  position: absolute;
51
51
  top: 3px;
@@ -5,6 +5,8 @@
5
5
  <title>riemann</title>
6
6
  <link rel="stylesheet" type="text/css" href="vendor/toastr/toastr.css" />
7
7
  <link rel="stylesheet" type="text/css" href="css" />
8
+ <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
9
+ <link rel="icon" href="/favicon.ico" type="image/x-icon">
8
10
  </head>
9
11
  <body>
10
12
  <div id="toolbar"></div>
@@ -25,6 +27,7 @@
25
27
  <script src="vendor/flot/jquery.flot.canvas.min.js"></script>
26
28
  <script src="vendor/flot/jquery.flot.time.min.js"></script>
27
29
  <script src="vendor/flot/jquery.flot.stack.min.js"></script>
30
+ <script src="vendor/flot/jquery.flot.tooltip.min.js"></script>
28
31
  <script src="vendor/PriorityQueue.js"></script>
29
32
  <script src="vendor/gauge.min.js"></script>
30
33
  <script src="vendor/jquery.gauge.js"></script>
@@ -55,6 +58,7 @@
55
58
  <script src="views/list.js"></script>
56
59
  <script src="views/help.js"></script>
57
60
  <script src="views/gauge.js"></script>
61
+ <script src="views/geiger.js"></script>
58
62
  <script src="views/dial.js"></script>
59
63
  <script src="views/grid.js"></script>
60
64
  <script src="views/iframe.js"></script>
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.email = ['aphyr@aphyr.com']
13
13
  gem.description = %q{HTTP dashboard for the distributed event system Riemann.}
14
14
  gem.summary = gem.description
15
- gem.homepage = 'https://github.com/aphyr/riemann-dash'
15
+ gem.homepage = 'https://github.com/riemann/riemann-dash'
16
16
  gem.platform = Gem::Platform::RUBY
17
17
 
18
18
  gem.add_dependency 'erubis', '>= 2.7.0'
metadata CHANGED
@@ -1,84 +1,74 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riemann-dash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.12
5
- prerelease:
4
+ version: 0.2.13
6
5
  platform: ruby
7
6
  authors:
8
7
  - Kyle Kingsbury
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-07-17 00:00:00.000000000 Z
11
+ date: 2016-06-26 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: erubis
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: 2.7.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 2.7.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: sinatra
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: 1.4.5
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: 1.4.5
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: sass
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: 3.1.14
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: 3.1.14
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: webrick
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ~>
59
+ - - "~>"
68
60
  - !ruby/object:Gem::Version
69
61
  version: 1.3.1
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ~>
66
+ - - "~>"
76
67
  - !ruby/object:Gem::Version
77
68
  version: 1.3.1
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: multi_json
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - '='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :runtime
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - '='
92
81
  - !ruby/object:Gem::Version
@@ -99,7 +88,7 @@ executables:
99
88
  extensions: []
100
89
  extra_rdoc_files: []
101
90
  files:
102
- - .gitignore
91
+ - ".gitignore"
103
92
  - Gemfile
104
93
  - Gemfile.lock
105
94
  - LICENSE
@@ -119,10 +108,13 @@ files:
119
108
  - lib/riemann/dash/public/clock.js
120
109
  - lib/riemann/dash/public/dash.js
121
110
  - lib/riemann/dash/public/eventPane.js
111
+ - lib/riemann/dash/public/favicon.ico
122
112
  - lib/riemann/dash/public/format.js
123
113
  - lib/riemann/dash/public/keys.js
124
114
  - lib/riemann/dash/public/persistence.js
125
115
  - lib/riemann/dash/public/profile.js
116
+ - lib/riemann/dash/public/sounds/beep.wav
117
+ - lib/riemann/dash/public/sounds/geiger.wav
126
118
  - lib/riemann/dash/public/strings.js
127
119
  - lib/riemann/dash/public/subs.js
128
120
  - lib/riemann/dash/public/toolbar.js
@@ -161,6 +153,8 @@ files:
161
153
  - lib/riemann/dash/public/vendor/flot/jquery.flot.threshold.min.js
162
154
  - lib/riemann/dash/public/vendor/flot/jquery.flot.time.js
163
155
  - lib/riemann/dash/public/vendor/flot/jquery.flot.time.min.js
156
+ - lib/riemann/dash/public/vendor/flot/jquery.flot.tooltip.js
157
+ - lib/riemann/dash/public/vendor/flot/jquery.flot.tooltip.min.js
164
158
  - lib/riemann/dash/public/vendor/gauge.min.js
165
159
  - lib/riemann/dash/public/vendor/jquery.gauge.js
166
160
  - lib/riemann/dash/public/vendor/jquery/jquery-1.9.1.min.js
@@ -176,6 +170,7 @@ files:
176
170
  - lib/riemann/dash/public/views/dial.js
177
171
  - lib/riemann/dash/public/views/flot.js
178
172
  - lib/riemann/dash/public/views/gauge.js
173
+ - lib/riemann/dash/public/views/geiger.js
179
174
  - lib/riemann/dash/public/views/grid.js
180
175
  - lib/riemann/dash/public/views/help.js
181
176
  - lib/riemann/dash/public/views/iframe.js
@@ -200,29 +195,28 @@ files:
200
195
  - test/fixtures/ws_config/dummy_config.json
201
196
  - test/fixtures/ws_config/pretty_printed_config.json
202
197
  - test/test_helper.rb
203
- homepage: https://github.com/aphyr/riemann-dash
198
+ homepage: https://github.com/riemann/riemann-dash
204
199
  licenses: []
200
+ metadata: {}
205
201
  post_install_message:
206
202
  rdoc_options: []
207
203
  require_paths:
208
204
  - lib
209
205
  required_ruby_version: !ruby/object:Gem::Requirement
210
- none: false
211
206
  requirements:
212
- - - ! '>='
207
+ - - ">="
213
208
  - !ruby/object:Gem::Version
214
209
  version: '0'
215
210
  required_rubygems_version: !ruby/object:Gem::Requirement
216
- none: false
217
211
  requirements:
218
- - - ! '>='
212
+ - - ">="
219
213
  - !ruby/object:Gem::Version
220
214
  version: '0'
221
215
  requirements: []
222
216
  rubyforge_project: riemann-dash
223
- rubygems_version: 1.8.25
217
+ rubygems_version: 2.4.5
224
218
  signing_key:
225
- specification_version: 3
219
+ specification_version: 4
226
220
  summary: HTTP dashboard for the distributed event system Riemann.
227
221
  test_files:
228
222
  - test/browser_config_test.rb