pulse-meter 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/pulse-meter/version.rb +1 -1
- data/lib/pulse-meter/visualize/app.rb +3 -2
- data/lib/pulse-meter/visualize/layout.rb +2 -2
- data/lib/pulse-meter/visualize/page.rb +2 -2
- data/lib/pulse-meter/visualize/public/css/application.css +6 -0
- data/lib/pulse-meter/visualize/public/js/application.coffee +23 -2
- data/lib/pulse-meter/visualize/public/js/application.js +26 -4
- data/lib/pulse-meter/visualize/views/main.haml +31 -7
- data/lib/pulse-meter/visualize/widget.rb +10 -8
- data/spec/pulse_meter/visualize/layout_spec.rb +1 -1
- data/spec/pulse_meter/visualize/page_spec.rb +33 -0
- data/spec/pulse_meter/visualize/widget_spec.rb +18 -0
- metadata +1 -1
data/lib/pulse-meter/version.rb
CHANGED
@@ -33,10 +33,11 @@ module PulseMeter
|
|
33
33
|
|
34
34
|
get '/pages/:page_id/widgets/:id' do
|
35
35
|
page_id = params[:page_id].to_i
|
36
|
-
id = params[:id].to_i
|
36
|
+
id = params[:id].to_i
|
37
|
+
timespan = params[:timespan].to_i
|
37
38
|
|
38
39
|
content_type :json
|
39
|
-
camelize_keys(@layout.widget(page_id - 1, id - 1)).to_json
|
40
|
+
camelize_keys(@layout.widget(page_id - 1, id - 1, timespan: timespan)).to_json
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
@@ -12,8 +12,8 @@ module PulseMeter
|
|
12
12
|
@highchart_options = args[:highchart_options] or raise ArgumentError, ":highchart_options not specified"
|
13
13
|
end
|
14
14
|
|
15
|
-
def widget_data(widget_id)
|
16
|
-
widgets[widget_id].data.merge(id: widget_id + 1)
|
15
|
+
def widget_data(widget_id, opts = {})
|
16
|
+
widgets[widget_id].data(opts).merge(id: widget_id + 1)
|
17
17
|
end
|
18
18
|
|
19
19
|
def widget_datas
|
@@ -68,6 +68,18 @@ $ ->
|
|
68
68
|
initialize: ->
|
69
69
|
@needRefresh = true
|
70
70
|
@setNextFetch()
|
71
|
+
@timespanInc = 0
|
72
|
+
|
73
|
+
increaseTimespan: (inc) ->
|
74
|
+
@timespanInc = @timespanInc + inc
|
75
|
+
@forceUpdate()
|
76
|
+
|
77
|
+
resetTimespan: ->
|
78
|
+
@timespanInc = 0
|
79
|
+
@forceUpdate()
|
80
|
+
|
81
|
+
url: ->
|
82
|
+
"#{@collection.url()}/#{@get('id')}?timespan=#{@get('timespan') + @timespanInc}"
|
71
83
|
|
72
84
|
time: -> (new Date()).getTime()
|
73
85
|
|
@@ -104,7 +116,7 @@ $ ->
|
|
104
116
|
forceUpdate: ->
|
105
117
|
@fetch {
|
106
118
|
success: (model, response) ->
|
107
|
-
model.trigger('
|
119
|
+
model.trigger('redraw')
|
108
120
|
}
|
109
121
|
}
|
110
122
|
|
@@ -182,11 +194,13 @@ $ ->
|
|
182
194
|
|
183
195
|
initialize: ->
|
184
196
|
@model.bind('destroy', @remove, this)
|
185
|
-
@model.bind('
|
197
|
+
@model.bind('redraw', @updateChart, this)
|
186
198
|
|
187
199
|
events: {
|
188
200
|
"click #refresh": 'refresh'
|
189
201
|
"click #need-refresh": 'setRefresh'
|
202
|
+
"click #extend-timespan": 'extendTimespan'
|
203
|
+
"click #reset-timespan": 'resetTimespan'
|
190
204
|
}
|
191
205
|
|
192
206
|
refresh: ->
|
@@ -197,6 +211,13 @@ $ ->
|
|
197
211
|
@model.setRefresh(needRefresh)
|
198
212
|
true
|
199
213
|
|
214
|
+
extendTimespan: ->
|
215
|
+
val = @$el.find("#extend-timespan-val").first().val()
|
216
|
+
@model.increaseTimespan(parseInt(val))
|
217
|
+
|
218
|
+
resetTimespan: ->
|
219
|
+
@model.resetTimespan()
|
220
|
+
|
200
221
|
renderChart: ->
|
201
222
|
@chartView.render()
|
202
223
|
|
@@ -65,7 +65,19 @@
|
|
65
65
|
Widget = Backbone.Model.extend({
|
66
66
|
initialize: function() {
|
67
67
|
this.needRefresh = true;
|
68
|
-
|
68
|
+
this.setNextFetch();
|
69
|
+
return this.timespanInc = 0;
|
70
|
+
},
|
71
|
+
increaseTimespan: function(inc) {
|
72
|
+
this.timespanInc = this.timespanInc + inc;
|
73
|
+
return this.forceUpdate();
|
74
|
+
},
|
75
|
+
resetTimespan: function() {
|
76
|
+
this.timespanInc = 0;
|
77
|
+
return this.forceUpdate();
|
78
|
+
},
|
79
|
+
url: function() {
|
80
|
+
return "" + (this.collection.url()) + "/" + (this.get('id')) + "?timespan=" + (this.get('timespan') + this.timespanInc);
|
69
81
|
},
|
70
82
|
time: function() {
|
71
83
|
return (new Date()).getTime();
|
@@ -107,7 +119,7 @@
|
|
107
119
|
forceUpdate: function() {
|
108
120
|
return this.fetch({
|
109
121
|
success: function(model, response) {
|
110
|
-
return model.trigger('
|
122
|
+
return model.trigger('redraw');
|
111
123
|
}
|
112
124
|
});
|
113
125
|
}
|
@@ -186,11 +198,13 @@
|
|
186
198
|
template: _.template($('#widget-template').html()),
|
187
199
|
initialize: function() {
|
188
200
|
this.model.bind('destroy', this.remove, this);
|
189
|
-
return this.model.bind('
|
201
|
+
return this.model.bind('redraw', this.updateChart, this);
|
190
202
|
},
|
191
203
|
events: {
|
192
204
|
"click #refresh": 'refresh',
|
193
|
-
"click #need-refresh": 'setRefresh'
|
205
|
+
"click #need-refresh": 'setRefresh',
|
206
|
+
"click #extend-timespan": 'extendTimespan',
|
207
|
+
"click #reset-timespan": 'resetTimespan'
|
194
208
|
},
|
195
209
|
refresh: function() {
|
196
210
|
return this.model.forceUpdate();
|
@@ -201,6 +215,14 @@
|
|
201
215
|
this.model.setRefresh(needRefresh);
|
202
216
|
return true;
|
203
217
|
},
|
218
|
+
extendTimespan: function() {
|
219
|
+
var val;
|
220
|
+
val = this.$el.find("#extend-timespan-val").first().val();
|
221
|
+
return this.model.increaseTimespan(parseInt(val));
|
222
|
+
},
|
223
|
+
resetTimespan: function() {
|
224
|
+
return this.model.resetTimespan();
|
225
|
+
},
|
204
226
|
renderChart: function() {
|
205
227
|
return this.chartView.render();
|
206
228
|
},
|
@@ -18,15 +18,38 @@
|
|
18
18
|
%i.icon-refresh
|
19
19
|
Refresh
|
20
20
|
%span.space
|
21
|
-
|
22
|
-
|
21
|
+
%label
|
22
|
+
Cutoff min:
|
23
|
+
%input.btn-mini#cutoff-min
|
23
24
|
%span.space
|
24
|
-
|
25
|
-
|
25
|
+
%label
|
26
|
+
Cutoff max:
|
27
|
+
%input.btn-mini#cutoff-max
|
26
28
|
%span.space
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
%label
|
30
|
+
Refresh:
|
31
|
+
%input.btn-mini#need-refresh{type: :checkbox, checked: :true}
|
32
|
+
<% if(type != 'pie'){ %>
|
33
|
+
%label
|
34
|
+
Timespan:
|
35
|
+
%span.btn.btn-mini#extend-timespan
|
36
|
+
%i.icon-arrow-left
|
37
|
+
Extend
|
38
|
+
%select#extend-timespan-val.btn-mini.span1
|
39
|
+
%option{value: 60, selected: true} 1 minute
|
40
|
+
%option{value: 60 * 5} 5 minutes
|
41
|
+
%option{value: 60 * 30} 30 minutes
|
42
|
+
%option{value: 60 * 60 * 2} 2 hours
|
43
|
+
%option{value: 60 * 60 * 6 } 6 hours
|
44
|
+
%option{value: 60 * 60 * 24} 1 day
|
45
|
+
%option{value: 60 * 60 * 24 * 2} 2 days
|
46
|
+
%option{value: 60 * 60 * 24 * 7} 1 week
|
47
|
+
%option{value: 60 * 60 * 24 * 7 * 2} 2 weeks
|
48
|
+
%option{value: 60 * 60 * 24 * 30} 1 month
|
49
|
+
%span#reset-timespan.btn.btn-mini
|
50
|
+
%i.icon-arrow-right
|
51
|
+
Reset
|
52
|
+
<% } %>
|
30
53
|
%hr
|
31
54
|
|
32
55
|
.container#main
|
@@ -38,3 +61,4 @@
|
|
38
61
|
%span.brand= @title
|
39
62
|
%ul.nav#page-titles
|
40
63
|
#widgets.row
|
64
|
+
|
@@ -22,35 +22,37 @@ module PulseMeter
|
|
22
22
|
@timespan = args[:timespan]
|
23
23
|
end
|
24
24
|
|
25
|
-
def data
|
25
|
+
def data(options = {})
|
26
|
+
real_timespan = options[:timespan] || timespan
|
26
27
|
{
|
27
28
|
title: title,
|
28
29
|
type: type,
|
29
30
|
values_title: values_label,
|
30
31
|
width: width,
|
31
32
|
interval: redraw_interval,
|
32
|
-
series: series_data
|
33
|
+
series: series_data(real_timespan),
|
34
|
+
timespan: timespan
|
33
35
|
}
|
34
36
|
end
|
35
37
|
|
36
38
|
protected
|
37
39
|
|
38
|
-
def series_data
|
40
|
+
def series_data(tspan)
|
39
41
|
case type
|
40
42
|
when :spline
|
41
|
-
line_series_data
|
43
|
+
line_series_data(tspan)
|
42
44
|
when :line
|
43
|
-
line_series_data
|
45
|
+
line_series_data(tspan)
|
44
46
|
when :area
|
45
|
-
line_series_data
|
47
|
+
line_series_data(tspan)
|
46
48
|
when :pie
|
47
49
|
pie_series_data
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
|
-
def line_series_data
|
53
|
+
def line_series_data(tspan)
|
52
54
|
sensors.map do |s|
|
53
|
-
s.timeline_data(
|
55
|
+
s.timeline_data(tspan, show_last_point)
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
@@ -39,7 +39,7 @@ describe PulseMeter::Visualize::Layout do
|
|
39
39
|
it "should return data for correct widget" do
|
40
40
|
w = layout.widget(1, 0)
|
41
41
|
w.should include(id: 1, title: "w3")
|
42
|
-
w = layout.widget(0, 1)
|
42
|
+
w = layout.widget(0, 1, timespan: 123)
|
43
43
|
w.should include(id: 2, title: "w2")
|
44
44
|
end
|
45
45
|
end
|
@@ -98,6 +98,39 @@ describe PulseMeter::Visualize::Page do
|
|
98
98
|
}]
|
99
99
|
end
|
100
100
|
|
101
|
+
Timecop.freeze(interval_start + 2 * interval - 1) do
|
102
|
+
page.widget_data(0, timespan: 0)[:series].should ==
|
103
|
+
[
|
104
|
+
{
|
105
|
+
type: :pie,
|
106
|
+
name: values_label,
|
107
|
+
data: [
|
108
|
+
{
|
109
|
+
name: a_sensor.annotation,
|
110
|
+
color: a_color,
|
111
|
+
y: 12
|
112
|
+
},
|
113
|
+
{
|
114
|
+
name: b_sensor.annotation,
|
115
|
+
color: b_color,
|
116
|
+
y: 33
|
117
|
+
}
|
118
|
+
]
|
119
|
+
|
120
|
+
}
|
121
|
+
]
|
122
|
+
page.widget_data(1, timespan: 1)[:series].should ==
|
123
|
+
[{
|
124
|
+
name: a_sensor.annotation,
|
125
|
+
color: a_color,
|
126
|
+
data: []
|
127
|
+
}, {
|
128
|
+
name: b_sensor.annotation,
|
129
|
+
color: b_color,
|
130
|
+
data: []
|
131
|
+
}]
|
132
|
+
end
|
133
|
+
|
101
134
|
|
102
135
|
end
|
103
136
|
end
|
@@ -105,6 +105,24 @@ describe PulseMeter::Visualize::Widget do
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
108
|
+
|
109
|
+
it "should accept custom timespan" do
|
110
|
+
Timecop.freeze(@current_time + interval) do
|
111
|
+
[:line, :spline, :area].each do |type|
|
112
|
+
widget = widgets[type]
|
113
|
+
widget.data(timespan: timespan)[:series].each do |s|
|
114
|
+
s[:data].size.should == 1
|
115
|
+
end
|
116
|
+
|
117
|
+
widget.data(timespan: timespan + interval)[:series].each do |s|
|
118
|
+
s[:data].size.should == 2
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
108
126
|
end
|
109
127
|
end
|
110
128
|
end
|