pulse-meter 0.0.1
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/.gitignore +19 -0
- data/.rbenv-version +1 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/Procfile +3 -0
- data/README.md +440 -0
- data/Rakefile +53 -0
- data/bin/pulse +6 -0
- data/examples/basic.ru +109 -0
- data/examples/basic_sensor_data.rb +38 -0
- data/examples/full/Procfile +2 -0
- data/examples/full/client.rb +82 -0
- data/examples/full/server.ru +114 -0
- data/examples/minimal/Procfile +2 -0
- data/examples/minimal/client.rb +16 -0
- data/examples/minimal/server.ru +20 -0
- data/examples/readme_client_example.rb +52 -0
- data/lib/cmd.rb +150 -0
- data/lib/pulse-meter.rb +17 -0
- data/lib/pulse-meter/mixins/dumper.rb +72 -0
- data/lib/pulse-meter/mixins/utils.rb +91 -0
- data/lib/pulse-meter/sensor.rb +44 -0
- data/lib/pulse-meter/sensor/base.rb +75 -0
- data/lib/pulse-meter/sensor/counter.rb +36 -0
- data/lib/pulse-meter/sensor/hashed_counter.rb +31 -0
- data/lib/pulse-meter/sensor/indicator.rb +33 -0
- data/lib/pulse-meter/sensor/timeline.rb +180 -0
- data/lib/pulse-meter/sensor/timelined/average.rb +26 -0
- data/lib/pulse-meter/sensor/timelined/counter.rb +16 -0
- data/lib/pulse-meter/sensor/timelined/hashed_counter.rb +22 -0
- data/lib/pulse-meter/sensor/timelined/max.rb +25 -0
- data/lib/pulse-meter/sensor/timelined/median.rb +14 -0
- data/lib/pulse-meter/sensor/timelined/min.rb +25 -0
- data/lib/pulse-meter/sensor/timelined/percentile.rb +31 -0
- data/lib/pulse-meter/version.rb +3 -0
- data/lib/pulse-meter/visualize/app.rb +43 -0
- data/lib/pulse-meter/visualize/dsl.rb +0 -0
- data/lib/pulse-meter/visualize/dsl/errors.rb +46 -0
- data/lib/pulse-meter/visualize/dsl/layout.rb +55 -0
- data/lib/pulse-meter/visualize/dsl/page.rb +50 -0
- data/lib/pulse-meter/visualize/dsl/sensor.rb +21 -0
- data/lib/pulse-meter/visualize/dsl/widget.rb +84 -0
- data/lib/pulse-meter/visualize/layout.rb +54 -0
- data/lib/pulse-meter/visualize/page.rb +30 -0
- data/lib/pulse-meter/visualize/public/css/application.css +19 -0
- data/lib/pulse-meter/visualize/public/css/bootstrap.css +4883 -0
- data/lib/pulse-meter/visualize/public/css/bootstrap.min.css +729 -0
- data/lib/pulse-meter/visualize/public/favicon.ico +0 -0
- data/lib/pulse-meter/visualize/public/img/glyphicons-halflings-white.png +0 -0
- data/lib/pulse-meter/visualize/public/img/glyphicons-halflings.png +0 -0
- data/lib/pulse-meter/visualize/public/js/application.coffee +262 -0
- data/lib/pulse-meter/visualize/public/js/application.js +279 -0
- data/lib/pulse-meter/visualize/public/js/backbone-min.js +38 -0
- data/lib/pulse-meter/visualize/public/js/bootstrap.js +1835 -0
- data/lib/pulse-meter/visualize/public/js/highcharts.js +203 -0
- data/lib/pulse-meter/visualize/public/js/jquery-1.7.2.min.js +4 -0
- data/lib/pulse-meter/visualize/public/js/json2.js +487 -0
- data/lib/pulse-meter/visualize/public/js/underscore-min.js +32 -0
- data/lib/pulse-meter/visualize/sensor.rb +60 -0
- data/lib/pulse-meter/visualize/views/main.haml +40 -0
- data/lib/pulse-meter/visualize/widget.rb +68 -0
- data/lib/pulse-meter/visualizer.rb +30 -0
- data/lib/test_helpers/matchers.rb +36 -0
- data/pulse-meter.gemspec +39 -0
- data/spec/pulse_meter/mixins/dumper_spec.rb +158 -0
- data/spec/pulse_meter/mixins/utils_spec.rb +134 -0
- data/spec/pulse_meter/sensor/base_spec.rb +97 -0
- data/spec/pulse_meter/sensor/counter_spec.rb +54 -0
- data/spec/pulse_meter/sensor/hashed_counter_spec.rb +39 -0
- data/spec/pulse_meter/sensor/indicator_spec.rb +43 -0
- data/spec/pulse_meter/sensor/timeline_spec.rb +58 -0
- data/spec/pulse_meter/sensor/timelined/average_spec.rb +6 -0
- data/spec/pulse_meter/sensor/timelined/counter_spec.rb +6 -0
- data/spec/pulse_meter/sensor/timelined/hashed_counter_spec.rb +8 -0
- data/spec/pulse_meter/sensor/timelined/max_spec.rb +7 -0
- data/spec/pulse_meter/sensor/timelined/median_spec.rb +7 -0
- data/spec/pulse_meter/sensor/timelined/min_spec.rb +7 -0
- data/spec/pulse_meter/sensor/timelined/percentile_spec.rb +17 -0
- data/spec/pulse_meter/visualize/app_spec.rb +27 -0
- data/spec/pulse_meter/visualize/dsl/layout_spec.rb +64 -0
- data/spec/pulse_meter/visualize/dsl/page_spec.rb +75 -0
- data/spec/pulse_meter/visualize/dsl/sensor_spec.rb +30 -0
- data/spec/pulse_meter/visualize/dsl/widget_spec.rb +127 -0
- data/spec/pulse_meter/visualize/layout_spec.rb +55 -0
- data/spec/pulse_meter/visualize/page_spec.rb +150 -0
- data/spec/pulse_meter/visualize/sensor_spec.rb +120 -0
- data/spec/pulse_meter/visualize/widget_spec.rb +113 -0
- data/spec/pulse_meter/visualizer_spec.rb +42 -0
- data/spec/pulse_meter_spec.rb +16 -0
- data/spec/shared_examples/timeline_sensor.rb +279 -0
- data/spec/shared_examples/timelined_subclass.rb +23 -0
- data/spec/spec_helper.rb +29 -0
- metadata +435 -0
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,262 @@
|
|
1
|
+
$ ->
|
2
|
+
globalOptions = gon.options
|
3
|
+
|
4
|
+
Highcharts.setOptions {
|
5
|
+
global: {
|
6
|
+
useUTC: globalOptions.useUtc
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
PageInfo = Backbone.Model.extend {
|
11
|
+
}
|
12
|
+
|
13
|
+
PageInfoList = Backbone.Collection.extend {
|
14
|
+
model: PageInfo
|
15
|
+
selected: ->
|
16
|
+
@find (m) ->
|
17
|
+
m.get 'selected'
|
18
|
+
|
19
|
+
|
20
|
+
selectFirst: ->
|
21
|
+
@at(0).set('selected', true) if @length > 0
|
22
|
+
|
23
|
+
selectPage: (id) ->
|
24
|
+
@each (m) ->
|
25
|
+
m.set 'selected', m.id == id
|
26
|
+
}
|
27
|
+
|
28
|
+
pageInfos = new PageInfoList
|
29
|
+
|
30
|
+
PageTitleView = Backbone.View.extend {
|
31
|
+
tagName: 'li'
|
32
|
+
|
33
|
+
template: _.template('<a href="#/pages/<%= id %>"><%= title %></a>')
|
34
|
+
|
35
|
+
initialize: ->
|
36
|
+
@model.bind 'change', @render, this
|
37
|
+
@model.bind 'destroy', @remove, this
|
38
|
+
|
39
|
+
render: ->
|
40
|
+
@$el.html @template(@model.toJSON())
|
41
|
+
if @model.get('selected')
|
42
|
+
@$el.addClass('active')
|
43
|
+
else
|
44
|
+
@$el.removeClass('active')
|
45
|
+
}
|
46
|
+
|
47
|
+
PageTitlesView = Backbone.View.extend {
|
48
|
+
initialize: ->
|
49
|
+
pageInfos.bind 'reset', @render, this
|
50
|
+
|
51
|
+
addOne: (pageInfo) ->
|
52
|
+
view = new PageTitleView {
|
53
|
+
model: pageInfo
|
54
|
+
}
|
55
|
+
view.render()
|
56
|
+
$('#page-titles').append(view.el)
|
57
|
+
|
58
|
+
render: ->
|
59
|
+
$('#page-titles').empty()
|
60
|
+
pageInfos.each(@addOne)
|
61
|
+
}
|
62
|
+
|
63
|
+
pageTitlesApp = new PageTitlesView
|
64
|
+
|
65
|
+
pageInfos.reset gon.pageInfos
|
66
|
+
|
67
|
+
Widget = Backbone.Model.extend {
|
68
|
+
initialize: ->
|
69
|
+
@needRefresh = true
|
70
|
+
@setNextFetch()
|
71
|
+
|
72
|
+
time: -> (new Date()).getTime()
|
73
|
+
|
74
|
+
setNextFetch: ->
|
75
|
+
@nextFetch = @time() + @get('interval') * 1000
|
76
|
+
|
77
|
+
setRefresh: (needRefresh) ->
|
78
|
+
@needRefresh = needRefresh
|
79
|
+
|
80
|
+
needFetch: ->
|
81
|
+
interval = @get('interval')
|
82
|
+
@time() > @nextFetch && @needRefresh && interval? && interval > 0
|
83
|
+
|
84
|
+
refetch: ->
|
85
|
+
if @needFetch()
|
86
|
+
@fetch()
|
87
|
+
@setNextFetch()
|
88
|
+
|
89
|
+
cutoffValue: (v, min, max) ->
|
90
|
+
if min isnt null && v.y < min
|
91
|
+
v.y = min
|
92
|
+
v.color = globalOptions.outlierColor
|
93
|
+
if max isnt null && v.y > max
|
94
|
+
v.y = max
|
95
|
+
v.color = globalOptions.outlierColor
|
96
|
+
|
97
|
+
cutoff: (min, max) ->
|
98
|
+
_.each(@get('series'), (s) ->
|
99
|
+
_.each( s.data, (v) ->
|
100
|
+
@cutoffValue(v, min, max)
|
101
|
+
, this)
|
102
|
+
, this)
|
103
|
+
}
|
104
|
+
|
105
|
+
WidgetList = Backbone.Collection.extend {
|
106
|
+
model: Widget
|
107
|
+
url: ->
|
108
|
+
ROOT + 'pages/' + pageInfos.selected().id + '/widgets'
|
109
|
+
}
|
110
|
+
|
111
|
+
WidgetChartView = Backbone.View.extend {
|
112
|
+
tagName: 'div'
|
113
|
+
|
114
|
+
initialize: ->
|
115
|
+
@model.bind 'destroy', @remove, this
|
116
|
+
|
117
|
+
updateData: (min, max) ->
|
118
|
+
@model.cutoff(min, max)
|
119
|
+
chartSeries = @chart.series
|
120
|
+
newSeries = @model.get('series')
|
121
|
+
for i in [0 .. chartSeries.length - 1]
|
122
|
+
if newSeries[i]?
|
123
|
+
chartSeries[i].setData(newSeries[i].data, false)
|
124
|
+
@chart.redraw()
|
125
|
+
|
126
|
+
render: ->
|
127
|
+
options = {
|
128
|
+
chart: {
|
129
|
+
renderTo: @el
|
130
|
+
plotBorderWidth: 1
|
131
|
+
spacingLeft: 0
|
132
|
+
spacingRight: 0
|
133
|
+
type: @model.get('type')
|
134
|
+
animation: false
|
135
|
+
zoomType: 'x'
|
136
|
+
}
|
137
|
+
credits: {
|
138
|
+
enabled: false
|
139
|
+
}
|
140
|
+
title: {
|
141
|
+
text: @model.get('title')
|
142
|
+
}
|
143
|
+
xAxis: {
|
144
|
+
type: 'datetime'
|
145
|
+
}
|
146
|
+
yAxis: {
|
147
|
+
title: {
|
148
|
+
text: @model.get('valuesTitle')
|
149
|
+
}
|
150
|
+
}
|
151
|
+
tooltip: {
|
152
|
+
xDateFormat: '%Y-%m-%d %H:%M:%S'
|
153
|
+
valueDecimals: 6
|
154
|
+
}
|
155
|
+
series: @model.get('series')
|
156
|
+
plotOptions: {
|
157
|
+
series: {
|
158
|
+
animation: false
|
159
|
+
lineWidth: 1
|
160
|
+
shadow: false
|
161
|
+
marker: {
|
162
|
+
radius: 0
|
163
|
+
}
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
$.extend(true, options, globalOptions.highchartOptions, pageInfos.selected().get('highchartOptions'))
|
168
|
+
@chart = new Highcharts.Chart(options)
|
169
|
+
|
170
|
+
}
|
171
|
+
|
172
|
+
WidgetView = Backbone.View.extend {
|
173
|
+
tagName: 'div'
|
174
|
+
|
175
|
+
template: _.template($('#widget-template').html())
|
176
|
+
|
177
|
+
initialize: ->
|
178
|
+
@model.bind('destroy', @remove, this)
|
179
|
+
@model.bind('change', @updateChart, this)
|
180
|
+
|
181
|
+
events: {
|
182
|
+
"click #refresh": 'refresh'
|
183
|
+
"click #need-refresh": 'setRefresh'
|
184
|
+
}
|
185
|
+
|
186
|
+
refresh: ->
|
187
|
+
@model.fetch()
|
188
|
+
|
189
|
+
setRefresh: ->
|
190
|
+
needRefresh = @$el.find('#need-refresh').is(":checked")
|
191
|
+
@model.setRefresh(needRefresh)
|
192
|
+
true
|
193
|
+
|
194
|
+
renderChart: ->
|
195
|
+
@chartView.render()
|
196
|
+
|
197
|
+
updateChart: ->
|
198
|
+
@chartView.updateData(@cutoffMin(), @cutoffMax())
|
199
|
+
|
200
|
+
render: ->
|
201
|
+
@$el.html @template(@model.toJSON())
|
202
|
+
@chartView = new WidgetChartView {
|
203
|
+
model: @model
|
204
|
+
}
|
205
|
+
@$el.find("#plotarea").append(@chartView.el)
|
206
|
+
@$el.addClass "span#{@model.get('width')}"
|
207
|
+
|
208
|
+
cutoffMin: ->
|
209
|
+
val = parseFloat(@controlValue('#cutoff-min'))
|
210
|
+
if _.isNaN(val) then null else val
|
211
|
+
|
212
|
+
cutoffMax: ->
|
213
|
+
val = parseFloat(@controlValue('#cutoff-max'))
|
214
|
+
if _.isNaN(val) then null else val
|
215
|
+
|
216
|
+
controlValue: (id) ->
|
217
|
+
val = @$el.find(id).first().val()
|
218
|
+
|
219
|
+
|
220
|
+
}
|
221
|
+
|
222
|
+
widgetList = new WidgetList
|
223
|
+
setInterval( ->
|
224
|
+
widgetList.each (w) ->
|
225
|
+
w.refetch()
|
226
|
+
, 200)
|
227
|
+
|
228
|
+
WidgetListView = Backbone.View.extend {
|
229
|
+
initialize: ->
|
230
|
+
widgetList.bind 'reset', @render, this
|
231
|
+
|
232
|
+
render: ->
|
233
|
+
container = $('#widgets')
|
234
|
+
container.empty()
|
235
|
+
widgetList.each (w) ->
|
236
|
+
view = new WidgetView {
|
237
|
+
model: w
|
238
|
+
}
|
239
|
+
view.render()
|
240
|
+
container.append(view.el)
|
241
|
+
view.renderChart()
|
242
|
+
}
|
243
|
+
|
244
|
+
widgetListApp = new WidgetListView
|
245
|
+
|
246
|
+
AppRouter = Backbone.Router.extend {
|
247
|
+
routes: {
|
248
|
+
'pages/:id': 'getPage'
|
249
|
+
'*actions': 'defaultRoute'
|
250
|
+
}
|
251
|
+
getPage: (ids) ->
|
252
|
+
id = parseInt(ids)
|
253
|
+
pageInfos.selectPage(id)
|
254
|
+
widgetList.fetch()
|
255
|
+
defaultRoute: (actions) ->
|
256
|
+
@navigate('//pages/1') if pageInfos.length > 0
|
257
|
+
}
|
258
|
+
|
259
|
+
appRouter = new AppRouter
|
260
|
+
|
261
|
+
Backbone.history.start()
|
262
|
+
|
@@ -0,0 +1,279 @@
|
|
1
|
+
// Generated by CoffeeScript 1.2.1-pre
|
2
|
+
(function() {
|
3
|
+
|
4
|
+
$(function() {
|
5
|
+
var AppRouter, PageInfo, PageInfoList, PageTitleView, PageTitlesView, Widget, WidgetChartView, WidgetList, WidgetListView, WidgetView, appRouter, globalOptions, pageInfos, pageTitlesApp, widgetList, widgetListApp;
|
6
|
+
globalOptions = gon.options;
|
7
|
+
Highcharts.setOptions({
|
8
|
+
global: {
|
9
|
+
useUTC: globalOptions.useUtc
|
10
|
+
}
|
11
|
+
});
|
12
|
+
PageInfo = Backbone.Model.extend({});
|
13
|
+
PageInfoList = Backbone.Collection.extend({
|
14
|
+
model: PageInfo,
|
15
|
+
selected: function() {
|
16
|
+
return this.find(function(m) {
|
17
|
+
return m.get('selected');
|
18
|
+
});
|
19
|
+
},
|
20
|
+
selectFirst: function() {
|
21
|
+
if (this.length > 0) return this.at(0).set('selected', true);
|
22
|
+
},
|
23
|
+
selectPage: function(id) {
|
24
|
+
return this.each(function(m) {
|
25
|
+
return m.set('selected', m.id === id);
|
26
|
+
});
|
27
|
+
}
|
28
|
+
});
|
29
|
+
pageInfos = new PageInfoList;
|
30
|
+
PageTitleView = Backbone.View.extend({
|
31
|
+
tagName: 'li',
|
32
|
+
template: _.template('<a href="#/pages/<%= id %>"><%= title %></a>'),
|
33
|
+
initialize: function() {
|
34
|
+
this.model.bind('change', this.render, this);
|
35
|
+
return this.model.bind('destroy', this.remove, this);
|
36
|
+
},
|
37
|
+
render: function() {
|
38
|
+
this.$el.html(this.template(this.model.toJSON()));
|
39
|
+
if (this.model.get('selected')) {
|
40
|
+
return this.$el.addClass('active');
|
41
|
+
} else {
|
42
|
+
return this.$el.removeClass('active');
|
43
|
+
}
|
44
|
+
}
|
45
|
+
});
|
46
|
+
PageTitlesView = Backbone.View.extend({
|
47
|
+
initialize: function() {
|
48
|
+
return pageInfos.bind('reset', this.render, this);
|
49
|
+
},
|
50
|
+
addOne: function(pageInfo) {
|
51
|
+
var view;
|
52
|
+
view = new PageTitleView({
|
53
|
+
model: pageInfo
|
54
|
+
});
|
55
|
+
view.render();
|
56
|
+
return $('#page-titles').append(view.el);
|
57
|
+
},
|
58
|
+
render: function() {
|
59
|
+
$('#page-titles').empty();
|
60
|
+
return pageInfos.each(this.addOne);
|
61
|
+
}
|
62
|
+
});
|
63
|
+
pageTitlesApp = new PageTitlesView;
|
64
|
+
pageInfos.reset(gon.pageInfos);
|
65
|
+
Widget = Backbone.Model.extend({
|
66
|
+
initialize: function() {
|
67
|
+
this.needRefresh = true;
|
68
|
+
return this.setNextFetch();
|
69
|
+
},
|
70
|
+
time: function() {
|
71
|
+
return (new Date()).getTime();
|
72
|
+
},
|
73
|
+
setNextFetch: function() {
|
74
|
+
return this.nextFetch = this.time() + this.get('interval') * 1000;
|
75
|
+
},
|
76
|
+
setRefresh: function(needRefresh) {
|
77
|
+
return this.needRefresh = needRefresh;
|
78
|
+
},
|
79
|
+
needFetch: function() {
|
80
|
+
var interval;
|
81
|
+
interval = this.get('interval');
|
82
|
+
return this.time() > this.nextFetch && this.needRefresh && (interval != null) && interval > 0;
|
83
|
+
},
|
84
|
+
refetch: function() {
|
85
|
+
if (this.needFetch()) {
|
86
|
+
this.fetch();
|
87
|
+
return this.setNextFetch();
|
88
|
+
}
|
89
|
+
},
|
90
|
+
cutoffValue: function(v, min, max) {
|
91
|
+
if (min !== null && v.y < min) {
|
92
|
+
v.y = min;
|
93
|
+
v.color = globalOptions.outlierColor;
|
94
|
+
}
|
95
|
+
if (max !== null && v.y > max) {
|
96
|
+
v.y = max;
|
97
|
+
return v.color = globalOptions.outlierColor;
|
98
|
+
}
|
99
|
+
},
|
100
|
+
cutoff: function(min, max) {
|
101
|
+
return _.each(this.get('series'), function(s) {
|
102
|
+
return _.each(s.data, function(v) {
|
103
|
+
return this.cutoffValue(v, min, max);
|
104
|
+
}, this);
|
105
|
+
}, this);
|
106
|
+
}
|
107
|
+
});
|
108
|
+
WidgetList = Backbone.Collection.extend({
|
109
|
+
model: Widget,
|
110
|
+
url: function() {
|
111
|
+
return ROOT + 'pages/' + pageInfos.selected().id + '/widgets';
|
112
|
+
}
|
113
|
+
});
|
114
|
+
WidgetChartView = Backbone.View.extend({
|
115
|
+
tagName: 'div',
|
116
|
+
initialize: function() {
|
117
|
+
return this.model.bind('destroy', this.remove, this);
|
118
|
+
},
|
119
|
+
updateData: function(min, max) {
|
120
|
+
var chartSeries, i, newSeries, _i, _ref;
|
121
|
+
this.model.cutoff(min, max);
|
122
|
+
chartSeries = this.chart.series;
|
123
|
+
newSeries = this.model.get('series');
|
124
|
+
for (i = _i = 0, _ref = chartSeries.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
|
125
|
+
if (newSeries[i] != null) {
|
126
|
+
chartSeries[i].setData(newSeries[i].data, false);
|
127
|
+
}
|
128
|
+
}
|
129
|
+
return this.chart.redraw();
|
130
|
+
},
|
131
|
+
render: function() {
|
132
|
+
var options;
|
133
|
+
options = {
|
134
|
+
chart: {
|
135
|
+
renderTo: this.el,
|
136
|
+
plotBorderWidth: 1,
|
137
|
+
spacingLeft: 0,
|
138
|
+
spacingRight: 0,
|
139
|
+
type: this.model.get('type'),
|
140
|
+
animation: false,
|
141
|
+
zoomType: 'x'
|
142
|
+
},
|
143
|
+
credits: {
|
144
|
+
enabled: false
|
145
|
+
},
|
146
|
+
title: {
|
147
|
+
text: this.model.get('title')
|
148
|
+
},
|
149
|
+
xAxis: {
|
150
|
+
type: 'datetime'
|
151
|
+
},
|
152
|
+
yAxis: {
|
153
|
+
title: {
|
154
|
+
text: this.model.get('valuesTitle')
|
155
|
+
}
|
156
|
+
},
|
157
|
+
tooltip: {
|
158
|
+
xDateFormat: '%Y-%m-%d %H:%M:%S',
|
159
|
+
valueDecimals: 6
|
160
|
+
},
|
161
|
+
series: this.model.get('series'),
|
162
|
+
plotOptions: {
|
163
|
+
series: {
|
164
|
+
animation: false,
|
165
|
+
lineWidth: 1,
|
166
|
+
shadow: false,
|
167
|
+
marker: {
|
168
|
+
radius: 0
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
};
|
173
|
+
$.extend(true, options, globalOptions.highchartOptions, pageInfos.selected().get('highchartOptions'));
|
174
|
+
return this.chart = new Highcharts.Chart(options);
|
175
|
+
}
|
176
|
+
});
|
177
|
+
WidgetView = Backbone.View.extend({
|
178
|
+
tagName: 'div',
|
179
|
+
template: _.template($('#widget-template').html()),
|
180
|
+
initialize: function() {
|
181
|
+
this.model.bind('destroy', this.remove, this);
|
182
|
+
return this.model.bind('change', this.updateChart, this);
|
183
|
+
},
|
184
|
+
events: {
|
185
|
+
"click #refresh": 'refresh',
|
186
|
+
"click #need-refresh": 'setRefresh'
|
187
|
+
},
|
188
|
+
refresh: function() {
|
189
|
+
return this.model.fetch();
|
190
|
+
},
|
191
|
+
setRefresh: function() {
|
192
|
+
var needRefresh;
|
193
|
+
needRefresh = this.$el.find('#need-refresh').is(":checked");
|
194
|
+
this.model.setRefresh(needRefresh);
|
195
|
+
return true;
|
196
|
+
},
|
197
|
+
renderChart: function() {
|
198
|
+
return this.chartView.render();
|
199
|
+
},
|
200
|
+
updateChart: function() {
|
201
|
+
return this.chartView.updateData(this.cutoffMin(), this.cutoffMax());
|
202
|
+
},
|
203
|
+
render: function() {
|
204
|
+
this.$el.html(this.template(this.model.toJSON()));
|
205
|
+
this.chartView = new WidgetChartView({
|
206
|
+
model: this.model
|
207
|
+
});
|
208
|
+
this.$el.find("#plotarea").append(this.chartView.el);
|
209
|
+
return this.$el.addClass("span" + (this.model.get('width')));
|
210
|
+
},
|
211
|
+
cutoffMin: function() {
|
212
|
+
var val;
|
213
|
+
val = parseFloat(this.controlValue('#cutoff-min'));
|
214
|
+
if (_.isNaN(val)) {
|
215
|
+
return null;
|
216
|
+
} else {
|
217
|
+
return val;
|
218
|
+
}
|
219
|
+
},
|
220
|
+
cutoffMax: function() {
|
221
|
+
var val;
|
222
|
+
val = parseFloat(this.controlValue('#cutoff-max'));
|
223
|
+
if (_.isNaN(val)) {
|
224
|
+
return null;
|
225
|
+
} else {
|
226
|
+
return val;
|
227
|
+
}
|
228
|
+
},
|
229
|
+
controlValue: function(id) {
|
230
|
+
var val;
|
231
|
+
return val = this.$el.find(id).first().val();
|
232
|
+
}
|
233
|
+
});
|
234
|
+
widgetList = new WidgetList;
|
235
|
+
setInterval(function() {
|
236
|
+
return widgetList.each(function(w) {
|
237
|
+
return w.refetch();
|
238
|
+
});
|
239
|
+
}, 200);
|
240
|
+
WidgetListView = Backbone.View.extend({
|
241
|
+
initialize: function() {
|
242
|
+
return widgetList.bind('reset', this.render, this);
|
243
|
+
},
|
244
|
+
render: function() {
|
245
|
+
var container;
|
246
|
+
container = $('#widgets');
|
247
|
+
container.empty();
|
248
|
+
return widgetList.each(function(w) {
|
249
|
+
var view;
|
250
|
+
view = new WidgetView({
|
251
|
+
model: w
|
252
|
+
});
|
253
|
+
view.render();
|
254
|
+
container.append(view.el);
|
255
|
+
return view.renderChart();
|
256
|
+
});
|
257
|
+
}
|
258
|
+
});
|
259
|
+
widgetListApp = new WidgetListView;
|
260
|
+
AppRouter = Backbone.Router.extend({
|
261
|
+
routes: {
|
262
|
+
'pages/:id': 'getPage',
|
263
|
+
'*actions': 'defaultRoute'
|
264
|
+
},
|
265
|
+
getPage: function(ids) {
|
266
|
+
var id;
|
267
|
+
id = parseInt(ids);
|
268
|
+
pageInfos.selectPage(id);
|
269
|
+
return widgetList.fetch();
|
270
|
+
},
|
271
|
+
defaultRoute: function(actions) {
|
272
|
+
if (pageInfos.length > 0) return this.navigate('//pages/1');
|
273
|
+
}
|
274
|
+
});
|
275
|
+
appRouter = new AppRouter;
|
276
|
+
return Backbone.history.start();
|
277
|
+
});
|
278
|
+
|
279
|
+
}).call(this);
|