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
@@ -1,13 +0,0 @@
1
- class FnordMetric::CountMetric < FnordMetric::Metric
2
-
3
- private
4
-
5
- def value_at(time_or_range)
6
- # FIXME: value_at(my_time) is really slow, because it has to fetch all events that
7
- # happened until that time (and this is not even cached, when time is in the future
8
- # or just now), so we should redirect the call to something like:
9
- # value_at(last_cache_since_my_time) + value_at(last_cache_since_my_time..my_time)
10
- events_at(time_or_range).count
11
- end
12
-
13
- end
@@ -1,2 +0,0 @@
1
- class FnordMetric::FunnelWidget < FnordMetric::Widget
2
- end
@@ -1,80 +0,0 @@
1
- class FnordMetric::Metric
2
-
3
- METRIC_TYPES = %w(count average sum combine)
4
-
5
- def self.from_options(options)
6
- if (klass_name = METRIC_TYPES.detect{ |n| !!options[n.intern] })
7
- klass = "FnordMetric::#{klass_name.classify}Metric".constantize
8
- return klass.new(options)
9
- end
10
- raise "please provide one of these options: average, sum, count, combine"
11
- end
12
-
13
- def initialize(options)
14
- @options = options
15
- end
16
-
17
- def current
18
- self.at(Time.now)
19
- end
20
-
21
- def at(time_or_range)
22
- if cache_this?(time_or_range) && (_v=try_cache(time_or_range))
23
- _v # cache hit
24
- else # cache miss
25
- value_at(time_or_range).tap do |_v|
26
- store_cache(time_or_range, _v) if cache_this?(time_or_range)
27
- end
28
- end
29
- end
30
-
31
- def token
32
- @options[:name]
33
- end
34
-
35
- def events
36
- _events = FnordMetric::Event
37
- if @options[:types]
38
- _events = _events.where(:type.in => [@options[:types]].flatten)
39
- end
40
- _events
41
- end
42
-
43
- def events_at(time_or_range)
44
- if time_or_range.is_a?(Range)
45
- events.where(:time.lt => time_or_range.last.to_i).where(:time.gt => time_or_range.first.to_i)
46
- else
47
- events.where(:time.lt => time_or_range.to_i)
48
- end
49
- end
50
-
51
- private
52
-
53
- def value_at(time_or_range)
54
- raise "implemented in subclass"
55
- end
56
-
57
- def cache_this?(time_or_range)
58
- ((!time_or_range.is_a?(Range) && time_or_range.to_i < Time.now.to_i) ||
59
- (time_or_range.is_a?(Range) && time_or_range.last.to_i < Time.now.to_i))
60
- end
61
-
62
- def try_cache(time_or_range)
63
- FnordMetric::Cache.get(cache_key(time_or_range))
64
- end
65
-
66
- def store_cache(time_or_range, value)
67
- FnordMetric::Cache.store!(cache_key(time_or_range), value)
68
- end
69
-
70
- def cache_key(time_or_range)
71
- time_part = if time_or_range.is_a?(Range)
72
- "r#{time_or_range.first.to_i}-#{time_or_range.last.to_i}"
73
- else
74
- "t#{time_or_range.to_i.to_s}"
75
- end
76
- [self.token, time_part].join("|")
77
- end
78
-
79
-
80
- end
@@ -1,37 +0,0 @@
1
- class FnordMetric::MetricAPI
2
-
3
- def initialize(params)
4
- @params = params.to_options
5
- @metric = FnordMetric.metrics.to_options[params[:name].to_sym]
6
- end
7
-
8
- def render
9
- return {:error => "metric not found"}.to_json unless @metric
10
- data = if @params[:at] && @params[:at] =~ /^[0-9]+$/
11
- { :value => @metric.at(Time.at(@params[:at].to_i)) }
12
- elsif @params[:at] && @params[:at] =~ /^([0-9]+)-([0-9]+)$/ && @params[:tick]
13
- { :values => tick_data }
14
- elsif @params[:at] && @params[:at] =~ /^([0-9]+)-([0-9]+)$/
15
- { :value => range_data }
16
- else
17
- { :value => @metric.at(Time.now) }
18
- end
19
- data.to_json
20
- end
21
-
22
- private
23
-
24
- def range_data
25
- start_ts, end_ts = @params[:at].split("-").map(&:to_i)
26
- @metric.at(start_ts..end_ts)
27
- end
28
-
29
- def tick_data(tick_length=@params[:tick].to_i)
30
- start_ts, end_ts = @params[:at].split("-").map(&:to_i)
31
- ticks = (start_ts..end_ts).step(tick_length)
32
- ticks.map do |tick|
33
- [tick, @metric.at(@params[:delta] ? (tick..tick+tick_length) : tick)]
34
- end
35
- end
36
-
37
- end
@@ -1,26 +0,0 @@
1
- class FnordMetric::NumbersWidget < FnordMetric::Widget
2
-
3
- def data
4
- super.merge(
5
- :gauges => data_gauges,
6
- :offsets => (@opts[:offsets] || [0, 1, "s30"]),
7
- :autoupdate => (@opts[:autoupdate] || 0)
8
- )
9
- end
10
-
11
- def data_gauges
12
- Hash.new.tap do |hash|
13
- gauges.each do |g|
14
- hash[g.name] = {
15
- :tick => g.tick,
16
- :title => g.title
17
- }
18
- end
19
- end
20
- end
21
-
22
- def has_tick?
23
- false
24
- end
25
-
26
- end
@@ -1,29 +0,0 @@
1
- class FnordMetric::Report
2
-
3
- attr_accessor :events, :metrics
4
-
5
- def initialize(_metrics, options)
6
- @options = options
7
- @metrics = Hash.new
8
- @events = Array.new
9
- _metrics.each{ |k,m| self.add_metric!(m) }
10
- end
11
-
12
- def add_metric!(metric)
13
- @metrics[metric.token] = metric
14
- add_helper_methods(metric)
15
- end
16
-
17
- def metaclass
18
- class << self; self; end
19
- end
20
-
21
- private
22
-
23
- def add_helper_methods(metric)
24
- self.metaclass.send(:define_method, metric.token) do
25
- @metrics[metric.token]
26
- end
27
- end
28
-
29
- end
@@ -1,13 +0,0 @@
1
- class FnordMetric::SumMetric < FnordMetric::Metric
2
-
3
- private
4
-
5
- def value_at(time_or_range)
6
- # FIXME: value_at(my_time) is really slow, because it has to fetch all events that
7
- # happened until that time (and this is not even cached, when time is in the future
8
- # or just now), so we should redirect the call to something like:
9
- # value_at(last_cache_since_my_time) + value_at(last_cache_since_my_time..my_time)
10
- events_at(time_or_range).sum(:"data.#{@options[:sum]}")
11
- end
12
-
13
- end
@@ -1,30 +0,0 @@
1
- class FnordMetric::TimelineWidget < FnordMetric::Widget
2
-
3
- def data
4
- @series_colors = ["#FACE4F", "#42436B", "#CD645A", "#2F635E"]
5
-
6
- super.merge(
7
- :gauges => gauges.map(&:name),
8
- :gauge_titles => gauge_titles,
9
- :start_timestamp => ticks.first,
10
- :end_timestamp => ticks.max,
11
- :autoupdate => (@opts[:autoupdate] || 60),
12
- :include_current => !!@opts[:include_current],
13
- :plot_style => (@opts[:plot_style] || 'line'),
14
- :tick => tick
15
- )
16
- end
17
-
18
- def gauge_titles
19
- {}.tap do |_hash|
20
- gauges.each do |gauge|
21
- _hash.merge!(gauge.name => gauge.title)
22
- end
23
- end
24
- end
25
-
26
- def has_tick?
27
- true
28
- end
29
-
30
- end
@@ -1,25 +0,0 @@
1
- class FnordMetric::ToplistWidget < FnordMetric::Widget
2
-
3
- def data
4
- super.merge(
5
- :gauges => data_gauges,
6
- :autoupdate => (@opts[:autoupdate] || 0)
7
- )
8
- end
9
-
10
- def data_gauges
11
- Hash.new.tap do |hash|
12
- gauges.each do |g|
13
- hash[g.name] = {
14
- :tick => g.tick,
15
- :title => g.title
16
- }
17
- end
18
- end
19
- end
20
-
21
- def has_tick?
22
- false
23
- end
24
-
25
- end
data/pub/fnordmetric.css DELETED
@@ -1,145 +0,0 @@
1
- body, html{ height:100%; padding:0px;}
2
- body{ background:#3b3e45; color:#333; margin:0; padding:0; overflow-y:scroll; font: 12px/20px "Helvetica Neue", Helvetica, Arial, sans-serif; }
3
-
4
- .shown{ display: block; }
5
- .hidden{ display: none; }
6
-
7
- .topbar{ height:38px; background:#24272c; position:fixed; top:0px; width:100%; z-index: 1000;}
8
- .topbar ul { list-style-type:none; margin:0; }
9
- .topbar ul li { padding: 5px 10px 5px 10px; background-color:#3b3e45; display:inline; height:38px; line-height:38px; border-radius:3px; margin-right:5px;}
10
- .topbar ul li a { color:#ccc; font-size:13px; text-decoration:none; }
11
- .topbar ul li a:hover { color:#fff; }
12
- .topbar ul li.active a { color:#fff; }
13
-
14
- #wrap{ margin:25px 20px; }
15
-
16
- #tabs{ width:150px; position:fixed; height:100%; margin-top:70px; }
17
- #tabs ul{ list-style-type:none; padding:0; margin:0; width:156px;}
18
- #tabs ul li{ height:34px; line-height:35px; cursor:pointer; color:#ccc; font-size:13px; border-radius:3px; margin-bottom:5px; }
19
- #tabs ul li:after{ content:'›'; display:block; float:right; margin-right:15px; color:#ccc; font-size:16px; line-height:35px; }
20
- #tabs ul li .picto{ margin-top:10px; margin-right:7px; }
21
- #tabs ul li:hover, #tabs ul li:hover:after{ color:#fff; }
22
- #tabs ul li:hover .picto{ opacity:1; }
23
-
24
- .picto{ display:block; height:14px; width:14px; float:left; opacity:0.7; }
25
- .picto.piechart{ background-position:-42px -173px; width:9px; margin-right:5px; }
26
-
27
- #viewport{ float:left; margin-left:150px; margin-top:30px; border-radius:3px; min-width:790px; }
28
- #viewport .viewport_inner{ margin:6px; background:#fff; min-height:1200px; border-radius:2px; }
29
-
30
- #viewport, #tabs ul li:hover, #tabs ul li.active{ background:#24272c; box-shadow: inset 0px 1px 2px 1px rgba(0, 0, 0, 0.4); }
31
-
32
- .widget{ min-height:100px; border-right:1px solid #ececec; float:left; }
33
- .widget.full_width{ border-right:none; }
34
- .widget .inner{ margin:20px; }
35
- /*.widget .headbar{ margin-bottom:30px; }*/
36
-
37
- .toplist_inner{ min-height:300px; }
38
- .toplist_inner.loading{ opacity:0.5; background:url('/loader.gif') no-repeat center center; }
39
-
40
- .toplist_item{ border-bottom:1px solid #dedede; height:42px; }
41
- .toplist_item .title{ float:left; line-height:42px; margin-left:20px; font-size:13px; color:#333; }
42
- .toplist_item .value{ float:right; line-height:42px; margin-right:20px; font-size:13px; font-weight:bold; color:#333; width:70px; color:#666; }
43
- .toplist_item .percent{ float:right; line-height:42px; margin-right:20px; font-size:18px; font-weight:bold; color:#333; width:70px; }
44
-
45
- .headbar {
46
-
47
- height:36px;
48
- background-color: #F4F4F4;
49
- background-image: -webkit-gradient(linear, left top, left bottom, from(#f4f4f4), to(#e9e9e9));
50
- background-image: -webkit-linear-gradient(top, #f4f4f4, #e9e9e9);
51
- background-image: -moz-linear-gradient(top, #f4f4f4, #e9e9e9);
52
- background-image: -ms-linear-gradient(top, #f4f4f4, #e9e9e9);
53
- background-image: -o-linear-gradient(top, #f4f4f4, #e9e9e9);
54
- background-image: linear-gradient(top, #f4f4f4, #e9e9e9);
55
- filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f4f4f4', EndColorStr='#e9e9e9');
56
- padding: 0 15px;
57
- border-bottom: 1px solid #C9C9C9;
58
- border-top: 1px solid #d0d0d0;
59
- font-size:13px;
60
- line-height:29px;
61
- text-shadow: 1px 0px 2px rgba(255, 255, 255, 1);
62
- -moz-text-shadow: 1px 0px 2px rgba(255,255,255,1);
63
- -webkit-text-shadow: 1px 0px 2px rgba(255,255,255,1);
64
- overflow:hidden;
65
- }
66
-
67
- .headbar.small{ height:29px; }
68
-
69
- .headbar h2{ line-height:37px; margin:0; float:left; font-size:14px; }
70
- .headbar .datepicker{ background:#fff; border:1px solid #999; height:20px; padding:0 7px; float:right; margin:8px -1px; min-width:100px; font-size:11px; font-style:italic; line-height:21px; }
71
- .headbar .button.mr{ margin-right:16px; }
72
-
73
- .headbar .button{
74
- margin:8px 0px; height:16px; float:right; display:block;
75
- margin-right:-1px;
76
- background:#eee;
77
- border:1px solid #999;
78
- border-bottom-color:#888;
79
- -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .1);
80
- cursor:pointer;
81
- border-radius:3px;
82
- font-size: 11px;
83
- font-weight:bold;
84
- line-height:16px;
85
- padding:2px 6px;
86
- text-align:center;
87
- text-decoration:none;
88
- vertical-align:top;
89
- white-space:nowrap;
90
- }
91
-
92
- .headbar .button:hover, .headbar.button.active{background:#ddd;border-bottom-color:#999;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, .05)}
93
-
94
-
95
- .numbers_container, .number{ float:left; width:60px; }
96
- .number{ padding-right:20px; margin-right:6px; }
97
- .number .value{ color:#444; font-size:20px; display:block; margin-bottom:5px; font-weight:bold; }
98
- .number .desc{ color:#999; font-size:12px; margin-bottom:5px; display:block; white-space:nowrap; }
99
- .number:last-child{ border-right:none; }
100
- .numbers_container{ padding-right:0px; width:215px; float:left; margin:15px 0 -1px 20px; padding-bottom:5px; border-bottom:1px solid #dedede; }
101
-
102
- .numbers_container.size_3{ width:258px; }
103
- .numbers_container.size_4{ width:358px; }
104
- .numbers_container.size_5{ width:450px; }
105
-
106
- .numbers_container .title{ padding:4px 0 1px 0; color:#333; font-size:14px; display:block;font-weight:400; }
107
-
108
-
109
- ul.session_list{ list-style-type:none; margin:0; padding:9px 16px 0 11px; }
110
- ul.session_list li{ color:#0A0A0A; height:32px; overflow:hidden; line-height:18px; padding:4px; }
111
- ul.session_list li:hover{ background:#eee; cursor:pointer; }
112
- ul.session_list li input{ float: left; margin-right: 7px; }
113
- ul.session_list li .picture{ height:25px; width:25px; float:left; background:#333; overflow:hidden; }
114
- ul.session_list li .name{ float:left; width:115px; overflow:hidden; margin-left:10px; font-size:12px; }
115
- ul.session_list li .time{ float:right; width:40px; overflow:hidden; text-align:right; font-size:10px; }
116
- ul.session_list li .history{ float:right; color:#999; font-size:10px; line-height: 12px;}
117
- ul.session_list li .history:hover{ color:#333; text-decoration:underline; }
118
-
119
- .sessions_feed{ min-width:300px; min-height:100px; float:left; }
120
- .sessions_feed ul.feed_inner{ margin:5px 15px; min-height:100px; padding:0px; }
121
- .sessions_feed ul.feed_inner li{ list-style-type:none; border-bottom:1px solid #e2e2e2; min-height:54px; }
122
- .sessions_feed ul.feed_inner li .message{ font-size:12px; line-height:19px; padding-top:9px; display:block; }
123
- .sessions_feed ul.feed_inner li .properties{ margin-left:50px; font-size:10px; display:block; color:#555; }
124
- .sessions_feed ul.feed_inner li .time{ font-size:10px; line-height:20px; padding-top:19px; padding-right:10px; display:block; color:#999; float:right; font-style:italic; }
125
- .sessions_feed ul.feed_inner li .picture{ height:40px; overflow:hidden; width:40px; float:left; background:#333; margin:7px 10px 0 0; cursor:pointer; }
126
- .sessions_sidebar{ min-height:1200px; float:right; width:250px; border-left:1px solid #C7C9CC; }
127
- .events_sidebar{ min-height:1200px; float:left; width:200px; border-right:1px solid #C7C9CC; }
128
-
129
- ul.event_type_list{ margin:10px; padding:0; }
130
- ul.event_type_list li{ list-style-type:none; color:#0A0A0A; margin-bottom:8px; height:18px; overflow:hidden; line-height:18px; padding:4px; }
131
- ul.event_type_list li input{ margin-right:7px; }
132
- ul.event_type_list li:hover{ background:#eee; cursor:pointer; }
133
- ul.event_type_list li .history{ float:right; color:#999; font-size:10px; }
134
- ul.event_type_list li .history:hover{ color:#333; text-decoration:underline; }
135
-
136
- .clearfix:after {
137
- content: ".";
138
- display: block;
139
- clear: both;
140
- visibility: hidden;
141
- line-height: 0;
142
- height: 0;
143
- }
144
-
145
- .highcharts-series circle{ stroke-width:1px; }