collimator 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e492cdf8a95728837e76a491624445cbcbfd6459
4
+ data.tar.gz: 570a2cbe337fc177837a98d59c071041fa1243cc
5
+ SHA512:
6
+ metadata.gz: 146fcc9d23e5e93893a8cb18823127a78f42b889cc31a7d7ba1251087d3cdf75f2fd4ddbc6a6e26ea194cef5f41deea5589f9b663e1f66c818e05af33beffd53
7
+ data.tar.gz: 50217a40e439d78e13224a5d9d8f70d24b84379017d598c9efe0005f52d7ca8532025f8b4d3da4d226effafe6e09951224a7c1bb7b6a750da014895086e51fea
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0-p353
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gem 'open4'
4
+ gem 'minitest'
5
+ gem 'minitest-reporters'
4
6
 
5
7
  # Specify your gem's dependencies in tabula.gemspec
6
8
  gemspec
data/Gemfile.lock CHANGED
@@ -1,24 +1,34 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- collimator (0.0.2)
4
+ collimator (0.0.3)
5
5
  colored
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ ansi (1.4.3)
11
+ builder (3.2.2)
10
12
  colored (1.2)
11
- json (1.7.5)
13
+ hashie (3.0.0)
14
+ minitest (5.2.3)
15
+ minitest-reporters (1.0.1)
16
+ ansi
17
+ builder
18
+ minitest (>= 5.0)
19
+ powerbar
12
20
  open4 (1.3.0)
21
+ powerbar (1.0.11)
22
+ ansi (~> 1.4.0)
23
+ hashie (>= 1.1.0)
13
24
  rake (0.9.4)
14
- rdoc (3.12)
15
- json (~> 1.4)
16
25
 
17
26
  PLATFORMS
18
27
  ruby
19
28
 
20
29
  DEPENDENCIES
21
30
  collimator!
31
+ minitest
32
+ minitest-reporters
22
33
  open4
23
34
  rake (~> 0.9.2)
24
- rdoc
data/Rakefile CHANGED
@@ -2,9 +2,6 @@ require 'bundler'
2
2
  require 'rake/clean'
3
3
  require 'rake/testtask'
4
4
 
5
- gem 'rdoc' # we need the installed RDoc gem, not the system one
6
- require 'rdoc/task'
7
-
8
5
  include Rake::DSL
9
6
 
10
7
  Bundler::GemHelper.install_tasks
@@ -14,10 +11,5 @@ Rake::TestTask.new do |t|
14
11
  t.pattern = 'test/*_test.rb'
15
12
  end
16
13
 
17
- Rake::RDocTask.new do |rd|
18
- rd.main = "README.rdoc"
19
- rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
20
- end
21
-
22
14
  task :default => [:test]
23
15
 
data/collimator.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "collimator"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Collimator::VERSION
17
- gem.add_development_dependency('rdoc')
17
+
18
18
  gem.add_development_dependency('rake', '~> 0.9.2')
19
19
  gem.add_dependency('colored')
20
20
  end
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path('../../lib/collimator', __FILE__)
3
+
4
+ include Collimator
5
+
6
+ colors = %w(red blue green cyan yellow magenta no_color_exists)
7
+
8
+ data = 12.times.map do |i|
9
+ { :name => "data #{i}", :value => Random.rand(64), :color => colors[Random.rand(7)] }
10
+ end
11
+
12
+ puts 'Data with values displayed'
13
+ BarGraph.data = data
14
+ BarGraph.options = {:show_values => true}
15
+ BarGraph.plot
16
+
17
+ puts ''
18
+ puts 'Same Data without values displayed'
19
+ BarGraph.options = {:show_values => false}
20
+ BarGraph.plot
data/lib/collimator.rb CHANGED
@@ -1,582 +1,11 @@
1
- require File.expand_path("../collimator/version", __FILE__)
2
-
3
1
  require 'rubygems'
4
2
  require 'colored'
5
3
 
