fnordmetric 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.travis.yml +1 -0
  2. data/VERSION +1 -1
  3. data/doc/preview1.png +0 -0
  4. data/doc/preview2.png +0 -0
  5. data/doc/ulm_stats.rb +622 -0
  6. data/doc/version +1 -0
  7. data/fnordmetric.gemspec +16 -38
  8. data/haml/app.haml +12 -5
  9. data/lib/fnordmetric.rb +3 -0
  10. data/lib/fnordmetric/app.rb +19 -10
  11. data/lib/fnordmetric/bars_widget.rb +26 -0
  12. data/lib/fnordmetric/context.rb +3 -3
  13. data/lib/fnordmetric/gauge.rb +20 -0
  14. data/lib/fnordmetric/gauge_calculations.rb +28 -4
  15. data/lib/fnordmetric/gauge_modifiers.rb +39 -6
  16. data/lib/fnordmetric/logger.rb +19 -0
  17. data/lib/fnordmetric/numbers_widget.rb +5 -15
  18. data/lib/fnordmetric/pie_widget.rb +23 -0
  19. data/lib/fnordmetric/standalone.rb +1 -1
  20. data/lib/fnordmetric/timeline_widget.rb +16 -23
  21. data/lib/fnordmetric/toplist_widget.rb +25 -0
  22. data/lib/fnordmetric/widget.rb +3 -3
  23. data/pub/{fnordmetric/fnordmetric.css → fnordmetric.css} +46 -36
  24. data/pub/fnordmetric.js +1069 -0
  25. data/pub/loader.gif +0 -0
  26. data/pub/{highcharts → vendor}/highcharts.js +0 -0
  27. data/pub/{jquery-1.6.1.min.js → vendor/jquery-1.6.1.min.js} +0 -0
  28. data/readme.rdoc +228 -311
  29. data/spec/app_spec.rb +63 -3
  30. data/spec/gauge_modifiers_spec.rb +157 -2
  31. data/spec/gauge_spec.rb +143 -12
  32. data/spec/widget_spec.rb +18 -18
  33. metadata +33 -58
  34. data/.document +0 -5
  35. data/_spec/app_spec.rb +0 -178
  36. data/_spec/cache_spec.rb +0 -53
  37. data/_spec/combine_metric_spec.rb +0 -19
  38. data/_spec/core_spec.rb +0 -50
  39. data/_spec/count_metric_spec.rb +0 -32
  40. data/_spec/dashboard_spec.rb +0 -67
  41. data/_spec/event_spec.rb +0 -46
  42. data/_spec/metric_spec.rb +0 -118
  43. data/_spec/report_spec.rb +0 -87
  44. data/_spec/sum_metric_spec.rb +0 -33
  45. data/_spec/widget_spec.rb +0 -107
  46. data/doc/example_server.rb +0 -56
  47. data/doc/import_dump.rb +0 -26
  48. data/pub/fnordmetric/fnordmetric.js +0 -543
  49. data/pub/fnordmetric/widget_numbers.js +0 -71
  50. data/pub/fnordmetric/widget_timeline.css +0 -0
  51. data/pub/fnordmetric/widget_timeline.js +0 -110
  52. data/pub/highcharts/adapters/mootools-adapter.js +0 -12
  53. data/pub/highcharts/adapters/mootools-adapter.src.js +0 -243
  54. data/pub/highcharts/adapters/prototype-adapter.js +0 -14
  55. data/pub/highcharts/adapters/prototype-adapter.src.js +0 -284
  56. data/pub/highcharts/highcharts.src.js +0 -11103
  57. data/pub/highcharts/modules/exporting.js +0 -22
  58. data/pub/highcharts/modules/exporting.src.js +0 -703
  59. data/pub/highcharts/themes/dark-blue.js +0 -268
  60. data/pub/highcharts/themes/dark-green.js +0 -268
  61. data/pub/highcharts/themes/gray.js +0 -262
  62. data/pub/highcharts/themes/grid.js +0 -97
  63. data/pub/raphael-min.js +0 -8
  64. data/pub/raphael-utils.js +0 -221
  65. data/ulm_stats.rb +0 -198
