pulse-meter 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|