pulse-meter 0.1.11 → 0.2.0

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/README.md CHANGED
@@ -394,20 +394,15 @@ A more complicated visualization
394
394
  # Use local time for x-axis of charts
395
395
  l.use_utc false
396
396
 
397
- # Color for values cut off
398
- l.outlier_color '#FF0000'
399
-
400
- # Transfer some global parameters to Highcharts
401
- l.highchart_options({
402
- tooltip: {
403
- value_decimals: 2
404
- }
397
+ # Transfer some global parameters to Google Charts
398
+ l.gchart_options({
399
+ backgroundColor: '#CCC'
405
400
  })
406
401
 
407
402
  # Add some pages
408
403
  l.page "Request count" do |p|
409
404
 
410
- # Add chart (of Highcharts `area' style, `spline', `pie' and `line' are also available)
405
+ # Add chart (of Google Charts `area' style, `pie' and `line' are also available)
411
406
  p.area "Requests per minute" do |w|
412
407
 
413
408
  # Plot :requests_per_minute values on this chart with black color
@@ -431,11 +426,9 @@ A more complicated visualization
431
426
  # Occupy half (5/10) of the page (horizontally)
432
427
  w.width 5
433
428
 
434
- # Transfer page-wide (and page-specific) options to Highcharts
435
- p.highchart_options({
436
- chart: {
437
- height: 300
438
- }
429
+ # Transfer page-wide (and page-specific) options to Google Charts
430
+ p.gchart_options({
431
+ height: 400
439
432
  })
440
433
  end
441
434
 
@@ -484,10 +477,8 @@ A more complicated visualization
484
477
 
485
478
  end
486
479
 
487
- p.highchart_options({
488
- chart: {
489
- height: 500
490
- }
480
+ p.ghchart_options({
481
+ height: 500
491
482
  })
492
483
  end
493
484
 
data/Rakefile CHANGED
@@ -50,4 +50,4 @@ namespace :example do
50
50
  end
51
51
  end
52
52
 
53
- end
53
+ end
data/examples/basic.ru CHANGED
@@ -10,7 +10,8 @@ layout = PulseMeter::Visualizer.draw do |l|
10
10
 
11
11
  l.page "Counts" do |p|
12
12
 
13
- p.spline "Lama count", sensor: :lama_count do |c|
13
+ p.line "Lama count" do |c|
14
+ c.sensor :lama_count, color: '#CC1155'
14
15
  c.redraw_interval 5
15
16
  c.values_label 'Count'
16
17
  c.width 5
@@ -26,7 +27,19 @@ layout = PulseMeter::Visualizer.draw do |l|
26
27
  c.timespan 1200
27
28
  end
28
29
 
29
- p.spline "Rhino & Lama & Goose count comparison" do |c|
30
+ p.line "Rhino & Lama & Goose count comparison" do |c|
31
+ c.redraw_interval 5
32
+ c.values_label 'Count'
33
+ c.width 5
34
+ c.show_last_point true
35
+ c.timespan 1200
36
+
37
+ c.sensor :rhino_count, color: '#AAAAAA'
38
+ c.sensor :lama_count, color: '#CC1155'
39
+ c.sensor :goose_count
40
+ end
41
+
42
+ p.table "Rhino & Lama & Goose count comparison" do |c|
30
43
  c.redraw_interval 5
31
44
  c.values_label 'Count'
32
45
  c.width 5
@@ -92,19 +105,14 @@ layout = PulseMeter::Visualizer.draw do |l|
92
105
  c.sensor :rhino_average_age
93
106
  end
94
107
 
95
- p.highchart_options({
96
- chart: {
97
- height: 300
98
- }
108
+ p.gchart_options({
109
+ background_color: '#CCC'
99
110
  })
100
111
  end
101
112
 
102
- l.use_utc false
103
- l.outlier_color '#FF0000'
104
- l.highchart_options({
105
- tooltip: {
106
- value_decimals: 2
107
- }
113
+ l.use_utc true
114
+ l.gchart_options({
115
+ height: 300
108
116
  })
109
117
  end
110
118
 
@@ -12,20 +12,15 @@ layout = PulseMeter::Visualizer.draw do |l|
12
12
  # Use local time for x-axis of charts
13
13
  l.use_utc false
14
14
 
15
- # Color for values cut off
16
- l.outlier_color '#FF0000'
17
-
18
- # Transfer some global parameters to Highcharts
19
- l.highchart_options({
20
- tooltip: {
21
- value_decimals: 2
22
- }
15
+ # Transfer some global parameters to Google Charts
16
+ l.gchart_options({
17
+ backgroundColor: '#CCC'
23
18
  })
24
19
 
25
20
  # Add some pages
26
21
  l.page "Request count" do |p|
27
22
 
28
- # Add chart (of Highcharts `area' style, `spline', `pie' and `line' are also available)
23
+ # Add chart (of Google Charts `area' style, `pie' and `line' are also available)
29
24
  p.area "Requests per minute" do |w|
30
25
 
31
26
  # Plot :requests_per_minute values on this chart with black color
@@ -49,11 +44,9 @@ layout = PulseMeter::Visualizer.draw do |l|
49
44
  # Occupy half (5/10) of the page (horizontally)
50
45
  w.width 5
51
46
 
52
- # Transfer page-wide (and page-specific) options to Highcharts
53
- p.highchart_options({
54
- chart: {
55
- height: 300
56
- }
47
+ # Transfer page-wide (and page-specific) options to Google Charts
48
+ p.gchart_options({
49
+ height: 500
57
50
  })
58
51
  end
59
52
 
@@ -102,10 +95,8 @@ layout = PulseMeter::Visualizer.draw do |l|
102
95
 
103
96
  end
104
97
 
105
- p.highchart_options({
106
- chart: {
107
- height: 500
108
- }
98
+ p.gchart_options({
99
+ height: 500
109
100
  })
110
101
  end
111
102
 
@@ -6,7 +6,8 @@ PulseMeter.redis = Redis.new
6
6
 
7
7
  sensor = PulseMeter::Sensor::Timelined::Counter.new(:simple_sample_counter,
8
8
  :interval => 5,
9
- :ttl => 60 * 60
9
+ :ttl => 60 * 60,
10
+ :annotation => 'Simple Sample Counter'
10
11
  )
11
12
 
12
13
  while true
@@ -1,3 +1,3 @@
1
1
  module PulseMeter
2
- VERSION = "0.1.11"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -3,15 +3,13 @@ module PulseMeter
3
3
  module DSL
4
4
  class Layout
5
5
  DEFAULT_TITLE = "Pulse Meter"
6
- DEFAULT_OUTLIER_COLOR = "#FF0000"
7
- DEFAULT_HIGHCHART_OPTIONS = {}
6
+ DEFAULT_GCHART_OPTIONS = {}
8
7
 
9
8
  def initialize
10
9
  @pages = []
11
10
  @title = DEFAULT_TITLE
12
11
  @use_utc = true
13
- @outlier_color = DEFAULT_OUTLIER_COLOR
14
- @highchart_options = DEFAULT_HIGHCHART_OPTIONS.dup
12
+ @gchart_options = DEFAULT_GCHART_OPTIONS.dup
15
13
  end
16
14
 
17
15
  def title(title)
@@ -22,12 +20,16 @@ module PulseMeter
22
20
  @use_utc = use
23
21
  end
24
22
 
25
- def outlier_color(color)
26
- @outlier_color = color
23
+ def outlier_color(_)
24
+ STDERR.puts "DEPRECATION: outlier_color DSL helper does not take effect anymore"
27
25
  end
28
26
 
29
- def highchart_options(options = {})
30
- @highchart_options.merge!(options)
27
+ def highchart_options(_)
28
+ STDERR.puts "DEPRECATION: highchart_options DSL helper does not take effect anymore, use gchart_options instead"
29
+ end
30
+
31
+ def gchart_options(options = {})
32
+ @gchart_options.merge!(options)
31
33
  end
32
34
 
33
35
  def page(title, &block)
@@ -43,8 +45,7 @@ module PulseMeter
43
45
  pages: pages,
44
46
  title: title,
45
47
  use_utc: @use_utc,
46
- outlier_color: @outlier_color,
47
- highchart_options: @highchart_options
48
+ gchart_options: @gchart_options
48
49
  } )
49
50
  end
50
51
 
@@ -1,14 +1,14 @@
1
1
  module PulseMeter
2
2
  module Visualize
3
3
  module DSL
4
- WIDGETS = %w(pie spline line area)
5
- DEFAULT_HIGHCHART_OPTIONS = {}
4
+ WIDGETS = %w(pie line area table)
5
+ DEFAULT_GCHART_OPTIONS = {}
6
6
 
7
7
  class Page
8
8
  def initialize(title = nil)
9
9
  @title = title || ""
10
10
  @widgets = []
11
- @highchart_options = DEFAULT_HIGHCHART_OPTIONS.dup
11
+ @gchart_options = DEFAULT_GCHART_OPTIONS.dup
12
12
  end
13
13
 
14
14
  def widget(type, title = '', widget_args = nil, &block)
@@ -26,19 +26,28 @@ module PulseMeter
26
26
  EVAL
27
27
  end
28
28
 
29
+ def spline(*args, &block)
30
+ STDERR.puts "DEPRECATION: spline widget is no longer available. Using `line' as a fallback."
31
+ line(*args, &block)
32
+ end
33
+
29
34
  def title(new_title)
30
35
  @title = new_title || ''
31
36
  end
32
37
 
33
- def highchart_options(options = {})
34
- @highchart_options.merge!(options)
38
+ def highchart_options(_)
39
+ STDERR.puts "DEPRECATION: highchart_options DSL helper does not take effect anymore, use gchart_options instead"
40
+ end
41
+
42
+ def gchart_options(options = {})
43
+ @gchart_options.merge!(options)
35
44
  end
36
45
 
37
46
  def to_page
38
47
  args = {
39
48
  title: @title,
40
49
  widgets: @widgets.map(&:to_widget),
41
- highchart_options: @highchart_options
50
+ gchart_options: @gchart_options
42
51
  }
43
52
  PulseMeter::Visualize::Page.new(args)
44
53
  end
@@ -5,16 +5,14 @@ module PulseMeter
5
5
 
6
6
  attr_reader :title
7
7
  attr_reader :use_utc
8
- attr_reader :outlier_color
9
- attr_reader :highchart_options
8
+ attr_reader :gchart_options
10
9
 
11
10
  def initialize(args)
12
11
  raise ArgumentError unless args.respond_to?('[]')
13
12
  @title = args[:title] or raise ArgumentError, ":title not specified"
14
13
  @pages = args[:pages] or raise ArgumentError, ":pages not specified"
15
14
  @use_utc = args[:use_utc]
16
- @outlier_color = args[:outlier_color]
17
- @highchart_options = args[:highchart_options]
15
+ @gchart_options = args[:gchart_options]
18
16
  end
19
17
 
20
18
  def to_app
@@ -27,7 +25,7 @@ module PulseMeter
27
25
  res << {
28
26
  id: i + 1,
29
27
  title: p.title,
30
- highchart_options: p.highchart_options
28
+ gchart_options: p.gchart_options
31
29
  }
32
30
  end
33
31
  res
@@ -36,8 +34,7 @@ module PulseMeter
36
34
  def options
37
35
  {
38
36
  use_utc: @use_utc,
39
- outlier_color: @outlier_color,
40
- highchart_options: @highchart_options
37
+ gchart_options: @gchart_options
41
38
  }
42
39
  end
43
40
 
@@ -3,13 +3,13 @@ module PulseMeter
3
3
  class Page
4
4
  attr_reader :widgets
5
5
  attr_reader :title
6
- attr_reader :highchart_options
6
+ attr_reader :gchart_options
7
7
 
8
8
  def initialize(args)
9
9
  raise ArgumentError unless args.respond_to?('[]')
10
10
  @title = args[:title] or raise ArgumentError, ":title not specified"
11
11
  @widgets = args[:widgets] or raise ArgumentError, ":widgets not specified"
12
- @highchart_options = args[:highchart_options] or raise ArgumentError, ":highchart_options not specified"
12
+ @gchart_options = args[:gchart_options] or raise ArgumentError, ":gchart_options not specified"
13
13
  end
14
14
 
15
15
  def widget_data(widget_id, opts = {})
@@ -1,12 +1,6 @@
1
1
  $ ->
2
2
  globalOptions = gon.options
3
3
 
4
- Highcharts.setOptions {
5
- global: {
6
- useUTC: globalOptions.useUtc
7
- }
8
- }
9
-
10
4
  PageInfo = Backbone.Model.extend {
11
5
  }
12
6
 
@@ -29,7 +23,7 @@ $ ->
29
23
 
30
24
  PageTitleView = Backbone.View.extend {
31
25
  tagName: 'li'
32
-
26
+
33
27
  template: _.template('<a href="#/pages/<%= id %>"><%= title %></a>')
34
28
 
35
29
  initialize: ->
@@ -99,19 +93,20 @@ $ ->
99
93
  @setNextFetch()
100
94
 
101
95
  cutoffValue: (v, min, max) ->
102
- if min isnt null && v.y < min
103
- v.y = min
104
- v.color = globalOptions.outlierColor
105
- if max isnt null && v.y > max
106
- v.y = max
107
- v.color = globalOptions.outlierColor
96
+ if v isnt null
97
+ if min isnt null && v < min
98
+ min
99
+ else if max isnt null && v > max
100
+ max
101
+ else
102
+ v
103
+ else
104
+ 0
108
105
 
109
106
  cutoff: (min, max) ->
110
- _.each(@get('series'), (s) ->
111
- console.log s.data.length
112
- _.each( s.data, (v) ->
113
- @cutoffValue(v, min, max)
114
- , this)
107
+ _.each(@get('series').rows, (row) ->
108
+ for i in [1 .. row.length - 1]
109
+ row[i] = @cutoffValue(row[i], min, max)
115
110
  , this)
116
111
 
117
112
  forceUpdate: ->
@@ -119,6 +114,97 @@ $ ->
119
114
  success: (model, response) ->
120
115
  model.trigger('redraw')
121
116
  }
117
+
118
+ pieData: ->
119
+ data = new google.visualization.DataTable()
120
+ data.addColumn('string', 'Title')
121
+ data.addColumn('number', @get('valuesTitle'))
122
+ data.addRows(@get('series').data)
123
+ data
124
+
125
+ dateOffset: ->
126
+ if globalOptions.useUtc
127
+ (new Date).getTimezoneOffset() * 60000
128
+ else
129
+ 0
130
+
131
+ lineData: ->
132
+ title = @get('title')
133
+ data = new google.visualization.DataTable()
134
+ data.addColumn('datetime', 'Time')
135
+ dateOffset = @dateOffset()
136
+ series = @get('series')
137
+ _.each series.titles, (t) ->
138
+ data.addColumn('number', t)
139
+
140
+ console.log series
141
+ _.each series.rows, (row) ->
142
+ row[0] = new Date(row[0] + dateOffset)
143
+ data.addRow(row)
144
+ data
145
+
146
+ options: ->
147
+ {
148
+ title: @get('title')
149
+ lineWidth: 1
150
+ chartArea: {
151
+ left: 40
152
+ width: '100%'
153
+ }
154
+ height: 300
155
+ legend: {
156
+ position: 'bottom'
157
+ }
158
+ vAxis: {
159
+ title: @get('valuesTitle')
160
+ }
161
+ axisTitlesPosition: 'in'
162
+ }
163
+
164
+ pieOptions: ->
165
+ $.extend true, @options(), {
166
+ slices: @get('series').options
167
+ }
168
+
169
+ lineOptions: ->
170
+ $.extend true, @options(), {
171
+ hAxis: {
172
+ format: 'yyyy.MM.dd HH:mm:ss'
173
+ }
174
+ series: @get('series').options
175
+ }
176
+
177
+ tableOptions: ->
178
+ $.extend true, @lineOptions(), {
179
+ sortColumn: 0
180
+ sortAscending: false
181
+ }
182
+
183
+ chartOptions: ->
184
+ opts = if @get('type') == 'pie'
185
+ @pieOptions()
186
+ else if @get('type') == 'table'
187
+ @tableOptions()
188
+ else
189
+ @lineOptions()
190
+ $.extend true, opts, globalOptions.gchartOptions, pageInfos.selected().get('gchartOptions')
191
+
192
+ chartData: ->
193
+ if @get('type') == 'pie'
194
+ @pieData()
195
+ else
196
+ @lineData()
197
+
198
+ chartClass: ->
199
+ if @get('type') == 'pie'
200
+ google.visualization.PieChart
201
+ else if @get('type') == 'area'
202
+ google.visualization.AreaChart
203
+ else if @get('type') == 'table'
204
+ google.visualization.Table
205
+ else
206
+ google.visualization.LineChart
207
+
122
208
  }
123
209
 
124
210
  WidgetList = Backbone.Collection.extend {
@@ -135,58 +221,14 @@ $ ->
135
221
 
136
222
  updateData: (min, max) ->
137
223
  @model.cutoff(min, max)
138
- chartSeries = @chart.series
139
- newSeries = @model.get('series')
140
- for i in [0 .. chartSeries.length - 1]
141
- if newSeries[i]?
142
- chartSeries[i].setData(newSeries[i].data, false)
143
- @chart.redraw()
224
+ @chart.draw(@model.chartData(), @model.chartOptions())
144
225
 
145
226
  render: ->
146
- options = {
147
- chart: {
148
- renderTo: @el
149
- plotBorderWidth: 1
150
- spacingLeft: 0
151
- spacingRight: 0
152
- type: @model.get('type')
153
- animation: false
154
- zoomType: 'x'
155
- }
156
- credits: {
157
- enabled: false
158
- }
159
- title: {
160
- text: @model.get('title')
161
- }
162
- xAxis: {
163
- type: 'datetime'
164
- }
165
- yAxis: {
166
- title: {
167
- text: @model.get('valuesTitle')
168
- }
169
- }
170
- tooltip: {
171
- xDateFormat: '%Y-%m-%d %H:%M:%S'
172
- valueDecimals: 6
173
- }
174
- series: @model.get('series')
175
- plotOptions: {
176
- series: {
177
- animation: false
178
- lineWidth: 1
179
- shadow: false
180
- marker: {
181
- radius: 0
182
- }
183
- }
184
- }
185
- }
186
- $.extend(true, options, globalOptions.highchartOptions, pageInfos.selected().get('highchartOptions'))
187
- @chart = new Highcharts.Chart(options)
227
+ chartClass = @model.chartClass()
228
+ @chart = new chartClass(@el)
229
+ @updateData()
188
230
 
189
- }
231
+ }
190
232
 
191
233
  WidgetView = Backbone.View.extend {
192
234
  tagName: 'div'