collimator 0.0.2 → 0.0.3

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.
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