@@ -1,71 +0,0 @@
1
- FnordMetric.css('/fnordmetric/fnordmetric.css', function(){});
2
- FnordMetric.js('/jquery-1.6.1.min.js', function(){
3
-
4
- drawLayout();
5
- updateDataAndValues();
6
-
7
- window.setInterval(updateDataAndValues, 5000);
8
-
9
- function drawLayout(){
10
- for(n in widget_config.metrics){
11
- $('body').append(container=$('<div></div>').attr('class', 'numbers_container').attr('rel', widget_config.metrics[n]));
12
- container.append($('<div></div>').addClass('title').html(widget_config.metrics[n]));
13
- for(var k in widget_config.intervals){
14
- container.append($('<div></div>').addClass('number').attr('rel', k).attr('data',0).append(
15
- $('<span></span>').addClass('value').html(0)
16
- ).append(
17
- $('<span></span>').addClass('desc').html(k)
18
- ));
19
- }
20
- }
21
- }
22
-
23
- function updateDataAndValues(){
24
- for(n in widget_config.metrics){
25
- for(k in widget_config.intervals){
26
- var _url = FnordMetric.p+'/metric/'+widget_config.metrics[n]+'?'+widget_config.intervals[k];
27
- $.get(_url, updateSingleNumber(widget_config.metrics[n], k));
28
- }
29
- }
30
- }
31
-
32
- function updateSingleNumber(metric_name, interval_name){
33
- return function(json){
34
- var _elem = $('.number[rel="'+interval_name+'"]', $('.numbers_container[rel="'+metric_name+'"]'));
35
- _elem.attr('data', json.value);
36
- updateValues(4);
37
- };
38
- }
39
-
40
- function formatValue(value){
41
- if(value < 10){ return value.toFixed(2); }
42
- if(value > 1000){ return (value/1000.0).toFixed(1) + "k"; }
43
- return value.toFixed(0);
44
- }
45
-
46
- function updateValues(diff_factor){
47
- var still_running = false;
48
- $('.number').each(function(){
49
- var target_val = parseFloat($(this).attr('data'));
50
- var current_val = parseFloat($(this).attr('data-current'));
51
- if(!current_val){ current_val=0; }
52
- var diff = (target_val-current_val)/diff_factor;
53
- if(diff < 1){ diff=1; }
54
- if(target_val > current_val){
55
- still_running = true;
56
- var new_val = current_val+diff;
57
- if(new_val > target_val){ new_val = target_val; }
58
- $(this).attr('data-current', new_val);
59
- $('.value', this).html(formatValue(new_val));
60
- }
61
- });
62
- if(still_running){
63
- (function(df){
64
- window.setTimeout(function(){ updateValues(df); }, 30);
65
- })(diff_factor);
66
- }
67
- }
68
-
69
-
70
-
71
- });
File without changes
@@ -1,110 +0,0 @@
1
- FnordMetric.js('/jquery-1.6.1.min.js', function(){
2
- FnordMetric.js('/highcharts/highcharts.js', function(){
3
- FnordMetric.css('/fnordmetric/fnordmetric.css', function(){});
4
- FnordMetric.css('/fnordmetric/widget_timeline.css', function(){});
5
-
6
-
7
- drawLayout();
8
- chart = new Highcharts.Chart({
9
- chart: { renderTo: 'container', defaultSeriesType: widget_config.chart_type, height: 270 },
10
- series: [],
11
- title: { text: '' },
12
- xAxis: {
13
- type: 'datetime',
14
- tickInterval: widget_config.tick * 1000,
15
- title: (widget_config.x_title||''),
16
- labels: { step: 2 }
17
- },
18
- yAxis: {
19
- title: (widget_config.y_title||''),
20
- maxPadding: 0
21
- },
22
- legend: {
23
- layout: 'horizontal',
24
- align: 'top',
25
- verticalAlign: 'top',
26
- x: -5,
27
- y: -3,
28
- margin: 25,
29
- borderWidth: 0
30
- },
31
- });
32
- redrawWithRange(true);
33
-
34
- if(widget_config.autoupdate){
35
- window.setInterval(function(){
36
- redrawWithRange(false, true);
37
- }, 3000);
38
- }
39
-
40
- function redrawWithRange(first_time, silent){
41
- if(!silent){ $("#container").css('opacity', 0.5); }
42
- redrawDatepicker();
43
- var _query = '?at='+widget_config.start_timestamp+'-'+widget_config.end_timestamp+
44
- '&tick='+widget_config.tick+(widget_config.delta ? '&delta=1' : '');
45
- chart.series = [];
46
- metrics_completed = 0;
47
- for(n in widget_config.metrics){
48
- $.ajax({
49
- url: FnordMetric.p+'/metric/'+widget_config.metrics[n]+_query,
50
- success: redrawMetric(first_time, n)
51
- });
52
- }
53
- }
54
-
55
- function redrawMetric(first_time, n){
56
- return (function(json){
57
- for(i in json.values){ json.values[i][0] = json.values[i][0]*1000; }
58
- if(!first_time){
59
- chart.get('series-'+n).setData(json.values);
60
- } else {
61
- chart.addSeries({name: widget_config.metrics[n], data: json.values, id: 'series-'+n });
62
- }
63
- if((metrics_completed += 1) == widget_config.metrics.length){
64
- $("#container").css('opacity', 1);
65
- }
66
- });
67
- }
68
-
69
- function redrawDatepicker(){
70
- $('.datepicker').html(
71
- Highcharts.dateFormat('%d.%m.%y %H:%M', parseInt(widget_config.start_timestamp)*1000) +
72
- '&nbsp;&dash;&nbsp;' +
73
- Highcharts.dateFormat('%d.%m.%y %H:%M', parseInt(widget_config.end_timestamp)*1000)
74
- );
75
- }
76
-
77
- function moveRange(direction){
78
- v = widget_config.tick*direction*8;
79
- widget_config.start_timestamp += v;
80
- widget_config.end_timestamp += v;
81
- redrawWithRange();
82
- }
83
-
84
- function drawLayout(){
85
- $('body').append( $('<div></div>').attr('class', 'headbar').append(
86
- $('<div></div>').attr('class', 'button mr').append($('<span></span>').html('refresh')).click(
87
- function(){ redrawWithRange(); }
88
- )
89
- ).append(
90
- // $('<div></div>').attr('class', 'button').append($('<span></span>').html('1h'))
91
- //).append(
92
- // $('<div></div>').attr('class', 'button').append($('<span></span>').html('1d'))
93
- //).append(
94
- $('<div></div>').attr('class', 'button mr').append($('<span></span>').html('&rarr;')).click(
95
- function(){ moveRange(1); }
96
- )
97
- ).append(
98
- $('<div></div>').attr('class', 'datepicker')
99
- ).append(
100
- $('<div></div>').attr('class', 'button').append($('<span></span>').html('&larr;')).click(
101
- function(){ moveRange(-1); }
102
- )
103
- ).append(
104
- $('<h2></h2>').html(widget_config.title)
105
- ) );
106
- $('body').append( $('<div></div>').attr('id', 'container') );
107
- }
108
-
109
- });
110
- });
@@ -1,12 +0,0 @@
1
- /*
2
- Highcharts JS v2.1.6 (2011-07-08)
3
- MooTools adapter
4
-
5
- (c) 2010-2011 Torstein H?nsi
6
-
7
- License: www.highcharts.com/license
8
- */
9
- (function(){var g=window,j=!!g.$merge,h=g.$extend||function(){return Object.append.apply(Object,arguments)};g.HighchartsAdapter={init:function(){var a=Fx.prototype,b=a.start,c=Fx.Morph.prototype,d=c.compute;a.start=function(f){var e=this.element;if(f.d)this.paths=Highcharts.pathAnim.init(e,e.d,this.toD);b.apply(this,arguments);return this};c.compute=function(f,e,k){var i=this.paths;if(i)this.element.attr("d",Highcharts.pathAnim.step(i[0],i[1],k,this.toD));else return d.apply(this,arguments)}},animate:function(a,
10
- b,c){var d=a.attr,f=c&&c.complete;if(d&&!a.setStyle){a.getStyle=a.attr;a.setStyle=function(){var e=arguments;a.attr.call(a,e[0],e[1][0])};a.$family=a.uid=true}HighchartsAdapter.stop(a);c=new Fx.Morph(d?a:$(a),h({transition:Fx.Transitions.Quad.easeInOut},c));if(b.d)c.toD=b.d;f&&c.addEvent("complete",f);c.start(b);a.fx=c},each:function(a,b){return j?$each(a,b):a.each(b)},map:function(a,b){return a.map(b)},grep:function(a,b){return a.filter(b)},merge:function(){var a=arguments,b=[{}],c=a.length;if(j)a=
11
- $merge.apply(null,a);else{for(;c--;)b[c+1]=a[c];a=Object.merge.apply(Object,b)}return a},addEvent:function(a,b,c){if(typeof b=="string"){if(b=="unload")b="beforeunload";if(!a.addEvent)if(a.nodeName)a=$(a);else h(a,new Events);a.addEvent(b,c)}},removeEvent:function(a,b,c){if(b){if(b=="unload")b="beforeunload";defined(c)?a.removeEvent(b,c):a.removeEvents(b)}else a.removeEvents()},fireEvent:function(a,b,c,d){b=new Event({type:b,target:a});b=h(b,c);b.preventDefault=function(){d=null};a.fireEvent&&a.fireEvent(b.type,
12
- b);d&&d(b)},stop:function(a){a.fx&&a.fx.cancel()}}})();
@@ -1,243 +0,0 @@
1
- /**
2
- * @license Highcharts JS v2.1.6 (2011-07-08)
3
- * MooTools adapter
4
- *
5
- * (c) 2010-2011 Torstein Hønsi
6
- *
7
- * License: www.highcharts.com/license
8
- */
9
-
10
- // JSLint options:
11
- /*global Highcharts, Fx, $, $extend, $each, $merge, Events, Event */
12
-
13
- (function() {
14
-
15
- var win = window,
16
- legacy = !!win.$merge,
17
- $extend = win.$extend || function() {
18
- return Object.append.apply(Object, arguments)
19
- };
20
-
21
- win.HighchartsAdapter = {
22
- /**
23
- * Initialize the adapter. This is run once as Highcharts is first run.
24
- */
25
- init: function() {
26
- var fxProto = Fx.prototype,
27
- fxStart = fxProto.start,
28
- morphProto = Fx.Morph.prototype,
29
- morphCompute = morphProto.compute;
30
-
31
- // override Fx.start to allow animation of SVG element wrappers
32
- fxProto.start = function(from, to) {
33
- var fx = this,
34
- elem = fx.element;
35
-
36
- // special for animating paths
37
- if (from.d) {
38
- //this.fromD = this.element.d.split(' ');
39
- fx.paths = Highcharts.pathAnim.init(
40
- elem,
41
- elem.d,
42
- fx.toD
43
- );
44
- }
45
- fxStart.apply(fx, arguments);
46
-
47
- return this; // chainable
48
- };
49
-
50
- // override Fx.step to allow animation of SVG element wrappers
51
- morphProto.compute = function(from, to, delta) {
52
- var fx = this,
53
- paths = fx.paths;
54
-
55
- if (paths) {
56
- fx.element.attr(
57
- 'd',
58
- Highcharts.pathAnim.step(paths[0], paths[1], delta, fx.toD)
59
- );
60
- } else {
61
- return morphCompute.apply(fx, arguments);
62
- }
63
- };
64
-
65
- },
66
-
67
- /**
68
- * Animate a HTML element or SVG element wrapper
69
- * @param {Object} el
70
- * @param {Object} params
71
- * @param {Object} options jQuery-like animation options: duration, easing, callback
72
- */
73
- animate: function (el, params, options) {
74
- var isSVGElement = el.attr,
75
- effect,
76
- complete = options && options.complete;
77
-
78
- if (isSVGElement && !el.setStyle) {
79
- // add setStyle and getStyle methods for internal use in Moo
80
- el.getStyle = el.attr;
81
- el.setStyle = function() { // property value is given as array in Moo - break it down
82
- var args = arguments;
83
- el.attr.call(el, args[0], args[1][0]);
84
- }
85
- // dirty hack to trick Moo into handling el as an element wrapper
86
- el.$family = el.uid = true;
87
- }
88
-
89
- // stop running animations
90
- HighchartsAdapter.stop(el);
91
-
92
- // define and run the effect
93
- effect = new Fx.Morph(
94
- isSVGElement ? el : $(el),
95
- $extend({
96
- transition: Fx.Transitions.Quad.easeInOut
97
- }, options)
98
- );
99
-
100
- // special treatment for paths
101
- if (params.d) {
102
- effect.toD = params.d;
103
- }
104
-
105
- // jQuery-like events
106
- if (complete) {
107
- effect.addEvent('complete', complete);
108
- }
109
-
110
- // run
111
- effect.start(params);
112
-
113
- // record for use in stop method
114
- el.fx = effect;
115
- },
116
-
117
- /**
118
- * MooTool's each function
119
- *
120
- */
121
- each: function(arr, fn) {
122
- return legacy ?
123
- $each(arr, fn) :
124
- arr.each(fn);
125
- },
126
-
127
- /**
128
- * Map an array
129
- * @param {Array} arr
130
- * @param {Function} fn
131
- */
132
- map: function (arr, fn){
133
- return arr.map(fn);
134
- },
135
-
136
- /**
137
- * Grep or filter an array
138
- * @param {Array} arr
139
- * @param {Function} fn
140
- */
141
- grep: function(arr, fn) {
142
- return arr.filter(fn);
143
- },
144
-
145
- /**
146
- * Deep merge two objects and return a third
147
- */
148
- merge: function() {
149
- var args = arguments,
150
- args13 = [{}], // MooTools 1.3+
151
- i = args.length,
152
- ret;
153
-
154
- if (legacy) {
155
- ret = $merge.apply(null, args);
156
- } else {
157
- while (i--) {
158
- args13[i + 1] = args[i];
159
- }
160
- ret = Object.merge.apply(Object, args13);
161
- }
162
-
163
- return ret;
164
- },
165
-
166
- /**
167
- * Add an event listener
168
- * @param {Object} el HTML element or custom object
169
- * @param {String} type Event type
170
- * @param {Function} fn Event handler
171
- */
172
- addEvent: function (el, type, fn) {
173
- if (typeof type == 'string') { // chart broke due to el being string, type function
174
-
175
- if (type == 'unload') { // Moo self destructs before custom unload events
176
- type = 'beforeunload';
177
- }
178
-
179
- // if the addEvent method is not defined, el is a custom Highcharts object
180
- // like series or point
181
- if (!el.addEvent) {
182
- if (el.nodeName) {
183
- el = $(el); // a dynamically generated node
184
- } else {
185
- $extend(el, new Events()); // a custom object
186
- }
187
- }
188
-
189
- el.addEvent(type, fn);
190
- }
191
- },
192
-
193
- removeEvent: function(el, type, fn) {
194
- if (type) {
195
- if (type == 'unload') { // Moo self destructs before custom unload events
196
- type = 'beforeunload';
197
- }
198
-
199
- if (defined(fn)) {
200
- el.removeEvent(type, fn);
201
- } else {
202
- el.removeEvents(type);
203
- }
204
- } else {
205
- el.removeEvents();
206
- }
207
- },
208
-
209
- fireEvent: function(el, event, eventArguments, defaultFunction) {
210
- // create an event object that keeps all functions
211
- event = new Event({
212
- type: event,
213
- target: el
214
- });
215
- event = $extend(event, eventArguments);
216
- // override the preventDefault function to be able to use
217
- // this for custom events
218
- event.preventDefault = function() {
219
- defaultFunction = null;
220
- };
221
- // if fireEvent is not available on the object, there hasn't been added
222
- // any events to it above
223
- if (el.fireEvent) {
224
- el.fireEvent(event.type, event);
225
- }
226
-
227
- // fire the default if it is passed and it is not prevented above
228
- if (defaultFunction) {
229
- defaultFunction(event);
230
- }
231
- },
232
-
233
- /**
234
- * Stop running animations on the object
235
- */
236
- stop: function (el) {
237
- if (el.fx) {
238
- el.fx.cancel();
239
- }
240
- }
241
- }
242
-
243
- })();
@@ -1,14 +0,0 @@
1
- /*
2
- Highcharts JS v2.1.6 (2011-07-08)
3
- Prototype adapter
4
-
5
- @author Michael Nelson, Torstein H?nsi.
6
-
7
- Feel free to use and modify this script.
8
- Highcharts license: www.highcharts.com/license.
9
- */
10
- var HighchartsAdapter=function(){var f=typeof Effect!="undefined";return{init:function(){if(f)Effect.HighchartsTransition=Class.create(Effect.Base,{initialize:function(b,a,c,d){var e;this.element=b;e=b.attr(a);if(a=="d"){this.paths=Highcharts.pathAnim.init(b,b.d,c);this.toD=c;e=0;c=1}this.start(Object.extend(d||{},{from:e,to:c,attribute:a}))},setup:function(){HighchartsAdapter._extend(this.element);this.element._highchart_animation=this},update:function(b){var a=this.paths;if(a)b=Highcharts.pathAnim.step(a[0],
11
- a[1],b,this.toD);this.element.attr(this.options.attribute,b)},finish:function(){this.element._highchart_animation=null}})},addEvent:function(b,a,c){if(b.addEventListener||b.attachEvent)Event.observe($(b),a,c);else{HighchartsAdapter._extend(b);b._highcharts_observe(a,c)}},animate:function(b,a,c){var d;c=c||{};c.delay=0;c.duration=(c.duration||500)/1E3;if(f)for(d in a)new Effect.HighchartsTransition($(b),d,a[d],c);else for(d in a)b.attr(d,a[d]);if(!b.attr)throw"Todo: implement animate DOM objects";
12
- },stop:function(b){b._highcharts_extended&&b._highchart_animation&&b._highchart_animation.cancel()},each:function(b,a){$A(b).each(a)},fireEvent:function(b,a,c,d){if(a.preventDefault)d=null;if(b.fire)b.fire(a,c);else b._highcharts_extended&&b._highcharts_fire(a,c);d&&d(c)},removeEvent:function(b,a,c){if($(b).stopObserving)$(b).stopObserving(a,c);else{HighchartsAdapter._extend(b);b._highcharts_stop_observing(a,c)}},grep:function(b,a){return b.findAll(a)},map:function(b,a){return b.map(a)},merge:function(){function b(a,
13
- c){var d,e;for(e in c){d=c[e];a[e]=d&&typeof d=="object"&&d.constructor!=Array&&typeof d.nodeType!=="number"?b(a[e]||{},d):c[e]}return a}return function(){for(var a=arguments,c={},d=0;d<a.length;d++)c=b(c,a[d]);return c}.apply(this,arguments)},_extend:function(b){b._highcharts_extended||Object.extend(b,{_highchart_events:{},_highchart_animation:null,_highcharts_extended:true,_highcharts_observe:function(a,c){this._highchart_events[a]=[this._highchart_events[a],c].compact().flatten()},_highcharts_stop_observing:function(a,
14
- c){if(a)if(c)this._highchart_events[a]=[this._highchart_events[a]].compact().flatten().without(c);else delete this._highchart_events[a];else this._highchart_events={}},_highcharts_fire:function(a,c){(this._highchart_events[a]||[]).each(function(d){c&&c.stopped||d.bind(this)(c)}.bind(this))}})}}}();