6
- module Collimator
7
-
8
- class TooManyDataPoints < Exception
9
- end
10
-
11
- module Table
12
-
13
- @horiz = '-'
14
- @border = '|'
15
- @corner = '+'
16
- @columns = []
17
- @rows = []
18
- @headers = []
19
- @footers = []
20
- @column_names = []
21
- @use_column_headings = false
22
- @auto_clear = true
23
- @separators = []
24
- @live_update = false
25
- @table_string = []
26
- @use_capture_string = false
27
- @use_capture_html = false
28
- @last_header_color = '#EEEEEE'
29
-
30
- def self.live_update=(live_upate)
31
- @live_update = live_upate
32
- end
33
-
34
- def self.live_update
35
- @live_update
36
- end
37
-
38
- def self.set_auto_clear(auto_clear = true)
39
- @auto_clear = auto_clear
40
- end
41
-
42
- def self.set_corner(corner_character)
43
- @corner = corner_character
44
- end
45
-
46
- def self.set_border(border_character)
47
- @border = border_character
48
- end
49
-
50
- def self.set_horizontal(horizontal_character)
51
- @horiz = horizontal_character
52
- end
53
-
54
- def self.header(text, opts = {})
55
- width, padding, justification, color = parse_options(opts)
56
-
57
- @headers << { :text => text, :padding => padding, :justification => justification , :color => color}
58
- end
59
-
60
- def self.footer(text, opts)
61
- width, padding, justification = parse_options(opts)
62
-
63
- @footers << { :text => text, :padding => padding, :justification => justification }
64
- end
65
-
66
- def self.column(heading, opts = {})
67
- width, padding, justification, color = parse_options(opts)
68
-
69
- @columns << { :width => width, :padding => padding, :justification => justification, :color => color }
70
- @use_column_headings = true if heading.length > 0
71
- @column_names << heading
72
- end
73
-
74
- def self.row(row)
75
- colored_data_array = []
76
- if row.class.to_s == "Hash"
77
- colored_data_array = row[:data].map { |v| {:data => v, :color => row[:color] } }
78
- else
79
- colored_data_array = row.clone
80
- end
81
- if @live_update
82
- put_line_of_data(colored_data_array)
83
- else
84
- @rows << colored_data_array
85
- end
86
- end
87
-
88
- def self.separator
89
- if @live_update
90
- put_horizontal_line_with_dividers
91
- else
92
- @separators << @rows.length
93
- end
94
- end
95
-
96
- def self.tabulate
97
- put_header
98
- put_column_heading_text
99
- prep_data
100
- put_table
101
- put_horizontal_line
102
- put_footer
103
-
104
- clear_all if @auto_clear
105
- end
106
-
107
- def self.tabulate_to_string
108
- @use_capture_html = false
109
- @use_capture_string = true
110
- @auto_clear = false
111
- tabulate
112
- @table_string.join("\n")
113
- end
114
-
115
- def self.tabulate_to_html
116
- @use_capture_string = false
117
- @use_capture_html = true
118
- @auto_clear = false
119
-
120
- prep_html_table
121
- tabulate
122
- complete_html_table
123
-
124
- @table_string.join("\n")
125
- end
126
-
127
- def self.prep_html_table
128
- @table_string = []
129
- @table_string << "<table STYLE=\"font-family: helvetica, verdana, tahoma; border-collapse: collapse;\">"
130
- end
131
-
132
- def self.complete_html_table
133
- @table_string << "</table>"
134
- end
135
-
136
- def self.start_live_update
137
- put_header
138
- put_column_heading_text
139
- end
140
-
141
- def self.complete_live_update
142
- put_horizontal_line
143
- put_footer
144
-
145
- clear_all if @auto_clear
146
- end
147
-
148
- def self.csv
149
- lines = []
150
-
151
- lines.concat(@headers.map { |h| h[:text] }) if @headers.count > 0
152
- lines << @column_names.join(',') if @use_column_headings
153
- @rows.each { |row| lines << row.join(',') }
154
- lines.concat(@footers.map { |h| h[:text] }) if @headers.count > 0
155
-
156
- out = lines.join("\n")
157
-
158
- clear_all if @auto_clear
159
-
160
- out
161
- end
162
-
163
- def self.clear_all
164
- @columns = []
165
- @rows = []
166
- @headers = []
167
- @footers = []
168
- @column_names = []
169
- @use_column_headings = false
170
- @horiz = '-'
171
- @border = '|'
172
- @corner = '+'
173
- @auto_clear = true
174
- @separators = []
175
- @live_update = false
176
- @table_string = []
177
- @use_capture_string = false
178
- @use_capture_html = false
179
- end
180
-
181
- def self.clear_data
182
- @rows = []
183
- @separators = []
184
- end
185
-
186
- private
187
-
188
- def self.send_line(line)
189
- if @use_capture_string || @use_capture_html
190
- @table_string << line
191
- else
192
- puts line
193
- end
194
- end
195
-
196
- def self.parse_options(opts)
197
- width = opts.has_key?(:width) ? opts[:width] : 10
198
- padding = opts.has_key?(:padding) ? opts[:padding] : 0
199
- justification = opts.has_key?(:justification) ? opts[:justification] : :center
200
- col_color = opts.has_key?(:color) ? opts[:color] : nil
201
-
202
- padding = 0 if justification == :decimal
203
-
204
- [width, padding, justification, col_color]
205
- end
206
-
207
- def self.put_table
208
- put_horizontal_line if @headers.length == 0 and !@use_column_headings
209
- row_number = 0
210
- @table_string << "<tbody>" if @use_capture_html
211
- @rows.each do |row|
212
- put_horizontal_line_with_dividers if @separators.include?(row_number)
213
- put_line_of_data(row)
214
- row_number += 1
215
- end
216
- @table_string << "</tbody>" if @use_capture_html
217
- end
218
-
219
- def self.prep_data
220
- column = 0
221
- @columns.each do |c|
222
- if c[:justification] == :decimal
223
- column_width = c[:width]
224
- column_center = column_width / 2
225
- values = []
226
- @rows.each do |r|
227
- value = r[column].class.to_s == "Hash" ? r[column][:data] : r[column].to_s
228
- color = r[column].class.to_s == "Hash" ? r[column][:color] : nil
229
-
230
- v2 = value
231
- decimal_place = v2.index('.') ? v2.index('.') : v2.length
232
- v2 = ' '*(column_center -decimal_place) + v2
233
- v2 = v2.ljust(column_width)
234
-
235
- v2 = {:data => v2, :color => color} if color
236
- values << v2
237
- end
238
-
239
- row = 0
240
- @rows.each do |r|
241
- r[column] = values[row]
242
- row += 1
243
- end
244
- end
245
-
246
- if c[:color]
247
- @rows.each do |r|
248
- value = ''
249
- color = nil
250
- if r[column].class.to_s == "Hash" # don't change the data point color if already set. single data point color overrides column color.
251
- color = r[column][:color]
252
- value = r[column][:data]
253
- else
254
- color = c[:color]
255
- value = r[column]
256
- end
257
- r[column] = {:data => value, :color => color}
258
- end
259
- end
260
- column += 1
261
- end
262
- end
263
-
264
- def self.prep_data_orig
265
- column = 0
266
- @columns.each do |c|
267
- if c[:justification] == :decimal
268
- column_width = c[:width]
269
- column_center = column_width / 2
270
- values = []
271
- length = 0
272
- decimal_place = 0
273
- @rows.each do |r|
274
- value = r[column].class.to_s == "Hash" ? r[column][:data] : r[column].to_s
275
- values << value
276
- length = value.length if value.length > length
277
- end
278
- values = values.map { |v| v.ljust(length) }
279
- values.each do |value|
280
- decimal_place = value.index('.') if (value.index('.') and (value.index('.') > decimal_place))
281
- end
282
- values = values.map do |v|
283
- place = v.index('.') ? v.index('.') : v.length
284
- ' '*(decimal_place - place) + v
285
- end
286
-
287
- row = 0
288
- @rows.each do |r|
289
- r[column] = values[row]
290
- row += 1
291
- end
292
- end
293
-
294
- if c[:color]
295
- @rows.each do |r|
296
- value = ''
297
- color = nil
298
- if r[column].class.to_s == "Hash" # don't change the data point color if already set. single data point color overrides column color.
299
- color = r[column][:color]
300
- value = r[column][:data]
301
- else
302
- color = c[:color]
303
- value = r[column]
304
- end
305
- r[column] = {:data => value, :color => color}
306
- end
307
- end
308
- column += 1
309
- end
310
- end
311
-
312
- def self.put_column_heading_text
313
- @use_capture_html ? put_column_heading_text_html : put_column_heading_text_string if @use_column_headings
314
- end
315
-
316
- def self.put_column_heading_text_string
317
- put_line_of_data(@column_names)
318
- put_horizontal_line_with_dividers
319
- end
320
-
321
- def self.style_color(rgb)
322
- luminance = get_luminance(rgb)
323
- color = luminance < 50 ? '#EEEEEE' : '#222222'
324
- color_style = "color: #{color};"
325
- end
326
-
327
- def self.style_header_border(rgb)
328
- luminance = get_luminance(rgb)
329
- color = luminance < 50 ? '#EEEEEE' : '#222222'
330
- color_style = "border-bottom: 1px solid #{color};"
331
- end
332
-
333
- def self.get_luminance(rgb)
334
- rgb_temp = rgb.gsub("#", '')
335
- luminance = 0
336
- if rgb_temp.length == 6
337
- r = rgb_temp[0..1].hex
338
- g = rgb_temp[2..3].hex
339
- b = rgb_temp[4..5].hex
340
- luminance = (0.299*r + 0.587*g + 0.114*b)
341
- end
342
- luminance
343
- end
344
-
345
- def self.put_column_heading_text_html
346
- c = @last_header_color
347
- text_color = style_color(c)
348
- border_color = style_header_border(c)
349
- out = "<tr STYLE=\"background-color: #{@last_header_color}; #{text_color} #{border_color}\">\n"
350
- column = 0
351
- @column_names.each do |cname|
352
- padding_style = @columns[column][:padding] ? "STYLE=\"padding-left: #{@columns[column][:padding]}em; padding-right: #{@columns[column][:padding]}em;\"" : ""
353
- out += "<th #{padding_style}>#{cname}</th>\n"
354
- column += 1
355
- end
356
-
357
- out += "</tr>\n"
358
- out += "</thead>"
359
-
360
- send_line out
361
- end
362
-
363
- def self.put_header_or_footer(header_or_footer = :header)
364
- data = header_or_footer == :footer ? @footers.clone : @headers.clone
365
-
366
- unless @use_capture_html
367
- if header_or_footer == :header and data.length > 0
368
- put_horizontal_line
369
- end
370
- end
371
-
372
- return if data.length == 0
373
-
374
- @table_string << "<thead>" if @use_capture_html if header_or_footer == :header
375
-
376
- data.each do | header |
377
- send_line make_header_line(header)
378
- end
379
-
380
- put_horizontal_line
381
- end
382
-
383
- def self.make_header_line(data)
384
- out = @use_capture_html ? make_header_line_html(data) : make_header_line_string(data)
385
- out
386
- end
387
-
388
- def self.make_header_line_string(header)
389
- header_width = line_width
390
- header_line = @border
391
- header_line += ' '*header[:padding] if header[:justification] == :left
392
- header_line += header[:text].center(header_width - 2) if header[:justification] == :center
393
- header_line += header[:text].ljust(header_width - header[:padding] - 2) if header[:justification] == :left
394
- header_line += header[:text].rjust(header_width - header[:padding] - 2) if header[:justification] == :right
395
- header_line += ' '*header[:padding] if header[:justification] == :right
396
-
397
- header_line += @border
398
- end
399
-
400
- def self.make_header_line_html(data)
401
- @last_header_color = data[:color] || @last_header_color
402
-
403
- text_color = style_color(@last_header_color)
404
- header_line = "<tr>"
405
- header_line += "<th STYLE=\"background-color: #{@last_header_color}; #{text_color}\" colspan='#{@column_names.count + 1}'>#{data[:text]}</th>"
406
- header_line += "</tr>"
407
- header_line
408
- end
409
-
410
- def self.put_footer
411
- put_header_or_footer(:footer) unless @use_capture_html
412
- end
413
-
414
- def self.put_header
415
- put_header_or_footer(:header)
416
- end
417
-
418
- def self.line_width
419
- @columns.length + 1 + @columns.inject(0) { |sum, c| sum + c[:width] + c[:padding] }
420
- end
421
-
422
- def self.format_data(value, width, padding, justification)
423
- data_value = value.class.to_s == "Hash" ? value[:data] : value
424
-
425
- s = ''
426
- s = data_value.to_s
427
- s = ' '*padding + s.ljust(width) if justification == :left
428
- s = s.rjust(width) + ' '*padding if justification == :right
429
- s = s.center(width) if justification == :center || justification == :decimal
430
- #s = s.send(value[:color].to_s) if value.class.to_s == "Hash"
431
- s = s.gsub(data_value.to_s, data_value.to_s.send(value[:color])) if value.class.to_s == "Hash"
432
- s
433
- end
434
-
435
- def self.put_row_of_html_data(row_data)
436
- column = 0
437
- row_string = "<tr>\n"
438
-
439
- row_data.each do | val |
440
- style_info = @columns[column][:padding] ? " STYLE=\"padding-left: #{@columns[column][:padding]}em; padding-right: #{@columns[column][:padding]}em;\"" : ''
441
- row_string += "<td#{style_info}>#{val}</td>\n"
442
- column += 1
443
- end
444
-
445
- row_string += "</tr>"
446
-
447
- send_line row_string
448
- end
449
-
450
- def self.put_row_of_string_data(row_data)
451
- column = 0
452
- row_string = @border
453
-
454
- row_data.each do | val |
455
- s = format_data(val, @columns[column][:width], @columns[column][:padding], @columns[column][:justification])
456
- row_string = row_string + s + @border
457
- column += 1
458
- end
459
-
460
- send_line row_string
461
- end
462
-
463
- def self.put_line_of_data(row_data)
464
- raise TooManyDataPoints if row_data.count > @columns.length
465
-
466
- row_data << '' while row_data.length < @columns.length
467
-
468
- if @use_capture_html
469
- put_row_of_html_data row_data
470
- else
471
- put_row_of_string_data row_data
472
- end
473
- end
474
-
475
- def self.put_horizontal_line
476
- unless @use_capture_html
477
- width = line_width
478
- send_line @corner + @horiz * (width - 2) + @corner
479
- end
480
- end
481
-
482
- def self.put_horizontal_line_with_dividers
483
- unless @use_capture_html
484
- a = []
485
- @columns.each { | c | a << @horiz*(c[:width] + c[:padding]) }
486
- s = @border + a.join(@corner) + @border
487
- send_line s
488
- end
489
- end
490
- end
491
-
492
- module ProgressBar
493
- @display_width = 100
494
- @max = 100
495
- @min = 0
496
- @method = :percent
497
- @step_size = 5
498
- @current = 0
499
-
500
- def self.set_parameters(params)
501
- @display_width = params[:display_width] if params.has_key?(:display_width)
502
- @max = params[:max] if params.has_key?(:max)
503
- @min = params[:min] if params.has_key?(:min)
504
- @method = params[:method] if params.has_key?(:method)
505
- @step_size = params[:step_size] if params.has_key?(:step_size)
506
- end
507
-
508
- def self.start(params = {})
509
- set_parameters params
510
- @current = @min
511
- put_current_progress
512
- end
513
-
514
- def self.increment
515
- @current += @step_size
516
- put_current_progress unless @current > @max
517
- end
518
-
519
- def self.complete
520
- clear
521
- puts " "*(@display_width + 2)
522
- end
523
-
524
- def self.clear
525
- print "\b"*(@display_width + 2)
526
- end
527
-
528
- private
529
-
530
- def self.put_current_progress
531
- clear
532
- STDOUT.flush
533
- print build_bar_string
534
- #puts build_bar_string
535
- end
536
-
537
- def self.build_bar_string
538
- units = @max - @min
539
- unit_width = @display_width/units
540
- percent_complete = @current / (units * 1.0)
541
-
542
- s = '-'*(percent_complete * @display_width) + ' '*((100-percent_complete) * @display_width)
543
- s1 = s[0..(@display_width/2 - 4)]
544
- s2 = s[(@display_width/2 + 3)..(@display_width - 1)]
545
-
546
- formatted_percent = "%0.1f" % (percent_complete * 100)
547
-
548
- s = '|' + s1 + "#{formatted_percent}%".center(6) + s2 + '|'
549
- #s = "#{units} - #{unit_width} - #{percent_complete} - #{@current}"
550
- end
551
- end
552
-
553
- module Spinner
554
- @spinning = nil
555
- @icons = ['-', '\\', '|', '/']
556
-
557
- def self.spin
558
- @spinning = Thread.new(@icons) do |myIcons|
559
- i = 0
560
- while true do
561
- print myIcons[i]
562
- STDOUT.flush
563
- if i == myIcons.length - 1
564
- i = 0
565
- else
566
- i += 1
567
- end
568
- sleep 0.1
4
+ require File.expand_path('../collimator/version', __FILE__)
5
+ require File.expand_path('../collimator/table', __FILE__)
6
+ require File.expand_path('../collimator/progress_bar', __FILE__)
7
+ require File.expand_path('../collimator/spinner', __FILE__)
8
+ require File.expand_path('../collimator/bar_graph', __FILE__)
9
+ require File.expand_path('../collimator/exceptions', __FILE__)
569
10
 
570
- print "\b"
571
- STDOUT.flush
572
- end
573
- end
574
- end
575
11
 
576
- def self.stop
577
- @spinning.exit
578
- print "\b"
579
- STDOUT.flush
580
- end
581
- end
582
- end