fnordmetric 0.7.5 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/doc/V1.0-ROADMAP +97 -0
  2. data/doc/full_example.rb +95 -511
  3. data/doc/legacy_example.rb +640 -0
  4. data/doc/minimal_example.rb +26 -0
  5. data/doc/preview3.png +0 -0
  6. data/fnordmetric.gemspec +3 -2
  7. data/lib/fnordmetric/acceptors/acceptor.rb +29 -0
  8. data/lib/fnordmetric/{inbound_stream.rb → acceptors/tcp_acceptor.rb} +8 -5
  9. data/lib/fnordmetric/{inbound_datagram.rb → acceptors/udp_acceptor.rb} +9 -8
  10. data/lib/fnordmetric/api.rb +2 -2
  11. data/lib/fnordmetric/context.rb +37 -18
  12. data/lib/fnordmetric/defaults.rb +9 -0
  13. data/lib/fnordmetric/ext.rb +72 -0
  14. data/lib/fnordmetric/gauge.rb +37 -10
  15. data/lib/fnordmetric/gauge_calculations.rb +38 -16
  16. data/lib/fnordmetric/gauge_modifiers.rb +67 -0
  17. data/lib/fnordmetric/gauge_rendering.rb +40 -0
  18. data/lib/fnordmetric/gauge_validations.rb +15 -0
  19. data/lib/fnordmetric/gauges/distribution_gauge.rb +85 -0
  20. data/lib/fnordmetric/gauges/timeseries_gauge.rb +143 -0
  21. data/lib/fnordmetric/gauges/toplist_gauge.rb +44 -0
  22. data/lib/fnordmetric/histogram.rb +57 -0
  23. data/lib/fnordmetric/logger.rb +42 -36
  24. data/lib/fnordmetric/namespace.rb +47 -23
  25. data/lib/fnordmetric/session.rb +6 -6
  26. data/lib/fnordmetric/standalone.rb +15 -35
  27. data/lib/fnordmetric/timeseries.rb +79 -0
  28. data/lib/fnordmetric/toplist.rb +61 -0
  29. data/lib/fnordmetric/version.rb +1 -1
  30. data/lib/fnordmetric/web/app.rb +122 -0
  31. data/lib/fnordmetric/web/app_helpers.rb +42 -0
  32. data/lib/fnordmetric/{dashboard.rb → web/dashboard.rb} +4 -0
  33. data/lib/fnordmetric/{event.rb → web/event.rb} +7 -2
  34. data/lib/fnordmetric/web/reactor.rb +87 -0
  35. data/lib/fnordmetric/web/web.rb +53 -0
  36. data/lib/fnordmetric/web/websocket.rb +38 -0
  37. data/lib/fnordmetric/widgets/bars_widget.rb +44 -0
  38. data/lib/fnordmetric/{html_widget.rb → widgets/html_widget.rb} +0 -0
  39. data/lib/fnordmetric/widgets/numbers_widget.rb +56 -0
  40. data/lib/fnordmetric/{pie_widget.rb → widgets/pie_widget.rb} +0 -0
  41. data/lib/fnordmetric/widgets/timeseries_widget.rb +55 -0
  42. data/lib/fnordmetric/widgets/toplist_widget.rb +64 -0
  43. data/lib/fnordmetric/worker.rb +26 -25
  44. data/lib/fnordmetric.rb +85 -115
  45. data/readme.md +362 -0
  46. data/spec/gauge_like_shared.rb +54 -0
  47. data/spec/gauge_spec.rb +2 -36
  48. data/spec/namespace_spec.rb +25 -11
  49. data/spec/spec_helper.rb +4 -0
  50. data/spec/{inbound_stream_spec.rb → tcp_acceptor_spec.rb} +3 -3
  51. data/spec/timeseries_gauge_spec.rb +54 -0
  52. data/spec/{inbound_datagram_spec.rb → udp_acceptor_spec.rb} +3 -3
  53. data/web/fnordmetric.css +786 -0
  54. data/web/haml/app.haml +38 -0
  55. data/web/haml/distribution_gauge.haml +118 -0
  56. data/web/haml/timeseries_gauge.haml +80 -0
  57. data/web/haml/toplist_gauge.haml +194 -0
  58. data/web/img/head.png +0 -0
  59. data/web/img/list.png +0 -0
  60. data/web/img/list_active.png +0 -0
  61. data/web/img/list_hover.png +0 -0
  62. data/web/img/loader_white.gif +0 -0
  63. data/web/img/navbar.png +0 -0
  64. data/web/img/navbar_btn.png +0 -0
  65. data/web/img/picto_gauge.png +0 -0
  66. data/web/js/fnordmetric.bars_widget.js +178 -0
  67. data/web/js/fnordmetric.dashboard_view.js +99 -0
  68. data/web/js/fnordmetric.gauge_view.js +260 -0
  69. data/web/js/fnordmetric.html_widget.js +21 -0
  70. data/web/js/fnordmetric.js +255 -0
  71. data/web/js/fnordmetric.numbers_widget.js +121 -0
  72. data/web/js/fnordmetric.overview_view.js +35 -0
  73. data/web/js/fnordmetric.pie_widget.js +118 -0
  74. data/web/js/fnordmetric.realtime_timeline_widget.js +175 -0
  75. data/web/js/fnordmetric.session_view.js +343 -0
  76. data/web/js/fnordmetric.timeline_widget.js +333 -0
  77. data/web/js/fnordmetric.timeseries_widget.js +388 -0
  78. data/web/js/fnordmetric.toplist_widget.js +112 -0
  79. data/web/js/fnordmetric.ui.js +91 -0
  80. data/web/js/fnordmetric.util.js +244 -0
  81. data/{pub → web}/loader.gif +0 -0
  82. data/web/vendor/d3.v2.js +9382 -0
  83. data/web/vendor/font-awesome/css/font-awesome.css +239 -0
  84. data/web/vendor/font-awesome/font/fontawesome-webfont.eot +0 -0
  85. data/web/vendor/font-awesome/font/fontawesome-webfont.svg +175 -0
  86. data/web/vendor/font-awesome/font/fontawesome-webfont.svgz +0 -0
  87. data/web/vendor/font-awesome/font/fontawesome-webfont.ttf +0 -0
  88. data/web/vendor/font-awesome/font/fontawesome-webfont.woff +0 -0
  89. data/web/vendor/jquery-1.6.2.min.js +18 -0
  90. data/web/vendor/jquery-ui.min.js +413 -0
  91. data/web/vendor/jquery.maskedinput.js +252 -0
  92. data/web/vendor/rickshaw.css +286 -0
  93. data/web/vendor/rickshaw.fnordmetric.js +2676 -0
  94. metadata +129 -79
  95. data/Gemfile +0 -6
  96. data/README.md +0 -404
  97. data/Rakefile +0 -6
  98. data/doc/version +0 -1
  99. data/haml/app.haml +0 -79
  100. data/haml/widget.haml +0 -9
  101. data/lib/fnordmetric/app.rb +0 -163
  102. data/lib/fnordmetric/average_metric.rb +0 -7
  103. data/lib/fnordmetric/bars_widget.rb +0 -26
  104. data/lib/fnordmetric/combine_metric.rb +0 -7
  105. data/lib/fnordmetric/count_metric.rb +0 -13
  106. data/lib/fnordmetric/funnel_widget.rb +0 -2
  107. data/lib/fnordmetric/metric.rb +0 -80
  108. data/lib/fnordmetric/metric_api.rb +0 -37
  109. data/lib/fnordmetric/numbers_widget.rb +0 -26
  110. data/lib/fnordmetric/report.rb +0 -29
  111. data/lib/fnordmetric/sum_metric.rb +0 -13
  112. data/lib/fnordmetric/timeline_widget.rb +0 -30
  113. data/lib/fnordmetric/toplist_widget.rb +0 -25
  114. data/pub/fnordmetric.css +0 -145
  115. data/pub/fnordmetric.js +0 -1179
  116. data/pub/vendor/highcharts.js +0 -170
  117. 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
+ &nbsp; 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
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('&larr;'))
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('&rarr;'))
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
+ '&nbsp;&dash;&nbsp;' +
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
+