fnordmetric 0.7.5 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/V1.0-ROADMAP +97 -0
- data/doc/full_example.rb +95 -511
- data/doc/legacy_example.rb +640 -0
- data/doc/minimal_example.rb +26 -0
- data/doc/preview3.png +0 -0
- data/fnordmetric.gemspec +3 -2
- data/lib/fnordmetric/acceptors/acceptor.rb +29 -0
- data/lib/fnordmetric/{inbound_stream.rb → acceptors/tcp_acceptor.rb} +8 -5
- data/lib/fnordmetric/{inbound_datagram.rb → acceptors/udp_acceptor.rb} +9 -8
- data/lib/fnordmetric/api.rb +2 -2
- data/lib/fnordmetric/context.rb +37 -18
- data/lib/fnordmetric/defaults.rb +9 -0
- data/lib/fnordmetric/ext.rb +72 -0
- data/lib/fnordmetric/gauge.rb +37 -10
- data/lib/fnordmetric/gauge_calculations.rb +38 -16
- data/lib/fnordmetric/gauge_modifiers.rb +67 -0
- data/lib/fnordmetric/gauge_rendering.rb +40 -0
- data/lib/fnordmetric/gauge_validations.rb +15 -0
- data/lib/fnordmetric/gauges/distribution_gauge.rb +85 -0
- data/lib/fnordmetric/gauges/timeseries_gauge.rb +143 -0
- data/lib/fnordmetric/gauges/toplist_gauge.rb +44 -0
- data/lib/fnordmetric/histogram.rb +57 -0
- data/lib/fnordmetric/logger.rb +42 -36
- data/lib/fnordmetric/namespace.rb +47 -23
- data/lib/fnordmetric/session.rb +6 -6
- data/lib/fnordmetric/standalone.rb +15 -35
- data/lib/fnordmetric/timeseries.rb +79 -0
- data/lib/fnordmetric/toplist.rb +61 -0
- data/lib/fnordmetric/version.rb +1 -1
- data/lib/fnordmetric/web/app.rb +122 -0
- data/lib/fnordmetric/web/app_helpers.rb +42 -0
- data/lib/fnordmetric/{dashboard.rb → web/dashboard.rb} +4 -0
- data/lib/fnordmetric/{event.rb → web/event.rb} +7 -2
- data/lib/fnordmetric/web/reactor.rb +87 -0
- data/lib/fnordmetric/web/web.rb +53 -0
- data/lib/fnordmetric/web/websocket.rb +38 -0
- data/lib/fnordmetric/widgets/bars_widget.rb +44 -0
- data/lib/fnordmetric/{html_widget.rb → widgets/html_widget.rb} +0 -0
- data/lib/fnordmetric/widgets/numbers_widget.rb +56 -0
- data/lib/fnordmetric/{pie_widget.rb → widgets/pie_widget.rb} +0 -0
- data/lib/fnordmetric/widgets/timeseries_widget.rb +55 -0
- data/lib/fnordmetric/widgets/toplist_widget.rb +64 -0
- data/lib/fnordmetric/worker.rb +26 -25
- data/lib/fnordmetric.rb +85 -115
- data/readme.md +362 -0
- data/spec/gauge_like_shared.rb +54 -0
- data/spec/gauge_spec.rb +2 -36
- data/spec/namespace_spec.rb +25 -11
- data/spec/spec_helper.rb +4 -0
- data/spec/{inbound_stream_spec.rb → tcp_acceptor_spec.rb} +3 -3
- data/spec/timeseries_gauge_spec.rb +54 -0
- data/spec/{inbound_datagram_spec.rb → udp_acceptor_spec.rb} +3 -3
- data/web/fnordmetric.css +786 -0
- data/web/haml/app.haml +38 -0
- data/web/haml/distribution_gauge.haml +118 -0
- data/web/haml/timeseries_gauge.haml +80 -0
- data/web/haml/toplist_gauge.haml +194 -0
- data/web/img/head.png +0 -0
- data/web/img/list.png +0 -0
- data/web/img/list_active.png +0 -0
- data/web/img/list_hover.png +0 -0
- data/web/img/loader_white.gif +0 -0
- data/web/img/navbar.png +0 -0
- data/web/img/navbar_btn.png +0 -0
- data/web/img/picto_gauge.png +0 -0
- data/web/js/fnordmetric.bars_widget.js +178 -0
- data/web/js/fnordmetric.dashboard_view.js +99 -0
- data/web/js/fnordmetric.gauge_view.js +260 -0
- data/web/js/fnordmetric.html_widget.js +21 -0
- data/web/js/fnordmetric.js +255 -0
- data/web/js/fnordmetric.numbers_widget.js +121 -0
- data/web/js/fnordmetric.overview_view.js +35 -0
- data/web/js/fnordmetric.pie_widget.js +118 -0
- data/web/js/fnordmetric.realtime_timeline_widget.js +175 -0
- data/web/js/fnordmetric.session_view.js +343 -0
- data/web/js/fnordmetric.timeline_widget.js +333 -0
- data/web/js/fnordmetric.timeseries_widget.js +388 -0
- data/web/js/fnordmetric.toplist_widget.js +112 -0
- data/web/js/fnordmetric.ui.js +91 -0
- data/web/js/fnordmetric.util.js +244 -0
- data/{pub → web}/loader.gif +0 -0
- data/web/vendor/d3.v2.js +9382 -0
- data/web/vendor/font-awesome/css/font-awesome.css +239 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.eot +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.svg +175 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.svgz +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.ttf +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.woff +0 -0
- data/web/vendor/jquery-1.6.2.min.js +18 -0
- data/web/vendor/jquery-ui.min.js +413 -0
- data/web/vendor/jquery.maskedinput.js +252 -0
- data/web/vendor/rickshaw.css +286 -0
- data/web/vendor/rickshaw.fnordmetric.js +2676 -0
- metadata +129 -79
- data/Gemfile +0 -6
- data/README.md +0 -404
- data/Rakefile +0 -6
- data/doc/version +0 -1
- data/haml/app.haml +0 -79
- data/haml/widget.haml +0 -9
- data/lib/fnordmetric/app.rb +0 -163
- data/lib/fnordmetric/average_metric.rb +0 -7
- data/lib/fnordmetric/bars_widget.rb +0 -26
- data/lib/fnordmetric/combine_metric.rb +0 -7
- data/lib/fnordmetric/count_metric.rb +0 -13
- data/lib/fnordmetric/funnel_widget.rb +0 -2
- data/lib/fnordmetric/metric.rb +0 -80
- data/lib/fnordmetric/metric_api.rb +0 -37
- data/lib/fnordmetric/numbers_widget.rb +0 -26
- data/lib/fnordmetric/report.rb +0 -29
- data/lib/fnordmetric/sum_metric.rb +0 -13
- data/lib/fnordmetric/timeline_widget.rb +0 -30
- data/lib/fnordmetric/toplist_widget.rb +0 -25
- data/pub/fnordmetric.css +0 -145
- data/pub/fnordmetric.js +0 -1179
- data/pub/vendor/highcharts.js +0 -170
- data/pub/vendor/jquery-1.6.1.min.js +0 -18
@@ -0,0 +1,388 @@
|
|
1
|
+
FnordMetric.widgets.timeseriesWidget = function(){
|
2
|
+
|
3
|
+
/*
|
4
|
+
options:
|
5
|
+
|
6
|
+
height: 430
|
7
|
+
default_cardinal: true/false
|
8
|
+
default_style: line/area/stack/flow
|
9
|
+
series
|
10
|
+
*/
|
11
|
+
|
12
|
+
var widget_uid = "fnord-" + parseInt(Math.random()*99990000);
|
13
|
+
var width, height, opts, graph, gconfig, legend, hoverDetail, shelving, highlighter, resolution;
|
14
|
+
|
15
|
+
var cardinal = true;
|
16
|
+
var xticks = 30;
|
17
|
+
|
18
|
+
function render(_opts){
|
19
|
+
opts = _opts;
|
20
|
+
|
21
|
+
if(opts.default_style == "areaspline"){ opts.default_style = 'area'; }
|
22
|
+
if(!opts.default_style){ opts.default_style = 'line'; }
|
23
|
+
if(!opts.default_cardinal){ opts.default_cardinal = true; }
|
24
|
+
|
25
|
+
draw_layout();
|
26
|
+
|
27
|
+
gconfig = {
|
28
|
+
element: $('.container', opts.elem)[0],
|
29
|
+
interpolation: (opts.default_cardinal ? 'cardinal' : 'linear'),
|
30
|
+
stroke: true,
|
31
|
+
series: opts.series,
|
32
|
+
padding: { top: 0.1, bottom: 0 }
|
33
|
+
}
|
34
|
+
|
35
|
+
$(opts.elem)
|
36
|
+
.addClass('resize_listener')
|
37
|
+
.bind('fm_resize', renderChart);
|
38
|
+
|
39
|
+
apply_style(opts.default_style);
|
40
|
+
|
41
|
+
if(opts.async_chart){
|
42
|
+
updateChart();
|
43
|
+
} else {
|
44
|
+
renderChart();
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
function toggle_cardinal(){
|
49
|
+
if($(this).hasClass('active')){ return false; }
|
50
|
+
$(this).addClass('active').siblings().removeClass('active');
|
51
|
+
|
52
|
+
if(cardinal === true){
|
53
|
+
cardinal = false;
|
54
|
+
gconfig.interpolation = 'linear';
|
55
|
+
} else {
|
56
|
+
cardinal = true;
|
57
|
+
gconfig.interpolation = 'cardinal';
|
58
|
+
}
|
59
|
+
|
60
|
+
graph.configure(gconfig);
|
61
|
+
graph.render();
|
62
|
+
}
|
63
|
+
|
64
|
+
function change_style(){
|
65
|
+
$(this).addClass('active').siblings().removeClass('active');
|
66
|
+
|
67
|
+
apply_style($(this).attr('data'));
|
68
|
+
//graph.configure(gconfig);
|
69
|
+
//graph.render();
|
70
|
+
|
71
|
+
renderChart();
|
72
|
+
}
|
73
|
+
|
74
|
+
function apply_style(style){
|
75
|
+
if(style == 'line'){
|
76
|
+
gconfig.renderer = 'line';
|
77
|
+
gconfig.offset = 'zero';
|
78
|
+
}
|
79
|
+
|
80
|
+
if(style == 'area'){
|
81
|
+
gconfig.renderer = 'area';
|
82
|
+
gconfig.offset = 'zero';
|
83
|
+
}
|
84
|
+
|
85
|
+
if(style == 'flow'){
|
86
|
+
gconfig.renderer = 'stack';
|
87
|
+
gconfig.offset = 'silhouette';
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
function apply_resolution(){
|
92
|
+
if(!resolution){
|
93
|
+
var trgt_resolution = 50;
|
94
|
+
var best_resolution = false;
|
95
|
+
|
96
|
+
for(ind in opts.series_resolutions){
|
97
|
+
var _diff = Math.abs(
|
98
|
+
trgt_resolution -
|
99
|
+
(opts.timespan / opts.series_resolutions[ind])
|
100
|
+
);
|
101
|
+
|
102
|
+
if((!best_resolution) || (_diff < best_resolution)){
|
103
|
+
best_resolution = opts.series_resolutions[ind];
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
resolution = best_resolution;
|
108
|
+
}
|
109
|
+
|
110
|
+
for(ind in gconfig.series){
|
111
|
+
gconfig.series[ind].data = gconfig.series[ind]["data"+resolution];
|
112
|
+
}
|
113
|
+
|
114
|
+
$('.button.tick', opts.elem)
|
115
|
+
.removeClass('active')
|
116
|
+
.filter('[data-tick="'+resolution+'"]')
|
117
|
+
.addClass('active');
|
118
|
+
}
|
119
|
+
|
120
|
+
function draw_layout(){
|
121
|
+
if(!opts.no_headbar){
|
122
|
+
$(opts.elem).append(
|
123
|
+
$('<div></div>')
|
124
|
+
.addClass('headbar')
|
125
|
+
.append($('<h2></h2>').html(opts.title))
|
126
|
+
.append(
|
127
|
+
$('<div class="btn_group mr"></div>')
|
128
|
+
.append(
|
129
|
+
$('<div></div>')
|
130
|
+
.addClass('button')
|
131
|
+
.append($('<span>').html('Flow'))
|
132
|
+
.attr('data', 'flow')
|
133
|
+
.click(change_style)
|
134
|
+
)
|
135
|
+
.append(
|
136
|
+
$('<div></div>')
|
137
|
+
.addClass('button')
|
138
|
+
.append($('<span>').html('Area'))
|
139
|
+
.attr('data', 'area')
|
140
|
+
.click(change_style)
|
141
|
+
)
|
142
|
+
.append(
|
143
|
+
$('<div></div>')
|
144
|
+
.addClass('button')
|
145
|
+
.append($('<span>').html('Line'))
|
146
|
+
.attr('data', 'line')
|
147
|
+
.click(change_style)
|
148
|
+
)
|
149
|
+
)
|
150
|
+
.append(
|
151
|
+
$('<div class="btn_group mr"></div>')
|
152
|
+
.append(
|
153
|
+
$('<div></div>')
|
154
|
+
.addClass('button mr')
|
155
|
+
.addClass(opts.default_cardinal ? '' : 'active')
|
156
|
+
.append($('<span>').html('Off'))
|
157
|
+
.attr('data', 'cardinal-off')
|
158
|
+
.click(toggle_cardinal)
|
159
|
+
)
|
160
|
+
.append(
|
161
|
+
$('<div></div>')
|
162
|
+
.addClass('button ml')
|
163
|
+
.addClass(opts.default_cardinal ? 'active' : '')
|
164
|
+
.append($('<span>').html('On'))
|
165
|
+
.attr('data', 'cardinal-on')
|
166
|
+
.click(toggle_cardinal)
|
167
|
+
)
|
168
|
+
)
|
169
|
+
)
|
170
|
+
}
|
171
|
+
|
172
|
+
$(opts.elem)
|
173
|
+
.append(
|
174
|
+
$('<div></div>')
|
175
|
+
.addClass('legend')
|
176
|
+
.css({
|
177
|
+
margin: '10px 30px 0 30px',
|
178
|
+
})
|
179
|
+
)
|
180
|
+
.append(
|
181
|
+
$('<div></div>')
|
182
|
+
.addClass('container')
|
183
|
+
.css({
|
184
|
+
height: opts.height,
|
185
|
+
margin: '0 23px 25px 23px',
|
186
|
+
})
|
187
|
+
);
|
188
|
+
|
189
|
+
if(opts.async_chart){
|
190
|
+
$('.headbar', opts.elem).prepend(
|
191
|
+
$('<div></div>')
|
192
|
+
.addClass('button ml')
|
193
|
+
.append($('<span></span>').html('←'))
|
194
|
+
.click(function(){ moveRange(-1); })
|
195
|
+
).prepend(
|
196
|
+
$('<div></div>')
|
197
|
+
.addClass('datepicker')
|
198
|
+
).prepend(
|
199
|
+
$('<div></div>')
|
200
|
+
.addClass('button')
|
201
|
+
.append($('<span></span>').html('→'))
|
202
|
+
.click(function(){ moveRange(1); })
|
203
|
+
).prepend(
|
204
|
+
$('<div class="refresh_btn"></div>')
|
205
|
+
.addClass('button ml')
|
206
|
+
.append($('<span></span>').html('refresh'))
|
207
|
+
.click(function(){ requestValuesAsync(); })
|
208
|
+
);
|
209
|
+
}
|
210
|
+
|
211
|
+
if(opts.series_resolutions){
|
212
|
+
$('.headbar', opts.elem).append('<div class="tick_btns btn_group"></div>');
|
213
|
+
for(ind in opts.series_resolutions){
|
214
|
+
var _tick = opts.series_resolutions[ind];
|
215
|
+
$('.tick_btns', opts.elem).append(
|
216
|
+
$('<div></div>').attr('class', 'button tick').append($('<span></span>')
|
217
|
+
.html(FnordMetric.util.formatTimeRange(_tick)))
|
218
|
+
.attr('data-tick', _tick)
|
219
|
+
.click(function(){
|
220
|
+
resolution = $(this).attr('data-tick');
|
221
|
+
renderChart();
|
222
|
+
})
|
223
|
+
);
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
if((opts.autoupdate) && (opts.async_chart)){
|
228
|
+
var secs = parseInt(opts.autoupdate);
|
229
|
+
if(secs > 0){
|
230
|
+
var autoupdate_interval = window.setInterval(function(){
|
231
|
+
updateChart(false, true);
|
232
|
+
}, secs*1000);
|
233
|
+
|
234
|
+
$('body').bind('fm_dashboard_close', function(){
|
235
|
+
window.clearInterval(autoupdate_interval);
|
236
|
+
});
|
237
|
+
}
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
function renderChart(){
|
242
|
+
width = opts.elem.width() - 50;
|
243
|
+
height = opts.height || 240;
|
244
|
+
|
245
|
+
gconfig.width = width;
|
246
|
+
gconfig.height = height;
|
247
|
+
|
248
|
+
$(gconfig.element).html("");
|
249
|
+
$(".rickshaw_legend", opts.elem).html("");
|
250
|
+
|
251
|
+
if(opts.series_resolutions){
|
252
|
+
apply_resolution();
|
253
|
+
}
|
254
|
+
|
255
|
+
graph = new Rickshaw.Graph(gconfig);
|
256
|
+
|
257
|
+
legend = new Rickshaw.Graph.Legend({
|
258
|
+
graph: graph,
|
259
|
+
element: $('.legend', opts.elem)[0]
|
260
|
+
});
|
261
|
+
|
262
|
+
hoverDetail = new Rickshaw.Graph.HoverDetail( {
|
263
|
+
graph: graph
|
264
|
+
});
|
265
|
+
|
266
|
+
shelving = new Rickshaw.Graph.Behavior.Series.Toggle({
|
267
|
+
graph: graph,
|
268
|
+
legend: legend
|
269
|
+
});
|
270
|
+
|
271
|
+
highlighter = new Rickshaw.Graph.Behavior.Series.Highlight({
|
272
|
+
graph: graph,
|
273
|
+
legend: legend
|
274
|
+
});
|
275
|
+
|
276
|
+
new Rickshaw.Graph.Axis.Time({
|
277
|
+
graph: graph,
|
278
|
+
}).render();
|
279
|
+
|
280
|
+
new Rickshaw.Graph.Axis.Y({
|
281
|
+
graph: graph,
|
282
|
+
}).render();
|
283
|
+
|
284
|
+
if(!gconfig.renderer){
|
285
|
+
gconfig.renderer = "line";
|
286
|
+
}
|
287
|
+
|
288
|
+
graph.configure(gconfig);
|
289
|
+
graph.render();
|
290
|
+
}
|
291
|
+
|
292
|
+
|
293
|
+
function announce(evt){
|
294
|
+
if(evt.widget_key == opts.widget_key){
|
295
|
+
if((evt.class == "widget_response") && (evt.cmd == "values_at")){
|
296
|
+
running_request = false;
|
297
|
+
$(opts.elem).css('opacity', 1);
|
298
|
+
updateSeriesData(evt.gauges);
|
299
|
+
}
|
300
|
+
}
|
301
|
+
}
|
302
|
+
|
303
|
+
function requestValuesAsync(){
|
304
|
+
FnordMetric.publish({
|
305
|
+
"type": "widget_request",
|
306
|
+
"klass": "TimeseriesWidget",
|
307
|
+
"gauges": opts.gauges,
|
308
|
+
"cmd": "values_at",
|
309
|
+
"tick": opts.tick,
|
310
|
+
"since": opts.start_timestamp,
|
311
|
+
"until": opts.end_timestamp,
|
312
|
+
"widget_key": opts.widget_key
|
313
|
+
})
|
314
|
+
}
|
315
|
+
|
316
|
+
function updateSeriesData(dgauges){
|
317
|
+
gconfig.series = [];
|
318
|
+
|
319
|
+
for(var ind = 0; ind < dgauges.length; ind++){
|
320
|
+
|
321
|
+
gconfig.series.push({
|
322
|
+
name: dgauges[ind].key,
|
323
|
+
color: opts.series[ind].color,
|
324
|
+
data: []
|
325
|
+
});
|
326
|
+
|
327
|
+
for(_time in dgauges[ind].vals){
|
328
|
+
gconfig.series[ind].data.push(
|
329
|
+
{ x: parseInt(_time), y: parseInt(dgauges[ind].vals[_time] || 0) }
|
330
|
+
);
|
331
|
+
}
|
332
|
+
|
333
|
+
}
|
334
|
+
|
335
|
+
renderChart();
|
336
|
+
}
|
337
|
+
|
338
|
+
function updateChart(first_time, silent){
|
339
|
+
if(!silent){ $(opts.elem).css('opacity', 0.5); }
|
340
|
+
updateRange();
|
341
|
+
redrawDatepicker();
|
342
|
+
requestValuesAsync();
|
343
|
+
}
|
344
|
+
|
345
|
+
function redrawDatepicker(){
|
346
|
+
$('.datepicker', opts.elem).html(
|
347
|
+
FnordMetric.util.dateFormat(opts.start_timestamp) +
|
348
|
+
' ‐ ' +
|
349
|
+
FnordMetric.util.dateFormat(opts.end_timestamp)
|
350
|
+
);
|
351
|
+
}
|
352
|
+
|
353
|
+
function updateRange(force){
|
354
|
+
if(!opts.tick){
|
355
|
+
opts.tick = opts.ticks[0];
|
356
|
+
}
|
357
|
+
|
358
|
+
var _now = parseInt(new Date().getTime() / 1000);
|
359
|
+
|
360
|
+
if((opts.autoupdate) &&
|
361
|
+
((_now - opts.end_timestamp) < ((opts.tick*(opts.autoupdate+1)) + 5))){
|
362
|
+
force = true;
|
363
|
+
}
|
364
|
+
|
365
|
+
if(!opts.start_timestamp || !opts.end_timestamp || !!force){
|
366
|
+
opts.end_timestamp = _now + opts.tick;
|
367
|
+
opts.start_timestamp = opts.end_timestamp - (opts.tick * xticks);
|
368
|
+
}
|
369
|
+
}
|
370
|
+
|
371
|
+
function moveRange(direction){
|
372
|
+
v = opts.tick*direction*8;
|
373
|
+
|
374
|
+
if(((opts.end_timestamp + v)*1000) < new Date().getTime()){
|
375
|
+
opts.start_timestamp += v;
|
376
|
+
opts.end_timestamp += v;
|
377
|
+
}
|
378
|
+
|
379
|
+
redrawDatepicker();
|
380
|
+
requestValuesAsync();
|
381
|
+
}
|
382
|
+
|
383
|
+
return {
|
384
|
+
render: render,
|
385
|
+
announce: announce
|
386
|
+
}
|
387
|
+
|
388
|
+
};
|
@@ -0,0 +1,112 @@
|
|
1
|
+
FnordMetric.widgets.toplistWidget = function(){
|
2
|
+
|
3
|
+
var opts;
|
4
|
+
var current_gauge = false;
|
5
|
+
|
6
|
+
function render(_opts){
|
7
|
+
opts = _opts;
|
8
|
+
|
9
|
+
var headbar = $('<div class="headbar"></div>').append(
|
10
|
+
$('<h2></h2>').html(opts.title)
|
11
|
+
);
|
12
|
+
|
13
|
+
opts.elem.append(headbar).css({
|
14
|
+
'marginBottom': 20,
|
15
|
+
'overflow': 'hidden'
|
16
|
+
}).append(
|
17
|
+
$('<div class="toplist_inner ui_toplist"></div>')
|
18
|
+
);
|
19
|
+
|
20
|
+
if(!opts.ticks){
|
21
|
+
var first = true;
|
22
|
+
for(k in opts.gauges){
|
23
|
+
headbar.append(
|
24
|
+
$('<div></div>')
|
25
|
+
.attr('class', 'button mr')
|
26
|
+
.attr('rel', k)
|
27
|
+
.append(
|
28
|
+
$('<span></span>').html(opts.gauges[k].title)
|
29
|
+
).click(function(){
|
30
|
+
loadGauge($(this).attr('rel'));
|
31
|
+
}
|
32
|
+
)
|
33
|
+
);
|
34
|
+
if(first){
|
35
|
+
first = false;
|
36
|
+
loadGauge(k);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
} else {
|
40
|
+
loadGauge(opts.gauges[0], true);
|
41
|
+
}
|
42
|
+
|
43
|
+
if(opts.autoupdate){
|
44
|
+
var secs = parseInt(opts.autoupdate);
|
45
|
+
if(secs > 0){
|
46
|
+
|
47
|
+
var autoupdate_interval = window.setInterval(function(){
|
48
|
+
loadGauge(false, true);
|
49
|
+
}, secs*1000);
|
50
|
+
|
51
|
+
$('body').bind('fm_dashboard_close', function(){
|
52
|
+
window.clearInterval(autoupdate_interval);
|
53
|
+
});
|
54
|
+
}
|
55
|
+
};
|
56
|
+
|
57
|
+
}
|
58
|
+
|
59
|
+
function loadGauge(gkey, silent){
|
60
|
+
if(!gkey)
|
61
|
+
gkey = current_gauge;
|
62
|
+
|
63
|
+
current_gauge = gkey;
|
64
|
+
|
65
|
+
if(!silent)
|
66
|
+
$('.toplist_inner', opts.elem).addClass('loading');
|
67
|
+
|
68
|
+
FnordMetric.publish({
|
69
|
+
"type": "widget_request",
|
70
|
+
"klass": "ToplistWidget",
|
71
|
+
"gauge": current_gauge,
|
72
|
+
"cmd": "values_for",
|
73
|
+
"tick": opts.tick,
|
74
|
+
"widget_key": opts.widget_key
|
75
|
+
});
|
76
|
+
}
|
77
|
+
|
78
|
+
function renderGauge(gkey, gdata){
|
79
|
+
var _elem = $('.toplist_inner', opts.elem).removeClass('loading').html('');
|
80
|
+
$(gdata.values).each(function(n, _gd){
|
81
|
+
var _perc = (parseInt(gdata.values[n][1]) / parseFloat(gdata.count))*100;
|
82
|
+
var _item = $('<div class="toplist_item"><div class="title"></div><div class="value"></div><div class="percent"></div></div>');
|
83
|
+
|
84
|
+
if(opts.click_callback){
|
85
|
+
var lelem = $('<a href="#" class="link">').html(gdata.values[n][0]);
|
86
|
+
var lclbck; eval("lclbck="+opts.click_callback)
|
87
|
+
lelem.attr('data-key', gdata.values[n][0]);
|
88
|
+
lelem.click(function(){ lclbck($(this).attr('data-key')); return false; });
|
89
|
+
$('.title', _item).html(lelem)
|
90
|
+
} else {
|
91
|
+
$('.title', _item).html(gdata.values[n][0]);
|
92
|
+
}
|
93
|
+
|
94
|
+
$('.value', _item).html(FnordMetric.util.formatGaugeValue(gkey, parseInt(gdata.values[n][1])));
|
95
|
+
$('.percent', _item).html(_perc.toFixed(1) + '%');
|
96
|
+
_elem.append(_item);
|
97
|
+
});
|
98
|
+
}
|
99
|
+
|
100
|
+
function announce(evt){
|
101
|
+
|
102
|
+
if((evt.widget_key == opts.widget_key) && ((evt.class == "widget_response") && (evt.cmd == "values_for")))
|
103
|
+
renderGauge(evt.gauge, evt);
|
104
|
+
|
105
|
+
}
|
106
|
+
|
107
|
+
return {
|
108
|
+
render: render,
|
109
|
+
announce: announce
|
110
|
+
};
|
111
|
+
|
112
|
+
};
|
@@ -0,0 +1,91 @@
|
|
1
|
+
FnordMetric.ui.navbar = function(elem, opts){
|
2
|
+
|
3
|
+
elem.css('width', $('#viewport').width());
|
4
|
+
|
5
|
+
var back = $('<a>')
|
6
|
+
.addClass('button back')
|
7
|
+
.html('«');
|
8
|
+
|
9
|
+
elem.prepend(back);
|
10
|
+
|
11
|
+
var head = $('<h1></h1>');
|
12
|
+
for(ind in opts.breadcrumb){
|
13
|
+
var cur = $('<a>').html(opts.breadcrumb[ind][0]);
|
14
|
+
if (ind == (opts.breadcrumb.length - 1)){
|
15
|
+
cur.addClass('current');
|
16
|
+
} else {
|
17
|
+
cur.append(' / ');
|
18
|
+
}
|
19
|
+
head.append(cur);
|
20
|
+
};
|
21
|
+
|
22
|
+
for(ind in opts.buttons){
|
23
|
+
var btn = $('<a>')
|
24
|
+
.addClass('button navbutton')
|
25
|
+
.click(opts.buttons[ind][1])
|
26
|
+
.html(opts.buttons[ind][0]);
|
27
|
+
elem.prepend(btn);
|
28
|
+
}
|
29
|
+
|
30
|
+
if(opts.datepicker){
|
31
|
+
elem.append(
|
32
|
+
$('<a class="button datepicker">')
|
33
|
+
.html('<div class="date"> </div><i class="icon-calendar"></i>'));
|
34
|
+
}
|
35
|
+
|
36
|
+
elem.append(head);
|
37
|
+
}
|
38
|
+
|
39
|
+
FnordMetric.ui.modal = function(opts){
|
40
|
+
FnordMetric.ui.close_modal('body');
|
41
|
+
width = $("#viewport").width() * 0.8;
|
42
|
+
|
43
|
+
if (opts.max_width)
|
44
|
+
width = Math.min(opts.max_width, width);
|
45
|
+
|
46
|
+
var dialog_elem = $('<div class="modal">')
|
47
|
+
.append($('<div class="modal_inner">'))
|
48
|
+
.css({
|
49
|
+
"width": width,
|
50
|
+
"height": opts.height,
|
51
|
+
"marginLeft": (($("#viewport").width() - width) / 2),
|
52
|
+
"display": "none"
|
53
|
+
});
|
54
|
+
|
55
|
+
|
56
|
+
if (opts.max_width)
|
57
|
+
dialog_elem.css('maxWidth', opts.max_width);
|
58
|
+
|
59
|
+
if (opts.content)
|
60
|
+
dialog_elem.html(opts.content);
|
61
|
+
|
62
|
+
$("#viewport").append(dialog_elem);
|
63
|
+
dialog_elem.show().addClass('visible');
|
64
|
+
$('.modal_backdrop').show().addClass('visible');
|
65
|
+
}
|
66
|
+
|
67
|
+
FnordMetric.ui.close_modal = function(elem){
|
68
|
+
var m = $('.modal', $(elem));
|
69
|
+
m.push($(elem).closest('.modal'));
|
70
|
+
|
71
|
+
m.removeClass('visible');
|
72
|
+
|
73
|
+
window.setTimeout(function(){
|
74
|
+
m.remove();
|
75
|
+
}, 500);
|
76
|
+
|
77
|
+
$('.modal_backdrop').removeClass('visible').fadeOut();
|
78
|
+
}
|
79
|
+
|
80
|
+
FnordMetric.ui.resizable = function(elem){
|
81
|
+
$('.resizable', $(elem)).each(function(){
|
82
|
+
var wwperc = parseInt($(this).attr('data-width'));
|
83
|
+
if (!wwperc || (wwperc < 1)){ wwperc = 100; }
|
84
|
+
var wwidth = $('.viewport_inner').width() * (wwperc/100.0);
|
85
|
+
if(wwperc==100){ $(this).addClass('full_width'); }
|
86
|
+
else if($(this).hasClass('right')) { $(this).css('float', 'right'); }
|
87
|
+
else { wwidth -= 1; $(this).css('float', 'left'); }
|
88
|
+
$(this).css('overflow', 'hidden');
|
89
|
+
$(this).width(wwidth);
|
90
|
+
});
|
91
|
+
}
|