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
data/web/haml/app.haml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title FnordMetric
|
5
|
+
%script{:src => "/vendor/jquery-1.6.2.min.js", :type => "text/javascript"}
|
6
|
+
%script{:src => "/vendor/jquery-ui.min.js", :type => "text/javascript"}
|
7
|
+
%script{:src => "/vendor/jquery.maskedinput.js", :type => "text/javascript"}
|
8
|
+
%script{:src => "/vendor/d3.v2.js", :type => "text/javascript"}
|
9
|
+
%script{:src => "/vendor/rickshaw.fnordmetric.js", :type => "text/javascript"}
|
10
|
+
%script{:src => "/js/fnordmetric.js", :type => "text/javascript"}
|
11
|
+
%script{:src => "/js/fnordmetric.util.js", :type => "text/javascript"}
|
12
|
+
%script{:src => "/js/fnordmetric.ui.js", :type => "text/javascript"}
|
13
|
+
%script{:src => "/js/fnordmetric.timeline_widget.js", :type => "text/javascript"}
|
14
|
+
%script{:src => "/js/fnordmetric.numbers_widget.js", :type => "text/javascript"}
|
15
|
+
%script{:src => "/js/fnordmetric.bars_widget.js", :type => "text/javascript"}
|
16
|
+
%script{:src => "/js/fnordmetric.pie_widget.js", :type => "text/javascript"}
|
17
|
+
%script{:src => "/js/fnordmetric.toplist_widget.js", :type => "text/javascript"}
|
18
|
+
%script{:src => "/js/fnordmetric.html_widget.js", :type => "text/javascript"}
|
19
|
+
%script{:src => "/js/fnordmetric.realtime_value_widget.js", :type => "text/javascript"}
|
20
|
+
%script{:src => "/js/fnordmetric.timeseries_widget.js", :type => "text/javascript"}
|
21
|
+
%script{:src => "/js/fnordmetric.overview_view.js", :type => "text/javascript"}
|
22
|
+
%script{:src => "/js/fnordmetric.gauge_view.js", :type => "text/javascript"}
|
23
|
+
%script{:src => "/js/fnordmetric.dashboard_view.js", :type => "text/javascript"}
|
24
|
+
%script{:src => "/js/fnordmetric.session_view.js", :type => "text/javascript"}
|
25
|
+
%link{:href => "/vendor/rickshaw.css", :rel => "stylesheet", :type => "text/css"}
|
26
|
+
%link{:href => "/vendor/font-awesome/css/font-awesome.css", :rel => "stylesheet", :type => "text/css"}
|
27
|
+
%link{:href => "/fnordmetric.css", :rel => "stylesheet", :type => "text/css"}
|
28
|
+
|
29
|
+
%body
|
30
|
+
#app.clearfix(style="overflow:hidden;")
|
31
|
+
|
32
|
+
#preload
|
33
|
+
%img(src="/img/loader_white.gif")
|
34
|
+
|
35
|
+
:javascript
|
36
|
+
$(document).ready(function(){
|
37
|
+
FnordMetric.init(#{current_namespace.to_json});
|
38
|
+
});
|
@@ -0,0 +1,118 @@
|
|
1
|
+
.report_view
|
2
|
+
|
3
|
+
%ul.ui_numbers(style="float:right;")
|
4
|
+
%li
|
5
|
+
.val
|
6
|
+
%span.ui_value(data-value="#{@samples}")
|
7
|
+
.title Number of Samples
|
8
|
+
%li
|
9
|
+
.val
|
10
|
+
%span.ui_value(data-value="#{@values.mean}")
|
11
|
+
.title Total Value Mean
|
12
|
+
%li
|
13
|
+
.val
|
14
|
+
%span.ui_value(data-value="#{@values.median}")
|
15
|
+
.title Total Value Median
|
16
|
+
%li.twoline
|
17
|
+
.title Time Range
|
18
|
+
.val= (fancy_timerange(@interval) * " - ")
|
19
|
+
|
20
|
+
|
21
|
+
%h1= @opts[:title]
|
22
|
+
%h3 Numeric Distribution Gauge
|
23
|
+
|
24
|
+
%ul.ui_tabs.tabs
|
25
|
+
%li.active{"data-tab" => "Overview"}
|
26
|
+
%a{:href => "#"} Overview
|
27
|
+
/ %li{"data-tab" => "Overview"}
|
28
|
+
/ %a{:href => "#"} Histograms
|
29
|
+
/ %li{"data-tab" => "Export"}
|
30
|
+
/ %a{:href => "#"} Export
|
31
|
+
|
32
|
+
|
33
|
+
.headbar
|
34
|
+
%h2 Histogram: #{@opts[:title]}
|
35
|
+
|
36
|
+
.widget_histogram_bars
|
37
|
+
%br
|
38
|
+
|
39
|
+
|
40
|
+
.resizable.right.resize_min_full_height(data-width="40" style="border-left:1px solid #ddd;")
|
41
|
+
.headbar.small Standard Deviation
|
42
|
+
|
43
|
+
.resizable(data-width="60")
|
44
|
+
|
45
|
+
.clearfix
|
46
|
+
.headbar.small Value Distribution
|
47
|
+
.numbers_container.resizable.numbers_pad_bottom(data-width="50")
|
48
|
+
.number
|
49
|
+
%span.desc Mean (Avg.)
|
50
|
+
%span.value.ui_value{:"data-value" => @values.mean }
|
51
|
+
.number
|
52
|
+
%span.desc Minimum
|
53
|
+
%span.value.ui_value{:"data-value" => @values.min }
|
54
|
+
.number
|
55
|
+
%span.desc Maximum
|
56
|
+
%span.value.ui_value{:"data-value" => @values.max }
|
57
|
+
.number
|
58
|
+
%span.desc Median
|
59
|
+
%span.value.ui_value{:"data-value" => @values.median }
|
60
|
+
/ .number
|
61
|
+
/ %span.desc Trend
|
62
|
+
/ %span.value
|
63
|
+
/ .ui_trend{:"data-trend" => (@mmm_timeseries_arr[0][-1][:avg].mean / (@mmm_timeseries_arr[-1][-1][:avg].mean - @mmm_timeseries_arr[0][-1][:avg].mean) rescue 0) }
|
64
|
+
.number
|
65
|
+
%span.desc Range
|
66
|
+
%span.value.ui_value{:"data-value" => @values.range }
|
67
|
+
.number
|
68
|
+
%span.desc Mode
|
69
|
+
%span.value.ui_value{:"data-value" => @values.mode }
|
70
|
+
|
71
|
+
|
72
|
+
.headbar
|
73
|
+
%h2 Mean, Min and Max over Time
|
74
|
+
.widget_mmm_timeseries
|
75
|
+
|
76
|
+
|
77
|
+
:gaugejs
|
78
|
+
|
79
|
+
FnordMetric.ui.resizable('.report_view');
|
80
|
+
FnordMetric.util.format('.report_view');
|
81
|
+
|
82
|
+
FnordMetric.widgets.barsWidget().render({
|
83
|
+
title: "Histogram: Number of #{key_nouns.last}",
|
84
|
+
color: "#{FnordMetric::COLORS.last}",
|
85
|
+
elem: $('.widget_histogram_bars'),
|
86
|
+
height: 320,
|
87
|
+
no_headbar: true,
|
88
|
+
values: #{@histogram.json_histogram(@histogram_mode)}
|
89
|
+
});
|
90
|
+
|
91
|
+
|
92
|
+
FnordMetric.widgets.timeseriesWidget().render({
|
93
|
+
title: "#{key_nouns.last}",
|
94
|
+
elem: $('.widget_mmm_timeseries'),
|
95
|
+
height: 260,
|
96
|
+
no_headbar: true,
|
97
|
+
default_style: 'line',
|
98
|
+
series_resolutions: #{@zooms.to_json},
|
99
|
+
series: [
|
100
|
+
{
|
101
|
+
name: 'Max',
|
102
|
+
color: "#{FnordMetric::COLORS[-1]}",
|
103
|
+
data: #{@mmm_timeseries_arr.map{|t,v| {:x=>t.to_i,:y=>v[:max]} }.to_json}
|
104
|
+
},
|
105
|
+
{
|
106
|
+
name: 'Min',
|
107
|
+
color: "#{FnordMetric::COLORS[-1]}",
|
108
|
+
data: #{@mmm_timeseries_arr.map{|t,v| {:x=>t.to_i,:y=>v[:min]} }.to_json}
|
109
|
+
},
|
110
|
+
{
|
111
|
+
name: 'Mean',
|
112
|
+
color: "#{FnordMetric::COLORS[-2]}",
|
113
|
+
data: #{@mmm_timeseries_arr.map{|t,v| {:x=>t.to_i,:y=>v[:avg].average} }.to_json}
|
114
|
+
}
|
115
|
+
]
|
116
|
+
});
|
117
|
+
|
118
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
.report_view
|
2
|
+
|
3
|
+
%ul.ui_numbers(style="float:right;")
|
4
|
+
%li
|
5
|
+
.val
|
6
|
+
%span.ui_value(data-value="#{@total}")
|
7
|
+
.title Number of Samples
|
8
|
+
%li.twoline
|
9
|
+
.title Time Range
|
10
|
+
.val= (fancy_timerange(@interval) * " - ")
|
11
|
+
|
12
|
+
%h1= @opts[:title] || @opts[:key]
|
13
|
+
%h3 Numeric Timeseries Gauge
|
14
|
+
|
15
|
+
%ul.ui_tabs.tabs
|
16
|
+
%li.active{"data-tab" => "Overview"}
|
17
|
+
%a{:href => "#"} Overview
|
18
|
+
%li{"data-tab" => "Punchcards"}
|
19
|
+
%a{:href => "#"} Punchcards
|
20
|
+
/ %li{"data-tab" => "Realtime"}
|
21
|
+
/ %a{:href => "#"} Realtime
|
22
|
+
/ %li{"data-tab" => "Export"}
|
23
|
+
/ %a{:href => "#"} Export
|
24
|
+
|
25
|
+
|
26
|
+
.widget_timeseries
|
27
|
+
|
28
|
+
.resizable(data-width="65" style="border-right:1px solid #ddd;")
|
29
|
+
.headbar.small Series Values
|
30
|
+
|
31
|
+
%table(cellspacing="0")
|
32
|
+
%tr
|
33
|
+
%th
|
34
|
+
-@series.each do |series, sopts|
|
35
|
+
%th(style="padding-top:4px")
|
36
|
+
%span.swatch(style="background:#{sopts[:color]}; display:inline-block;")
|
37
|
+
%span= series
|
38
|
+
|
39
|
+
%tr
|
40
|
+
%td Total (<span class="ui_value" data-timerange="#{@interval.size}"></span>)
|
41
|
+
-@series.each do |series, sopts|
|
42
|
+
%td
|
43
|
+
.ui_value.large.left{:"data-value" => sopts[:timeseries].sum, :style => "min-width:70px;"}
|
44
|
+
.ui_trend.left{:style => "margin-left:5px", :"data-trend" => sopts[:timeseries].trend}
|
45
|
+
|
46
|
+
-FnordMetric::TICKS[tick, @interval.size].each do |zoom|
|
47
|
+
%tr
|
48
|
+
%td
|
49
|
+
.ui_value{:"data-timerange-offset" => zoom, :"data-offset" => -1}
|
50
|
+
-@series.each do |series, sopts|
|
51
|
+
%td
|
52
|
+
-srange = ((@interval.last-zoom)..@interval.last)
|
53
|
+
.ui_value.large.left{:"data-value" => sopts[:timeseries].sum(srange), :style => "width:70px;"}
|
54
|
+
.ui_trend.left{:style => "margin-left:5px", :"data-trend" => sopts[:timeseries].trend(srange)}
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
.resizable(data-width="35")
|
59
|
+
.headbar.small Series Weights
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
:gaugejs
|
64
|
+
|
65
|
+
FnordMetric.ui.resizable('.report_view');
|
66
|
+
FnordMetric.util.updateNumbers('.report_view', 4);
|
67
|
+
FnordMetric.util.format('.report_view');
|
68
|
+
|
69
|
+
FnordMetric.widgets.timeseriesWidget().render({
|
70
|
+
title: "#{key_nouns.last}",
|
71
|
+
elem: $('.widget_timeseries'),
|
72
|
+
height: 420,
|
73
|
+
default_style: 'stack',
|
74
|
+
series_resolutions: #{@zooms.to_json},
|
75
|
+
timespan: #{@interval.size},
|
76
|
+
series: [#{@series.map{ |k,s|
|
77
|
+
dat = s[:data].map{ |k,d| "data#{k}: #{d.to_json(&@calculate_proc)}" }
|
78
|
+
"{ name: #{k.to_json}, color: '#{s[:color]}', #{dat * ","} }"
|
79
|
+
} * ","}]
|
80
|
+
});
|
@@ -0,0 +1,194 @@
|
|
1
|
+
.report_view
|
2
|
+
|
3
|
+
%ul.ui_numbers(style="float:right;")
|
4
|
+
%li
|
5
|
+
.val
|
6
|
+
%span.ui_value(data-value="#{@toplist.total}")
|
7
|
+
.title Number of Samples
|
8
|
+
%li.twoline
|
9
|
+
.title Time Range
|
10
|
+
.val= (fancy_timerange(@interval) * " - ")
|
11
|
+
|
12
|
+
%h1= @opts[:title] || @opts[:key]
|
13
|
+
%h3 Toplist Gauge
|
14
|
+
|
15
|
+
%ul.ui_tabs.toplgauge_tabs
|
16
|
+
%li.active{"data-tab" => "Overview", :onclick=>"toplgaugeTabClick.apply(this);"}
|
17
|
+
%a{:href => "#"} Overview
|
18
|
+
%li{"data-tab" => "Trending", :onclick=>"toplgaugeTabClick.apply(this);"}
|
19
|
+
%a{:href => "#"} Trending
|
20
|
+
/ %li{"data-tab" => "Compate"}
|
21
|
+
/ %a{:href => "#"} Compare
|
22
|
+
/ %li{"data-tab" => "Export"}
|
23
|
+
/ %a{:href => "#"} Export
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
.ui_sidebar_toplist.resizable.resize_min_full_height(data-width="55")
|
28
|
+
|
29
|
+
.widget_toplist.toplgauge_tab.overview
|
30
|
+
.headbar
|
31
|
+
%h2 Top #{key_nouns.last}
|
32
|
+
.ui_toplist.clickable
|
33
|
+
.searchbar
|
34
|
+
%input(type="search" placeholder="Search..." style="width:95%; margin-top:1px; height:36px; line-height:36px;" onchange="toplgaugeSeach($(this).val());" onkeyup="toplgaugeSeach($(this).val());" onclick="toplgaugeSeach($(this).val());")
|
35
|
+
|
36
|
+
- @toplist.toplist(top_k).each_with_index do |(item, score), ind|
|
37
|
+
.toplist_item(onclick="toplgaugeSelectItem.apply(this); return false;" data-item="#{item}" style="#{ind > 49 ? 'display:none;' : nil}" class="#{ind > 49 ? nil : :initial}")
|
38
|
+
.title= item
|
39
|
+
.value
|
40
|
+
%span.ui_value{:"data-value" => score }
|
41
|
+
.percent
|
42
|
+
%span.ui_value{:"data-percent" => @toplist.percentage(item) }
|
43
|
+
%span.ui_trend{ :"data-trend" => @toplist.trend(item).round(1) }
|
44
|
+
|
45
|
+
|
46
|
+
.toplgauge_tab.trending(style="display:none;")
|
47
|
+
.headbar
|
48
|
+
%h2 Trending #{key_nouns.last}
|
49
|
+
|
50
|
+
.ui_toplist.clickable
|
51
|
+
- @toplist.trending(50).each do |item, trend|
|
52
|
+
|
53
|
+
.toplist_item(onclick="toplgaugeSelectItem.apply(this); return false;" data-item="#{item}")
|
54
|
+
.title= item
|
55
|
+
.value.large
|
56
|
+
%span.ui_value{:"data-value" => @toplist.value(item) }
|
57
|
+
= " / "
|
58
|
+
%span.ui_value{:"data-percent" => @toplist.percentage(item) }
|
59
|
+
|
60
|
+
.trend
|
61
|
+
%span.ui_trend(data-trend="#{trend.round(1)}")
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
.widget_keystats.resize_full_height.resizable(data-width="45")
|
66
|
+
.empty_state.resize_full_height
|
67
|
+
.headbar
|
68
|
+
|
69
|
+
%div(style="font-weight:bold; font-size:16px; color:#aaa; text-align:center; margin-top:50%;")
|
70
|
+
%i.icon.icon-arrow-left
|
71
|
+
Please select an item
|
72
|
+
|
73
|
+
|
74
|
+
.keystats(style="display:none;")
|
75
|
+
.widget_item_timeseries
|
76
|
+
.headbar.small
|
77
|
+
|
78
|
+
.numbers_container(style="width:auto; border-bottom:none;")
|
79
|
+
.title
|
80
|
+
.number.total
|
81
|
+
%span.desc Total
|
82
|
+
%span.value.ui_value
|
83
|
+
.number.percent
|
84
|
+
%span.desc Percent
|
85
|
+
%span.value.ui_value
|
86
|
+
.number.delta
|
87
|
+
%span.desc Delta
|
88
|
+
%span.value
|
89
|
+
.ui_trend
|
90
|
+
.number.rank
|
91
|
+
%span.desc Rank
|
92
|
+
%span.value
|
93
|
+
|
94
|
+
|
95
|
+
:gaugejs
|
96
|
+
|
97
|
+
FnordMetric.util.updateNumbers('.report_view', 4);
|
98
|
+
FnordMetric.util.format('.report_view');
|
99
|
+
|
100
|
+
FnordMetric.ui.resizable('#viewport');
|
101
|
+
|
102
|
+
|
103
|
+
:javascript
|
104
|
+
|
105
|
+
var toplist_gauge_timeseries = #{@toplist.timelines.to_json};
|
106
|
+
var toplist_gauge_ticks = #{@all_ticks.sort.to_json};
|
107
|
+
|
108
|
+
var toplist_gauge_numbers = #{Hash[@toplist.toplist(top_k).map{ |k,t|
|
109
|
+
[k, { :total => t,
|
110
|
+
:percent => @toplist.percentage(k),
|
111
|
+
:rank => @toplist.rank(k),
|
112
|
+
:delta => @toplist.trend(k) }]
|
113
|
+
}].to_json};
|
114
|
+
|
115
|
+
|
116
|
+
function toplgaugeSelectItem(){
|
117
|
+
var item_key = $(this).attr('data-item');
|
118
|
+
|
119
|
+
$(this).addClass('active')
|
120
|
+
.siblings().removeClass('active');
|
121
|
+
|
122
|
+
$('.widget_keystats .widget_item_timeseries').html('');
|
123
|
+
$('.widget_keystats .keystats').show();
|
124
|
+
$('.widget_keystats .empty_state').hide();
|
125
|
+
|
126
|
+
$('.widget_keystats .numbers_container .title')
|
127
|
+
.html(item_key);
|
128
|
+
|
129
|
+
$('.widget_keystats .headbar.small')
|
130
|
+
.html("#{key_nouns.first}: " + item_key);
|
131
|
+
|
132
|
+
$('.widget_keystats .number.total .ui_value')
|
133
|
+
.attr('data-value', toplist_gauge_numbers[item_key].total);
|
134
|
+
|
135
|
+
$('.widget_keystats .number.percent .ui_value')
|
136
|
+
.attr('data-percent', toplist_gauge_numbers[item_key].percent);
|
137
|
+
|
138
|
+
$('.widget_keystats .number.delta .ui_trend')
|
139
|
+
.attr('data-trend', toplist_gauge_numbers[item_key].delta);
|
140
|
+
|
141
|
+
$('.widget_keystats .number.rank .value')
|
142
|
+
.html('#' + toplist_gauge_numbers[item_key].rank);
|
143
|
+
|
144
|
+
FnordMetric.util.format('.widget_keystats .keystats');
|
145
|
+
|
146
|
+
var series_data = [];
|
147
|
+
|
148
|
+
for(ind in toplist_gauge_ticks){
|
149
|
+
var _time = toplist_gauge_ticks[ind];
|
150
|
+
var _val = toplist_gauge_timeseries[item_key][_time];
|
151
|
+
if(!_val){ _val = 0; }
|
152
|
+
series_data.push({x: parseInt(_time), y: parseFloat(_val)});
|
153
|
+
}
|
154
|
+
|
155
|
+
FnordMetric.widgets.timeseriesWidget().render({
|
156
|
+
title: "#{key_nouns.first}: " + item_key,
|
157
|
+
elem: $('.widget_item_timeseries'),
|
158
|
+
height: 320,
|
159
|
+
default_style: 'line',
|
160
|
+
series: [{
|
161
|
+
name: item_key,
|
162
|
+
color: "#{FnordMetric::COLORS.last}",
|
163
|
+
data: series_data
|
164
|
+
}]
|
165
|
+
});
|
166
|
+
|
167
|
+
}
|
168
|
+
|
169
|
+
|
170
|
+
function toplgaugeTabClick(){
|
171
|
+
if($(this).attr('data-tab') == "Overview"){
|
172
|
+
$('.toplgauge_tab').hide().filter('.overview').show();
|
173
|
+
} else if($(this).attr('data-tab') == "Trending"){
|
174
|
+
$('.toplgauge_tab').hide().filter('.trending').show();
|
175
|
+
}
|
176
|
+
|
177
|
+
$('.toplgauge_tabs li').removeClass('active');
|
178
|
+
$(this).addClass('active');
|
179
|
+
}
|
180
|
+
|
181
|
+
|
182
|
+
function toplgaugeSeach(item){
|
183
|
+
$('.widget_toplist .toplist_item').hide();
|
184
|
+
|
185
|
+
if(item.length < 2){
|
186
|
+
$('.widget_toplist .toplist_item.initial').show();
|
187
|
+
} else {
|
188
|
+
$('.widget_toplist .toplist_item[data-item^="'+item+'"]').show();
|
189
|
+
}
|
190
|
+
|
191
|
+
}
|
192
|
+
|
193
|
+
|
194
|
+
|
data/web/img/head.png
ADDED
Binary file
|
data/web/img/list.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/web/img/navbar.png
ADDED
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,178 @@
|
|
1
|
+
FnordMetric.widgets.barsWidget = function(){
|
2
|
+
|
3
|
+
var widget_uid = "fnord-" + parseInt(Math.random()*99990000);
|
4
|
+
var width, height, opts, graph, gconfig, legend, hoverDetail, shelving, highlighter, values;
|
5
|
+
|
6
|
+
var cardinal = true;
|
7
|
+
|
8
|
+
function render(_opts){
|
9
|
+
opts = _opts;
|
10
|
+
|
11
|
+
if(!opts.default_style){ opts.default_style = 'line'; }
|
12
|
+
if(!opts.default_cardinal){ opts.default_cardinal = true; }
|
13
|
+
|
14
|
+
draw_layout();
|
15
|
+
|
16
|
+
$(opts.elem)
|
17
|
+
.addClass('resize_listener')
|
18
|
+
.bind('fm_resize', renderChart);
|
19
|
+
|
20
|
+
gconfig = {
|
21
|
+
element: $('.container', opts.elem)[0],
|
22
|
+
renderer: "bar",
|
23
|
+
width: width,
|
24
|
+
height: height - 20,
|
25
|
+
padding: { top: 0.1, bottom: 0 }
|
26
|
+
}
|
27
|
+
|
28
|
+
if(opts.async_chart){
|
29
|
+
updateChart();
|
30
|
+
} else {
|
31
|
+
if(!opts.values){ opts.values = [[0,0],[1,0]]; }
|
32
|
+
values = opts.values;
|
33
|
+
renderChart();
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
function draw_layout(){
|
39
|
+
if(!opts.no_headbar){
|
40
|
+
$(opts.elem).append(
|
41
|
+
$('<div></div>')
|
42
|
+
.addClass('headbar')
|
43
|
+
.append($('<h2></h2>').html(opts.title))
|
44
|
+
);
|
45
|
+
}
|
46
|
+
|
47
|
+
$(opts.elem).append(
|
48
|
+
$('<div></div>')
|
49
|
+
.addClass('container')
|
50
|
+
.css({
|
51
|
+
height: opts.height,
|
52
|
+
margin: '10px 23px 25px 23px',
|
53
|
+
})
|
54
|
+
);
|
55
|
+
|
56
|
+
if(opts.async_chart){
|
57
|
+
$('.headbar', opts.elem).prepend(
|
58
|
+
$('<div></div>')
|
59
|
+
.addClass('button ml')
|
60
|
+
.append($('<span></span>').html('←'))
|
61
|
+
.click(function(){ moveRange(-1); })
|
62
|
+
).prepend(
|
63
|
+
$('<div></div>')
|
64
|
+
.addClass('datepicker')
|
65
|
+
).prepend(
|
66
|
+
$('<div></div>')
|
67
|
+
.addClass('button')
|
68
|
+
.append($('<span></span>').html('→'))
|
69
|
+
.click(function(){ moveRange(1); })
|
70
|
+
);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
function renderChart(){
|
75
|
+
width = opts.elem.width() - 50;
|
76
|
+
height = opts.height || 240;
|
77
|
+
|
78
|
+
gconfig.width = width;
|
79
|
+
gconfig.height = height;
|
80
|
+
|
81
|
+
$(gconfig.element).html("");
|
82
|
+
|
83
|
+
gconfig.series = [{
|
84
|
+
name: opts.title,
|
85
|
+
color: opts.color,
|
86
|
+
data: []
|
87
|
+
}];
|
88
|
+
|
89
|
+
|
90
|
+
if (values.length == 0)
|
91
|
+
values.push(["No data yet",1]);
|
92
|
+
|
93
|
+
for(var n=0; n < values.length; n++){
|
94
|
+
gconfig.series[0].data.push({
|
95
|
+
x: n,
|
96
|
+
label: values[n][0],
|
97
|
+
y: values[n][1]
|
98
|
+
});
|
99
|
+
}
|
100
|
+
|
101
|
+
graph = new Rickshaw.Graph(gconfig);
|
102
|
+
|
103
|
+
new Rickshaw.Graph.Axis.Y({
|
104
|
+
graph: graph,
|
105
|
+
}).render();
|
106
|
+
|
107
|
+
graph.configure(gconfig);
|
108
|
+
graph.render();
|
109
|
+
}
|
110
|
+
|
111
|
+
|
112
|
+
function announce(evt){
|
113
|
+
if(evt.widget_key == opts.widget_key){
|
114
|
+
if((evt.class == "widget_response") && (evt.cmd == "values_for")){
|
115
|
+
running_request = false;
|
116
|
+
$(opts.elem).css('opacity', 1);
|
117
|
+
values = evt.values;
|
118
|
+
renderChart();
|
119
|
+
}
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
function requestValuesAsync(){
|
124
|
+
FnordMetric.publish({
|
125
|
+
"type": "widget_request",
|
126
|
+
"klass": "BarsWidget",
|
127
|
+
"gauge": opts.gauge,
|
128
|
+
"cmd": "values_for",
|
129
|
+
"since": opts.start_timestamp,
|
130
|
+
"until": opts.end_timestamp,
|
131
|
+
"widget_key": opts.widget_key
|
132
|
+
})
|
133
|
+
}
|
134
|
+
|
135
|
+
function updateChart(first_time, silent){
|
136
|
+
if(!silent){ $(opts.elem).css('opacity', 0.5); }
|
137
|
+
updateRange();
|
138
|
+
redrawDatepicker();
|
139
|
+
requestValuesAsync();
|
140
|
+
}
|
141
|
+
|
142
|
+
function redrawDatepicker(){
|
143
|
+
$('.datepicker', opts.elem).html(
|
144
|
+
FnordMetric.util.dateFormat(opts.start_timestamp) +
|
145
|
+
' ‐ ' +
|
146
|
+
FnordMetric.util.dateFormat(opts.end_timestamp)
|
147
|
+
);
|
148
|
+
}
|
149
|
+
|
150
|
+
function updateRange(force){
|
151
|
+
if(!opts.tick){
|
152
|
+
opts.tick = opts.ticks[0];
|
153
|
+
}
|
154
|
+
|
155
|
+
if(!opts.start_timestamp || !opts.end_timestamp || !!force){
|
156
|
+
opts.end_timestamp = parseInt(new Date().getTime() / 1000);
|
157
|
+
opts.start_timestamp = opts.end_timestamp - opts.tick;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
function moveRange(direction){
|
162
|
+
v = opts.tick*direction*8;
|
163
|
+
|
164
|
+
if(((opts.end_timestamp + v)*1000) < new Date().getTime()){
|
165
|
+
opts.start_timestamp += v;
|
166
|
+
opts.end_timestamp += v;
|
167
|
+
}
|
168
|
+
|
169
|
+
updateChart();
|
170
|
+
}
|
171
|
+
|
172
|
+
return {
|
173
|
+
render: render,
|
174
|
+
announce: announce
|
175
|
+
}
|
176
|
+
|
177
|
+
};
|
178
|
+
|