pulse-meter 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -0
- data/examples/basic.ru +23 -5
- data/examples/basic_sensor_data.rb +15 -2
- data/examples/full/server.ru +2 -3
- data/examples/minimal/server.ru +3 -2
- data/lib/pulse-meter/sensor.rb +2 -1
- data/lib/pulse-meter/sensor/configuration.rb +3 -1
- data/lib/pulse-meter/sensor/hashed_indicator.rb +22 -0
- data/lib/pulse-meter/sensor/timeline.rb +13 -1
- data/lib/pulse-meter/version.rb +1 -1
- data/lib/pulse-meter/visualize/app.rb +6 -2
- data/lib/pulse-meter/visualize/base.rb +15 -0
- data/lib/pulse-meter/visualize/dsl/base.rb +131 -0
- data/lib/pulse-meter/visualize/dsl/errors.rb +0 -6
- data/lib/pulse-meter/visualize/dsl/layout.rb +12 -41
- data/lib/pulse-meter/visualize/dsl/page.rb +15 -41
- data/lib/pulse-meter/visualize/dsl/sensor.rb +9 -10
- data/lib/pulse-meter/visualize/dsl/widget.rb +18 -65
- data/lib/pulse-meter/visualize/dsl/widget_old.rb +95 -0
- data/lib/pulse-meter/visualize/dsl/widgets/area.rb +20 -0
- data/lib/pulse-meter/visualize/dsl/widgets/gauge.rb +12 -0
- data/lib/pulse-meter/visualize/dsl/widgets/line.rb +21 -0
- data/lib/pulse-meter/visualize/dsl/widgets/pie.rb +16 -0
- data/lib/pulse-meter/visualize/dsl/widgets/table.rb +19 -0
- data/lib/pulse-meter/visualize/layout.rb +7 -16
- data/lib/pulse-meter/visualize/page.rb +5 -10
- data/lib/pulse-meter/visualize/public/favicon.ico +0 -0
- data/lib/pulse-meter/visualize/public/js/application.coffee +156 -107
- data/lib/pulse-meter/visualize/public/js/application.js +283 -122
- data/lib/pulse-meter/visualize/sensor.rb +7 -13
- data/lib/pulse-meter/visualize/views/main.haml +8 -52
- data/lib/pulse-meter/visualize/views/widgets/area.haml +31 -0
- data/lib/pulse-meter/visualize/views/widgets/extend_options.haml +11 -0
- data/lib/pulse-meter/visualize/views/widgets/gauge.haml +13 -0
- data/lib/pulse-meter/visualize/views/widgets/line.haml +31 -0
- data/lib/pulse-meter/visualize/views/widgets/pie.haml +13 -0
- data/lib/pulse-meter/visualize/views/widgets/table.haml +23 -0
- data/lib/pulse-meter/visualize/widget.rb +17 -87
- data/lib/pulse-meter/visualize/widgets/gauge.rb +47 -0
- data/lib/pulse-meter/visualize/widgets/pie.rb +36 -0
- data/lib/pulse-meter/visualize/widgets/timeline.rb +90 -0
- data/lib/pulse-meter/visualizer.rb +18 -8
- data/perl/PulseMeter/Sensor/Base.pm +42 -0
- data/perl/PulseMeter/Sensor/Counter.pm +19 -0
- data/perl/PulseMeter/Sensor/HashedIndicator.pm +12 -0
- data/perl/PulseMeter/Sensor/Indicator.pm +17 -0
- data/perl/PulseMeter/Sensor/Timeline.pm +51 -0
- data/perl/PulseMeter/Sensor/Timelined/Average.pm +13 -0
- data/perl/PulseMeter/Sensor/Timelined/Counter.pm +12 -0
- data/perl/PulseMeter/Sensor/Timelined/HashedCounter.pm +12 -0
- data/perl/PulseMeter/Sensor/Timelined/Max.pm +18 -0
- data/perl/PulseMeter/Sensor/Timelined/Median.pm +8 -0
- data/perl/PulseMeter/Sensor/Timelined/Min.pm +18 -0
- data/perl/PulseMeter/Sensor/Timelined/Percentile.pm +17 -0
- data/perl/PulseMeter/Sensor/Timelined/UniqCounter.pm +13 -0
- data/perl/PulseMeter/Sensor/UniqCounter.pm +12 -0
- data/pulse-meter.gemspec +1 -0
- data/spec/pulse_meter/sensor/configuration_spec.rb +10 -2
- data/spec/pulse_meter/sensor/hashed_indicator_spec.rb +39 -0
- data/spec/pulse_meter/visualize/dsl/layout_spec.rb +8 -8
- data/spec/pulse_meter/visualize/dsl/page_spec.rb +29 -42
- data/spec/pulse_meter/visualize/dsl/sensor_spec.rb +5 -5
- data/spec/pulse_meter/visualize/dsl/widget_spec.rb +1 -122
- data/spec/pulse_meter/visualize/dsl/widgets/area_spec.rb +44 -0
- data/spec/pulse_meter/visualize/dsl/widgets/gauge_spec.rb +22 -0
- data/spec/pulse_meter/visualize/dsl/widgets/line_spec.rb +44 -0
- data/spec/pulse_meter/visualize/dsl/widgets/pie_spec.rb +35 -0
- data/spec/pulse_meter/visualize/dsl/widgets/table_spec.rb +36 -0
- data/spec/pulse_meter/visualize/layout_spec.rb +3 -3
- data/spec/pulse_meter/visualize/page_spec.rb +2 -2
- data/spec/pulse_meter/visualize/sensor_spec.rb +4 -4
- data/spec/pulse_meter/visualize/series_extractor_spec.rb +3 -3
- data/spec/pulse_meter/visualize/widgets/area_spec.rb +78 -0
- data/spec/pulse_meter/visualize/widgets/gauge_spec.rb +63 -0
- data/spec/pulse_meter/visualize/widgets/line_spec.rb +77 -0
- data/spec/pulse_meter/visualize/widgets/pie_spec.rb +73 -0
- data/spec/pulse_meter/visualize/widgets/table_spec.rb +78 -0
- data/spec/shared_examples/dsl_widget.rb +106 -0
- data/spec/shared_examples/timeline_sensor.rb +32 -2
- metadata +75 -6
- data/lib/pulse-meter/visualize/dsl.rb +0 -0
- data/spec/pulse_meter/visualize/widget_spec.rb +0 -122
@@ -2,16 +2,7 @@ require "pulse-meter/visualize/series_extractor"
|
|
2
2
|
|
3
3
|
module PulseMeter
|
4
4
|
module Visualize
|
5
|
-
class Sensor
|
6
|
-
attr_reader :name
|
7
|
-
attr_reader :color
|
8
|
-
|
9
|
-
def initialize(args)
|
10
|
-
raise ArgumentError unless args.respond_to?('[]')
|
11
|
-
@name = args[:sensor] or raise ArgumentError, ":sensor not specified"
|
12
|
-
@color = args[:color]
|
13
|
-
end
|
14
|
-
|
5
|
+
class Sensor < Base
|
15
6
|
def last_value(now, need_incomplete=false)
|
16
7
|
sensor = real_sensor
|
17
8
|
|
@@ -40,7 +31,7 @@ module PulseMeter
|
|
40
31
|
end
|
41
32
|
|
42
33
|
def annotation
|
43
|
-
real_sensor.annotation
|
34
|
+
real_sensor.annotation || real_sensor.name
|
44
35
|
end
|
45
36
|
|
46
37
|
def type
|
@@ -50,6 +41,10 @@ module PulseMeter
|
|
50
41
|
def interval
|
51
42
|
real_sensor.interval
|
52
43
|
end
|
44
|
+
|
45
|
+
def value
|
46
|
+
real_sensor.value
|
47
|
+
end
|
53
48
|
|
54
49
|
def extractor
|
55
50
|
PulseMeter::Visualize.extractor(self)
|
@@ -59,10 +54,9 @@ module PulseMeter
|
|
59
54
|
|
60
55
|
def real_sensor
|
61
56
|
# TODO add !temporarily! caching if this will be called too frequently
|
62
|
-
PulseMeter::Sensor::Base.restore(
|
57
|
+
PulseMeter::Sensor::Base.restore(name)
|
63
58
|
end
|
64
59
|
|
65
|
-
|
66
60
|
end
|
67
61
|
end
|
68
62
|
end
|
@@ -10,59 +10,15 @@
|
|
10
10
|
%link{rel: 'stylesheet', href: url("/css/#{cssfile}"), type: 'text/css', media: 'screen'}
|
11
11
|
%script{type: 'text/javascript', src: "https://www.google.com/jsapi"}
|
12
12
|
:javascript
|
13
|
-
google.load("visualization", "1", {packages:["corechart", "table"]});
|
13
|
+
google.load("visualization", "1", {packages:["corechart", "table", "gauge"]});
|
14
|
+
google.setOnLoadCallback(drawChart);
|
15
|
+
function drawChart() {
|
16
|
+
document.startApp();
|
17
|
+
}
|
14
18
|
%body
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
.form-inline
|
19
|
-
%button#refresh.btn.btn-mini
|
20
|
-
%i.icon-refresh
|
21
|
-
Refresh
|
22
|
-
<% if(type != 'table'){ %>
|
23
|
-
%span.space
|
24
|
-
%label
|
25
|
-
Cutoff min:
|
26
|
-
%input.btn-mini#cutoff-min
|
27
|
-
%span.space
|
28
|
-
%label
|
29
|
-
Cutoff max:
|
30
|
-
%input.btn-mini#cutoff-max
|
31
|
-
<% } %>
|
32
|
-
%span.space
|
33
|
-
%label
|
34
|
-
Refresh:
|
35
|
-
%input.btn-mini#need-refresh{type: :checkbox, checked: :true}
|
36
|
-
<% if(type != 'pie'){ %>
|
37
|
-
%label
|
38
|
-
Timespan:
|
39
|
-
%select#extend-timespan-val.btn-mini.span1
|
40
|
-
%option{value: 60, selected: true} 1 minute
|
41
|
-
%option{value: 60 * 5} 5 minutes
|
42
|
-
%option{value: 60 * 30} 30 minutes
|
43
|
-
%option{value: 60 * 60 * 2} 2 hours
|
44
|
-
%option{value: 60 * 60 * 6 } 6 hours
|
45
|
-
%option{value: 60 * 60 * 24} 1 day
|
46
|
-
%option{value: 60 * 60 * 24 * 2} 2 days
|
47
|
-
%option{value: 60 * 60 * 24 * 7} 1 week
|
48
|
-
%option{value: 60 * 60 * 24 * 7 * 2} 2 weeks
|
49
|
-
%option{value: 60 * 60 * 24 * 30} 1 month
|
50
|
-
%button#extend-timespan.btn.btn-mini
|
51
|
-
<% if(type != 'table'){ %>
|
52
|
-
%i.icon-arrow-left
|
53
|
-
<% } else { %>
|
54
|
-
%i.icon-arrow-down
|
55
|
-
<% } %>
|
56
|
-
Extend
|
57
|
-
%button#reset-timespan.btn.btn-mini
|
58
|
-
<% if(type != 'table'){ %>
|
59
|
-
%i.icon-arrow-right
|
60
|
-
<% } else { %>
|
61
|
-
%i.icon-arrow-up
|
62
|
-
<% } %>
|
63
|
-
Reset
|
64
|
-
<% } %>
|
65
|
-
%hr
|
19
|
+
|
20
|
+
- %w(area line table pie gauge).each do |wtype|
|
21
|
+
= partial "widgets/#{wtype}"
|
66
22
|
|
67
23
|
.container#main
|
68
24
|
.row
|
@@ -0,0 +1,31 @@
|
|
1
|
+
%script.widget-template{type: 'text/template', 'data-widget-type' => 'area'}
|
2
|
+
#plotarea
|
3
|
+
#chart-controls
|
4
|
+
.form-inline
|
5
|
+
%button#refresh.btn.btn-mini
|
6
|
+
%i.icon-refresh
|
7
|
+
Refresh
|
8
|
+
%span.space
|
9
|
+
%label
|
10
|
+
Cutoff min:
|
11
|
+
%input.btn-mini#cutoff-min
|
12
|
+
%span.space
|
13
|
+
%label
|
14
|
+
Cutoff max:
|
15
|
+
%input.btn-mini#cutoff-max
|
16
|
+
%span.space
|
17
|
+
%label
|
18
|
+
Refresh:
|
19
|
+
%input.btn-mini#need-refresh{type: :checkbox, checked: :true}
|
20
|
+
%label
|
21
|
+
Timespan:
|
22
|
+
%select#extend-timespan-val.btn-mini.span1
|
23
|
+
= partial "widgets/extend_options"
|
24
|
+
%button#extend-timespan.btn.btn-mini
|
25
|
+
%i.icon-arrow-left
|
26
|
+
Extend
|
27
|
+
%button#reset-timespan.btn.btn-mini
|
28
|
+
%i.icon-arrow-right
|
29
|
+
Reset
|
30
|
+
%hr
|
31
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
%option{value: 60, selected: true} 1 minute
|
2
|
+
%option{value: 60 * 5} 5 minutes
|
3
|
+
%option{value: 60 * 30} 30 minutes
|
4
|
+
%option{value: 60 * 60 * 2} 2 hours
|
5
|
+
%option{value: 60 * 60 * 6 } 6 hours
|
6
|
+
%option{value: 60 * 60 * 24} 1 day
|
7
|
+
%option{value: 60 * 60 * 24 * 2} 2 days
|
8
|
+
%option{value: 60 * 60 * 24 * 7} 1 week
|
9
|
+
%option{value: 60 * 60 * 24 * 7 * 2} 2 weeks
|
10
|
+
%option{value: 60 * 60 * 24 * 30} 1 month
|
11
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
%script.widget-template{type: 'text/template', 'data-widget-type' => 'gauge'}
|
2
|
+
#plotarea
|
3
|
+
#chart-controls
|
4
|
+
.form-inline
|
5
|
+
%button#refresh.btn.btn-mini
|
6
|
+
%i.icon-refresh
|
7
|
+
Refresh
|
8
|
+
%span.space
|
9
|
+
%label
|
10
|
+
Refresh:
|
11
|
+
%input.btn-mini#need-refresh{type: :checkbox, checked: :true}
|
12
|
+
%hr
|
13
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
%script.widget-template{type: 'text/template', 'data-widget-type' => 'line'}
|
2
|
+
#plotarea
|
3
|
+
#chart-controls
|
4
|
+
.form-inline
|
5
|
+
%button#refresh.btn.btn-mini
|
6
|
+
%i.icon-refresh
|
7
|
+
Refresh
|
8
|
+
%span.space
|
9
|
+
%label
|
10
|
+
Cutoff min:
|
11
|
+
%input.btn-mini#cutoff-min
|
12
|
+
%span.space
|
13
|
+
%label
|
14
|
+
Cutoff max:
|
15
|
+
%input.btn-mini#cutoff-max
|
16
|
+
%span.space
|
17
|
+
%label
|
18
|
+
Refresh:
|
19
|
+
%input.btn-mini#need-refresh{type: :checkbox, checked: :true}
|
20
|
+
%label
|
21
|
+
Timespan:
|
22
|
+
%select#extend-timespan-val.btn-mini.span1
|
23
|
+
= partial "widgets/extend_options"
|
24
|
+
%button#extend-timespan.btn.btn-mini
|
25
|
+
%i.icon-arrow-left
|
26
|
+
Extend
|
27
|
+
%button#reset-timespan.btn.btn-mini
|
28
|
+
%i.icon-arrow-right
|
29
|
+
Reset
|
30
|
+
%hr
|
31
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
%script.widget-template{type: 'text/template', 'data-widget-type' => 'pie'}
|
2
|
+
#plotarea
|
3
|
+
#chart-controls
|
4
|
+
.form-inline
|
5
|
+
%button#refresh.btn.btn-mini
|
6
|
+
%i.icon-refresh
|
7
|
+
Refresh
|
8
|
+
%span.space
|
9
|
+
%label
|
10
|
+
Refresh:
|
11
|
+
%input.btn-mini#need-refresh{type: :checkbox, checked: :true}
|
12
|
+
%hr
|
13
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
%script.widget-template{type: 'text/template', 'data-widget-type' => 'table'}
|
2
|
+
#plotarea
|
3
|
+
#chart-controls
|
4
|
+
.form-inline
|
5
|
+
%button#refresh.btn.btn-mini
|
6
|
+
%i.icon-refresh
|
7
|
+
Refresh
|
8
|
+
%span.space
|
9
|
+
%label
|
10
|
+
Refresh:
|
11
|
+
%input.btn-mini#need-refresh{type: :checkbox, checked: :true}
|
12
|
+
%label
|
13
|
+
Timespan:
|
14
|
+
%select#extend-timespan-val.btn-mini.span1
|
15
|
+
= partial "widgets/extend_options"
|
16
|
+
%button#extend-timespan.btn.btn-mini
|
17
|
+
%i.icon-arrow-down
|
18
|
+
Extend
|
19
|
+
%button#reset-timespan.btn.btn-mini
|
20
|
+
%i.icon-arrow-up
|
21
|
+
Reset
|
22
|
+
%hr
|
23
|
+
|
@@ -2,60 +2,29 @@ module PulseMeter
|
|
2
2
|
module Visualize
|
3
3
|
class Error < StandardError; end
|
4
4
|
|
5
|
-
class Widget
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
attr_reader :sensors
|
10
|
-
attr_reader :title
|
11
|
-
attr_reader :type
|
12
|
-
attr_reader :width
|
13
|
-
attr_reader :values_label
|
14
|
-
attr_reader :show_last_point
|
15
|
-
attr_reader :redraw_interval
|
16
|
-
attr_reader :timespan
|
17
|
-
|
18
|
-
def initialize(args)
|
19
|
-
raise ArgumentError unless args.respond_to?('[]')
|
20
|
-
@title = args[:title] or raise ArgumentError, ":title not specified"
|
21
|
-
@sensors = args[:sensors] or raise ArgumentError, ":sensors not specified"
|
22
|
-
@type = args[:type] or raise ArgumentError, ":type not specified"
|
23
|
-
@width = args[:width]
|
24
|
-
@values_label = args[:values_label]
|
25
|
-
@show_last_point = args[:show_last_point] || false
|
26
|
-
@redraw_interval = args[:redraw_interval]
|
27
|
-
@timespan = args[:timespan]
|
5
|
+
class Widget < Base
|
6
|
+
def initialize(opts)
|
7
|
+
super
|
8
|
+
@opts[:sensors] ||= []
|
28
9
|
end
|
29
10
|
|
30
|
-
def data
|
31
|
-
ensure_sensor_match!
|
32
|
-
real_timespan = options[:timespan] || timespan
|
11
|
+
def data
|
33
12
|
{
|
34
|
-
title: title,
|
35
13
|
type: type,
|
36
|
-
|
14
|
+
title: title,
|
15
|
+
redraw_interval: redraw_interval,
|
37
16
|
width: width,
|
38
|
-
|
39
|
-
|
40
|
-
timespan: timespan
|
17
|
+
gchart_options: gchart_options,
|
18
|
+
values_title: values_label
|
41
19
|
}
|
42
20
|
end
|
43
21
|
|
44
|
-
|
45
|
-
|
46
|
-
def series_data(tspan)
|
47
|
-
case type
|
48
|
-
when :line
|
49
|
-
line_series_data(tspan)
|
50
|
-
when :area
|
51
|
-
line_series_data(tspan)
|
52
|
-
when :pie
|
53
|
-
pie_series_data
|
54
|
-
when :table
|
55
|
-
line_series_data(tspan)
|
56
|
-
end
|
22
|
+
def type
|
23
|
+
self.class.to_s.split('::').last.downcase
|
57
24
|
end
|
58
25
|
|
26
|
+
protected
|
27
|
+
|
59
28
|
def ensure_sensor_match!
|
60
29
|
intervals = []
|
61
30
|
sensors.each do |s|
|
@@ -71,51 +40,12 @@ module PulseMeter
|
|
71
40
|
end
|
72
41
|
end
|
73
42
|
|
74
|
-
def line_series_data(tspan)
|
75
|
-
now = Time.now
|
76
|
-
sensor_datas = sensors.map{ |s|
|
77
|
-
s.timeline_data(now, tspan, show_last_point)
|
78
|
-
}
|
79
|
-
rows = []
|
80
|
-
titles = []
|
81
|
-
series_options = []
|
82
|
-
datas = []
|
83
|
-
sensor_datas.each do |sensor_data|
|
84
|
-
sensor_data.each do |tl|
|
85
|
-
titles << tl[:name]
|
86
|
-
series_options << {color: tl[:color]}
|
87
|
-
datas << tl[:data]
|
88
|
-
end
|
89
|
-
end
|
90
|
-
unless datas.empty?
|
91
|
-
first = datas.shift
|
92
|
-
first.each_with_index do |tl_data, row_num|
|
93
|
-
rows << datas.each_with_object([tl_data[:x], tl_data[:y]]) do |data_col, row|
|
94
|
-
row << data_col[row_num][:y]
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
{
|
99
|
-
titles: titles,
|
100
|
-
rows: rows,
|
101
|
-
options: series_options
|
102
|
-
}
|
103
|
-
end
|
104
43
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
sensors.each do |s|
|
110
|
-
s.last_point_data(now, show_last_point).each do |point_data|
|
111
|
-
values << [point_data[:name], point_data[:y]]
|
112
|
-
slice_options << {color: point_data[:color]}
|
113
|
-
end
|
44
|
+
def gauge_series_data
|
45
|
+
ensure_gauge_indicators!
|
46
|
+
sensors.map do |s|
|
47
|
+
[s.annotation, s.value]
|
114
48
|
end
|
115
|
-
{
|
116
|
-
data: values,
|
117
|
-
options: slice_options
|
118
|
-
}
|
119
49
|
end
|
120
50
|
|
121
51
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module PulseMeter
|
2
|
+
module Visualize
|
3
|
+
module Widgets
|
4
|
+
class Gauge < PulseMeter::Visualize::Widget
|
5
|
+
class NotAnIndicatorSensorInGaugeWidget < PulseMeter::Visualize::Error; end
|
6
|
+
|
7
|
+
def data(options = {})
|
8
|
+
super().merge({
|
9
|
+
series: values_data
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def ensure_gauge_indicators!
|
16
|
+
sensors.each do |s|
|
17
|
+
unless s.type <= PulseMeter::Sensor::Indicator || s.type <= PulseMeter::Sensor::HashedIndicator
|
18
|
+
raise NotAnIndicatorSensorInGaugeWidget, "Sensor #{s.name} is not an indicator(PulseMeter::Sensor::Indicator or PulseMeter::Sensor::HashedIndicator)"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def values_data
|
24
|
+
ensure_gauge_indicators!
|
25
|
+
gauges = []
|
26
|
+
sensors.map do |s|
|
27
|
+
s_type = s.type
|
28
|
+
case
|
29
|
+
when s_type == PulseMeter::Sensor::Indicator
|
30
|
+
gauges << [s.annotation, s.value]
|
31
|
+
when s_type == PulseMeter::Sensor::HashedIndicator
|
32
|
+
s.value.each_pair do |k, v|
|
33
|
+
gauge_title = "#{s.annotation}: #{k}"
|
34
|
+
gauges << [gauge_title, v]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
gauges
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module PulseMeter
|
2
|
+
module Visualize
|
3
|
+
module Widgets
|
4
|
+
class Pie < PulseMeter::Visualize::Widget
|
5
|
+
|
6
|
+
def data(options = {})
|
7
|
+
super().merge({
|
8
|
+
series: slice_data
|
9
|
+
})
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def slice_data
|
15
|
+
values = []
|
16
|
+
slice_options = []
|
17
|
+
now = Time.now
|
18
|
+
sensors.each do |s|
|
19
|
+
s.last_point_data(now, show_last_point).each do |point_data|
|
20
|
+
values << [point_data[:name], point_data[:y]]
|
21
|
+
slice_options << {color: point_data[:color]}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
{
|
25
|
+
data: values,
|
26
|
+
options: slice_options
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|