soperf 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.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/Gemfile.lock +2 -4
- data/lib/soperf.rb +1 -9
- data/lib/soperf/chart.rb +28 -131
- data/lib/soperf/chart_container.rb +77 -0
- data/lib/soperf/color_helper.rb +6 -6
- data/lib/soperf/render_job.rb +87 -0
- data/lib/soperf/row.rb +19 -16
- data/lib/soperf/soperf_helpers.rb +67 -0
- data/lib/soperf/version.rb +3 -0
- data/soperf.gemspec +1 -2
- data/spec/lib/color_picker_spec.rb +4 -4
- data/spec/lib/time_helper_spec.rb +1 -1
- metadata +7 -19
- data/lib/soperf/terminal_helper.rb +0 -7
- data/lib/soperf/time_helper.rb +0 -32
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
N2I1OTczMjRlMmVjODJlNTk2NDZkYWE2NGJlZGFkYmIwMzQ1ZGVkNw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzA2NjYwM2ExOGI2OGNjYjM1MjE1NDM5ZjVjNTU3ZjIwODg2MWYxNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZGU2ZjI1YzQwMDU2NTZmMWQ5YzkxODk3Y2E0MWFjM2JkZmFiMTA3NTViY2M4
|
10
|
+
ZGQ4YzA3ZTI1NTg0ZjgwMGEzNTgzMzA1NTI2M2RiYjFhZDhhMDU3ODM0Nzdi
|
11
|
+
ODVlYmZkZTA5MDVmMmQ1ODIxYzJhNjc1M2FmMDllNmZiNTJkYjA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MjZlODExZGI3YTMxNWIzYzFiYTRiZmJlNjkzZGYwMWNhZmQ0ZThkZDM5Nzdh
|
14
|
+
ZTRhZmRmYTE4MDM1ZDNjZWRlYjQzNDk0NWMyNDM1MzRjNWFhMTRhOTI5OTYw
|
15
|
+
MGZlZTEzMjA0NmFjZDVjYTQ3NjU5NzYwMjQ3OTg2Mzc2MmYzNzg=
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/lib/soperf.rb
CHANGED
@@ -1,14 +1,6 @@
|
|
1
|
-
# Dir.glob(File.join(File.expand_path(File.dirname(__FILE__)), ".")).each {|dir| $LOAD_PATH << dir }
|
2
|
-
|
3
1
|
require 'colorize'
|
4
|
-
require 'highline'
|
5
2
|
require_relative 'soperf/box_drawing_chars'
|
3
|
+
require_relative 'soperf/soperf_helpers'
|
6
4
|
require_relative 'soperf/chart'
|
7
5
|
require_relative 'soperf/color_helper'
|
8
6
|
require_relative 'soperf/row'
|
9
|
-
require_relative 'soperf/terminal_helper'
|
10
|
-
require_relative 'soperf/time_helper'
|
11
|
-
|
12
|
-
module SoPerf
|
13
|
-
VERSION = "0.1.4"
|
14
|
-
end
|
data/lib/soperf/chart.rb
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
|
4
4
|
require_relative 'row'
|
5
5
|
require_relative 'box_drawing_chars'
|
6
|
-
require_relative '
|
7
|
-
require_relative 'time_helper'
|
6
|
+
require_relative 'soperf_helpers'
|
8
7
|
require_relative 'color_helper'
|
8
|
+
require_relative 'render_job'
|
9
|
+
require_relative 'chart_container'
|
9
10
|
|
10
11
|
module SoPerf
|
11
12
|
class Chart
|
@@ -13,170 +14,66 @@ module SoPerf
|
|
13
14
|
include BoxDrawingChars
|
14
15
|
include TerminalHelper
|
15
16
|
include TimeHelper
|
17
|
+
include ValueFinder
|
16
18
|
|
17
19
|
def initialize(data_hash)
|
18
|
-
@data_hash = Hash[data_hash.sort_by
|
20
|
+
@data_hash = Hash[data_hash.sort_by do |_, arr| #sort the data by start time of first range
|
21
|
+
arr = [arr] unless arr.is_a?(Array)
|
22
|
+
arr.map { |range| range.first }.max
|
23
|
+
end]
|
19
24
|
@chart = {}
|
20
25
|
set_up_rows
|
21
26
|
@duration = data_range(:round) #Find the full range of the data, rounded up
|
22
|
-
@longest_name = data_hash.map { |k,
|
23
|
-
@
|
27
|
+
@longest_name = data_hash.map { |k, _| k.to_s.length }.max #The longest name of the results
|
28
|
+
@spacer = Spacer.new(@longest_name)
|
29
|
+
@text_info = @data_hash.map { |k, v| "#{@chart[k].name(true)}: #{translate_time(v.first)}-#{translate_time(v.last)}" }
|
24
30
|
@forced_width = nil
|
25
31
|
end
|
26
32
|
|
27
|
-
def usable_space #Space for the chart, accounting for printing row names
|
28
|
-
@forced_width ? @forced_width : terminal_width - spacer.length - 10
|
29
|
-
end
|
30
|
-
|
31
33
|
def ideal_scale
|
32
34
|
(usable_space.to_f)/duration
|
33
35
|
end
|
34
36
|
|
35
|
-
def spacer(i=0)
|
36
|
-
i = i.length if i.is_a?(String)
|
37
|
-
spacer = ''
|
38
|
-
(@longest_name-i).times { spacer<<' ' }
|
39
|
-
spacer
|
40
|
-
end
|
41
|
-
|
42
37
|
def data_range(round=:round)
|
43
|
-
range = data_hash.map { |_, v| v
|
38
|
+
range = data_hash.map { |_, v| v.last }.max
|
44
39
|
round==:round ? ((range/10.0).ceil*10) : range
|
45
40
|
end
|
46
41
|
|
47
42
|
def set_up_rows
|
48
|
-
|
49
|
-
data_hash.each { |k, v| @chart[k] = Row.new(k,
|
43
|
+
ColorHelper.reset_color_index
|
44
|
+
data_hash.each { |k, v| @chart[k] = Row.new(k, v) }
|
50
45
|
end
|
51
46
|
|
52
47
|
def render(options_hash={})
|
53
48
|
options_hash[:color] = true unless options_hash.has_key?(:color)
|
54
49
|
@forced_width = options_hash[:width] if options_hash.has_key?(:width)
|
55
50
|
show_summary = options_hash.has_key?(:summary) ? options_hash[:summary] : true
|
56
|
-
|
57
|
-
@
|
58
|
-
|
51
|
+
@names = @chart.map { |_, v| v.name(true) }
|
52
|
+
options_hash.merge!({duration: data_range, longest_name: @longest_name,
|
53
|
+
spacer: @spacer, names: @names})
|
59
54
|
|
60
|
-
@
|
55
|
+
@render_job = RenderJob.new(options_hash)
|
61
56
|
|
62
|
-
|
57
|
+
result = ''
|
58
|
+
set_up_rows
|
59
|
+
@chart.each_pair { |_, row| result << row.render(@render_job) + NEWLINE }
|
60
|
+
contained = ChartContainer.new(@render_job).container(result)
|
61
|
+
rendered = "#{contained}\n#{(show_summary ? print_text_info(@render_job) : '')}"
|
63
62
|
reset
|
64
63
|
options_hash[:color] ? rendered : (rendered.uncolorize)
|
65
64
|
end
|
66
65
|
|
67
|
-
def container(rendered_string)
|
68
|
-
plain_string = rendered_string.split("\n")[0].uncolorize
|
69
|
-
width = ([plain_string.rindex(TICK_ON_LINE_END_CHAR)||0, (plain_string.rindex(LINE_CHAR)||0)].max)+1
|
70
|
-
top = []
|
71
|
-
width.times { top << TICK_CHAR }
|
72
|
-
top[0] = TOP_LEFT_CORNER_CHAR
|
73
|
-
top[-1] = TOP_RIGHT_CORNER_CHAR
|
74
|
-
scaled_tick_locations.each { |i| top[i] = TOP_ON_LINE_CHAR if top[i] == TICK_CHAR }
|
75
|
-
|
76
|
-
bottom = top.dup.join
|
77
|
-
top = top.join
|
78
|
-
bottom[0], bottom[-1] = BOTTOM_LEFT_CORNER_CHAR, BOTTOM_RIGHT_CORNER_CHAR
|
79
|
-
bottom.gsub!(TOP_ON_LINE_CHAR, BOTTOM_ON_LINE_CHAR)
|
80
|
-
|
81
|
-
|
82
|
-
"#{spacer(-1) + top}\n#{add_names(rendered_string)}#{spacer(-1) + bottom}\n#{x_axis_legend}"
|
83
|
-
end
|
84
|
-
|
85
|
-
def closest(arr, val) #returns the index of the closest-matching element of the array
|
86
|
-
closest = arr.map { |elem| (elem-val).abs }
|
87
|
-
closest.index(closest.min)
|
88
|
-
end
|
89
|
-
|
90
|
-
def tick_locations
|
91
|
-
@tick_locations ||=
|
92
|
-
(
|
93
|
-
result = [] #locations of the ticks
|
94
|
-
tick_values = [] #value for every single space on the chart
|
95
|
-
(duration+1).times { |i| tick_values<<((data_range.to_f/duration)*i) }
|
96
|
-
pretty_tick_values.each { |val| result<<closest(tick_values, val) }
|
97
|
-
result
|
98
|
-
)
|
99
|
-
end
|
100
|
-
|
101
|
-
def pretty_tick_values
|
102
|
-
@pretty_tick_values ||=
|
103
|
-
(
|
104
|
-
arr = [0]
|
105
|
-
(data_range(:round)/tick_freq).times { arr<<arr.last+tick_freq }
|
106
|
-
arr
|
107
|
-
)
|
108
|
-
end
|
109
|
-
|
110
|
-
def tick_freq
|
111
|
-
@tick_freq ||=
|
112
|
-
(
|
113
|
-
result = 10
|
114
|
-
while (result*10)/duration<data_range/5 && result*10 < data_range
|
115
|
-
result*=10
|
116
|
-
end
|
117
|
-
ideal_scale > 1 ? result/=2 : result #If we've upscaled at all, add more tick lines to compensate.
|
118
|
-
data_range(:round)/result < usable_space/20 ? result/=2 : result #If we've got too few lines, add more!
|
119
|
-
result
|
120
|
-
)
|
121
|
-
end
|
122
|
-
|
123
66
|
def scaled_tick_locations
|
124
67
|
@scaled_tick_locations ||= tick_locations.map { |val| val*scale }
|
125
68
|
end
|
126
69
|
|
127
|
-
def
|
128
|
-
|
129
|
-
result =
|
130
|
-
@chart.each_with_index do |(k, row), i|
|
131
|
-
result<< "#{spacer(row.name)}#{row.name(true)}:#{lines[i]}\n"
|
132
|
-
end
|
133
|
-
result
|
134
|
-
end
|
135
|
-
|
136
|
-
def x_axis_legend
|
137
|
-
x_axis = []
|
138
|
-
ticks = tick_locations
|
139
|
-
usable_space.times { x_axis<<' ' }
|
140
|
-
|
141
|
-
odd_tick_locations = scaled_tick_locations.values_at(*scaled_tick_locations.each_index.select { |i| i.even? })
|
142
|
-
odd_ticks = ticks.values_at(*ticks.each_index.select { |i| i.even? })
|
143
|
-
|
144
|
-
odd_tick_locations.each_with_index do |l, i|
|
145
|
-
x_axis[l]=odd_ticks[i]
|
146
|
-
end
|
147
|
-
|
148
|
-
x_axis.map! do |val|
|
149
|
-
val.is_a?(Integer) ? translate_time(val) : ' '
|
150
|
-
end
|
151
|
-
|
152
|
-
spacer('time')+"#{'time'}:#{fill_in_labels(x_axis)}"
|
153
|
-
end
|
154
|
-
|
155
|
-
def fill_in_labels(arr)
|
156
|
-
result = ''
|
157
|
-
leave_blank = 0
|
158
|
-
arr.each do |val|
|
159
|
-
if val == ' ' &&
|
160
|
-
if leave_blank>0
|
161
|
-
result << ''
|
162
|
-
leave_blank-=1
|
163
|
-
else
|
164
|
-
result<<val
|
165
|
-
end
|
166
|
-
else
|
167
|
-
leave_blank += (str = "#{val}").length-1
|
168
|
-
result<<str
|
169
|
-
end
|
170
|
-
end
|
171
|
-
result
|
172
|
-
end
|
173
|
-
|
174
|
-
def print_text_info
|
175
|
-
result = spacer(-1)
|
70
|
+
def print_text_info(render_job)
|
71
|
+
# return ''
|
72
|
+
result = @spacer.space(-1)
|
176
73
|
|
177
74
|
@text_info.length.times do |i|
|
178
|
-
if (result.split("\n")[-1] + @text_info[i]).uncolorize.length >
|
179
|
-
result << "\n" + spacer(-1) + @text_info[i] + ", "
|
75
|
+
if (result.split("\n")[-1] + @text_info[i]).uncolorize.length > render_job.width
|
76
|
+
result << "\n" + @spacer.space(-1) + @text_info[i] + ", "
|
180
77
|
else
|
181
78
|
result << "#{@text_info[i]}, "
|
182
79
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative 'soperf_helpers'
|
2
|
+
require_relative 'box_drawing_chars'
|
3
|
+
require 'colorize'
|
4
|
+
|
5
|
+
module SoPerf
|
6
|
+
class ChartContainer
|
7
|
+
include BoxDrawingChars
|
8
|
+
include TimeHelper
|
9
|
+
|
10
|
+
def initialize(render_job)
|
11
|
+
@render_job = render_job
|
12
|
+
@spacer = @render_job.spacer
|
13
|
+
@scaled_tick_locations = render_job.scaled_tick_locations
|
14
|
+
end
|
15
|
+
|
16
|
+
def container(rendered_string)
|
17
|
+
plain_string = rendered_string.split("\n")[0].uncolorize
|
18
|
+
width = ([plain_string.rindex(TICK_ON_LINE_END_CHAR)||0, (plain_string.rindex(LINE_CHAR)||0)].max)+1
|
19
|
+
top = []
|
20
|
+
width.times { top << TICK_CHAR }
|
21
|
+
top[0] = TOP_LEFT_CORNER_CHAR
|
22
|
+
top[-1] = TOP_RIGHT_CORNER_CHAR
|
23
|
+
@render_job.scaled_tick_locations.each { |i| top[i] = TOP_ON_LINE_CHAR if top[i] == TICK_CHAR }
|
24
|
+
|
25
|
+
bottom = top.dup.join
|
26
|
+
top = top.join
|
27
|
+
bottom[0], bottom[-1] = BOTTOM_LEFT_CORNER_CHAR, BOTTOM_RIGHT_CORNER_CHAR
|
28
|
+
bottom.gsub!(TOP_ON_LINE_CHAR, BOTTOM_ON_LINE_CHAR)
|
29
|
+
|
30
|
+
"#{@spacer.space(-1) + top}\n#{add_names(rendered_string)}#{@spacer.space(-1) + bottom}\n#{x_axis_legend}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def x_axis_legend
|
34
|
+
x_axis = Array.new(@render_job.width) { ' ' }
|
35
|
+
odd_tick_locations = @scaled_tick_locations.values_at(*@scaled_tick_locations.each_index.select { |i| i.even? })
|
36
|
+
|
37
|
+
odd_ticks = @render_job.pretty_tick_values.values_at(*@render_job.pretty_tick_values.each_index.select { |i| i.even? })
|
38
|
+
|
39
|
+
odd_tick_locations.each_with_index do |l, i|
|
40
|
+
x_axis[l]=odd_ticks[i].to_i
|
41
|
+
end
|
42
|
+
x_axis.map! do |val|
|
43
|
+
val.is_a?(Integer) ? translate_time(val) : ' '
|
44
|
+
end
|
45
|
+
|
46
|
+
@spacer.space('time')+"#{'time'}:#{fill_in_labels(x_axis)}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def fill_in_labels(arr)
|
50
|
+
result = ''
|
51
|
+
leave_blank = 0
|
52
|
+
arr.each do |val|
|
53
|
+
if val == ' ' &&
|
54
|
+
if leave_blank>0
|
55
|
+
result << ''
|
56
|
+
leave_blank-=1
|
57
|
+
else
|
58
|
+
result<<val
|
59
|
+
end
|
60
|
+
else
|
61
|
+
leave_blank += (str = "#{val}").length-1
|
62
|
+
result<<str
|
63
|
+
end
|
64
|
+
end
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_names(rendered_string)
|
69
|
+
lines = rendered_string.split("\n")
|
70
|
+
result = ''
|
71
|
+
@render_job.names.each_with_index do |name, i|
|
72
|
+
result<< "#{@spacer.space(name.uncolorize)}#{name}:#{lines[i]}\n"
|
73
|
+
end
|
74
|
+
result
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/soperf/color_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative 'box_drawing_chars'
|
2
2
|
|
3
3
|
module SoPerf
|
4
|
-
class
|
4
|
+
class ColorHelper
|
5
5
|
include BoxDrawingChars
|
6
6
|
@@use_color = true
|
7
7
|
|
@@ -28,11 +28,11 @@ module SoPerf
|
|
28
28
|
def self.colorize(str, color)
|
29
29
|
if @@use_color
|
30
30
|
str.gsub(
|
31
|
-
TICK_CHAR,
|
32
|
-
TICK_ON_LINE_CHAR,
|
33
|
-
TICK_ON_LINE_START_CHAR,
|
34
|
-
TICK_ON_LINE_END_CHAR,
|
35
|
-
SINGLE_SPACE_LINE,
|
31
|
+
TICK_CHAR, ColorHelper.color(TICK_CHAR, color)).gsub(
|
32
|
+
TICK_ON_LINE_CHAR, ColorHelper.color(TICK_ON_LINE_CHAR, color)).gsub(
|
33
|
+
TICK_ON_LINE_START_CHAR, ColorHelper.color(TICK_ON_LINE_START_CHAR, color)).gsub(
|
34
|
+
TICK_ON_LINE_END_CHAR, ColorHelper.color(TICK_ON_LINE_END_CHAR, color)).gsub(
|
35
|
+
SINGLE_SPACE_LINE, ColorHelper.color(SINGLE_SPACE_LINE, color))
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require_relative 'soperf_helpers'
|
2
|
+
|
3
|
+
module SoPerf
|
4
|
+
class RenderJob
|
5
|
+
include TerminalHelper
|
6
|
+
include ValueFinder
|
7
|
+
attr_accessor :width, :scale, :raw_duration, :duration, :spacer,
|
8
|
+
:tick_frequency, :pretty_tick_values, :tick_locations,
|
9
|
+
:each_space_values, :scaled_tick_locations, :use_color,
|
10
|
+
:names, :longest_name
|
11
|
+
|
12
|
+
def initialize(options_hash)
|
13
|
+
options = default_render_options.merge(options_hash)
|
14
|
+
raise StandardError if options[:duration].nil?
|
15
|
+
|
16
|
+
@names = options[:names]
|
17
|
+
@spacer = options[:spacer]
|
18
|
+
@use_color = options[:color]
|
19
|
+
@width = options.has_key?(:width) ? options[:width] : usable_space(terminal_width, options[:longest_name])
|
20
|
+
puts terminal_width
|
21
|
+
@raw_duration = options[:duration]
|
22
|
+
@duration = ((options[:duration]/10.0).ceil*10)
|
23
|
+
@scale = @width/@duration.to_f
|
24
|
+
@tick_frequency = tick_frequency
|
25
|
+
@pretty_tick_values = pretty_tick_values
|
26
|
+
@tick_locations = tick_locations
|
27
|
+
@each_space_values = values_for_each_space
|
28
|
+
@scaled_tick_locations = scaled_tick_locations
|
29
|
+
@longest_name = options[:longest_name]
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_render_options
|
33
|
+
{ duration: nil,
|
34
|
+
longest_name: 0,
|
35
|
+
color: true,
|
36
|
+
summary: true,
|
37
|
+
spacer: Spacer.new }
|
38
|
+
end
|
39
|
+
|
40
|
+
def values_for_each_space
|
41
|
+
result = []
|
42
|
+
count = 0
|
43
|
+
(@width+1).times do
|
44
|
+
result << count
|
45
|
+
count += @duration/@width.to_f
|
46
|
+
end
|
47
|
+
@pretty_tick_values.each do |val|
|
48
|
+
index = closest(result, val)
|
49
|
+
result[index] = val
|
50
|
+
end
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
def tick_locations
|
55
|
+
result = [] #locations of the ticks
|
56
|
+
tick_values = [] #value for every single space on the chart
|
57
|
+
(@width+1).times { |i| tick_values<<((@duration/@width.to_f)*i) }
|
58
|
+
@pretty_tick_values.each { |val| result<<closest(tick_values, val) }
|
59
|
+
result.map { |elem| elem/scale }
|
60
|
+
end
|
61
|
+
|
62
|
+
def tick_frequency
|
63
|
+
result = 10
|
64
|
+
while (result*10)/duration<@raw_duration/5 && result*10 < @raw_duration
|
65
|
+
result*=10
|
66
|
+
end
|
67
|
+
result/=2 if @scale > 1 #If we've upscaled at all, add more tick lines to compensate.
|
68
|
+
result/=2 if @duration/result < @width/20 #If we've got too few lines, add more!
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
def pretty_tick_values
|
73
|
+
arr = [0]
|
74
|
+
(@duration/@tick_frequency).times { arr<<arr.last+@tick_frequency }
|
75
|
+
arr.map { |val| val*@scale }
|
76
|
+
arr
|
77
|
+
end
|
78
|
+
|
79
|
+
def usable_space(base_width, longest_name) #Space for the chart,
|
80
|
+
base_width - longest_name - 10 #accounting for printing row names
|
81
|
+
end
|
82
|
+
|
83
|
+
def scaled_tick_locations
|
84
|
+
@tick_locations.map { |val| val*@scale }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/soperf/row.rb
CHANGED
@@ -4,18 +4,20 @@
|
|
4
4
|
require 'colorize'
|
5
5
|
require_relative 'color_helper'
|
6
6
|
require_relative 'box_drawing_chars'
|
7
|
-
require_relative '
|
7
|
+
require_relative 'soperf_helpers'
|
8
8
|
|
9
9
|
module SoPerf
|
10
10
|
class Row
|
11
11
|
include BoxDrawingChars
|
12
12
|
include TimeHelper
|
13
|
+
include ValueFinder
|
13
14
|
attr_accessor :contents, :color, :raw_range
|
14
15
|
|
15
|
-
def initialize(name, raw_range, color =
|
16
|
+
def initialize(name, raw_range, color = ColorHelper.pick_a_color)
|
16
17
|
@name = name.to_s
|
17
18
|
@color = color
|
18
19
|
@raw_range = raw_range
|
20
|
+
@raw_range = (raw_range.last..raw_range.first) if raw_range.first > raw_range.last
|
19
21
|
@use_color = true
|
20
22
|
@raw_duration = raw_range.last-raw_range.first
|
21
23
|
@pretty_duration = translate_time(@raw_duration)
|
@@ -29,32 +31,33 @@ module SoPerf
|
|
29
31
|
range.member?(int) ? 1 : 0
|
30
32
|
end
|
31
33
|
|
32
|
-
def raw_array(duration, range=raw_range)
|
33
|
-
contents
|
34
|
-
|
35
|
-
|
34
|
+
def raw_array(duration, range=raw_range, space_vals)
|
35
|
+
contents = Array.new(duration+1) { 0 }
|
36
|
+
starting_index = closest(space_vals, range.first)
|
37
|
+
ending_index = closest(space_vals, range.last)
|
38
|
+
(starting_index..ending_index).each { |i| contents[i]=1 }
|
36
39
|
contents
|
37
40
|
end
|
38
41
|
|
39
42
|
def scaled_range(scale)
|
40
|
-
(raw_range.first*
|
43
|
+
(scale*raw_range.first..scale*raw_range.last)
|
41
44
|
end
|
42
45
|
|
43
46
|
def name(colored = false)
|
44
|
-
colored ?
|
47
|
+
colored ? ColorHelper.color(@name, color) : @name
|
45
48
|
end
|
46
49
|
|
47
|
-
def render(
|
48
|
-
|
49
|
-
duration
|
50
|
-
@use_color
|
51
|
-
arr
|
52
|
-
translate(arr,
|
50
|
+
def render(render_job)
|
51
|
+
@render_job = render_job
|
52
|
+
duration = (render_job.duration*render_job.scale).to_i
|
53
|
+
@use_color = render_job.use_color
|
54
|
+
arr = raw_array(duration, raw_range, render_job.each_space_values)
|
55
|
+
translate(arr, render_job.scaled_tick_locations)
|
53
56
|
end
|
54
57
|
|
55
58
|
def add_duration(str)
|
56
59
|
look_ahead_spaces = (@pretty_duration.to_s).length+1
|
57
|
-
label =
|
60
|
+
label = ColorHelper.color(@pretty_duration.to_s, color)
|
58
61
|
if str.rindex(TICK_ON_LINE_END_CHAR)
|
59
62
|
index = str.rindex(TICK_ON_LINE_END_CHAR)
|
60
63
|
char = TICK_ON_LINE_END_CHAR
|
@@ -115,7 +118,7 @@ module SoPerf
|
|
115
118
|
str[-1]=TICK_ON_LINE_CHAR if str[-1]==TICK_CHAR
|
116
119
|
str[-1]=LINE_CHAR if str[-1]==WHITESPACE_CHAR
|
117
120
|
|
118
|
-
result =
|
121
|
+
result = ColorHelper.colorize(add_duration(str), color)
|
119
122
|
@use_color ? result : result.uncolorize
|
120
123
|
end
|
121
124
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative 'box_drawing_chars'
|
2
|
+
|
3
|
+
module SoPerf
|
4
|
+
|
5
|
+
class Spacer
|
6
|
+
def initialize(chars=0)
|
7
|
+
chars = chars.length if chars.is_a?(String)
|
8
|
+
@length = chars
|
9
|
+
end
|
10
|
+
|
11
|
+
def space(i=0)
|
12
|
+
i = i.length if i.is_a?(String)
|
13
|
+
spacer = ''
|
14
|
+
(@length-i).times { spacer<<' ' }
|
15
|
+
spacer
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module TerminalHelper
|
20
|
+
def terminal_width
|
21
|
+
`/usr/bin/env tput cols`.to_i
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ValueFinder
|
26
|
+
def closest(arr, val) #returns the index of the closest-matching element of the array
|
27
|
+
closest = arr.map { |elem| (elem-val).abs }
|
28
|
+
closest.index(closest.min)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module TimeHelper
|
33
|
+
def translate_time(val)
|
34
|
+
val = val.abs.round(2)
|
35
|
+
if val == 0
|
36
|
+
0
|
37
|
+
else
|
38
|
+
res = val
|
39
|
+
if res/1000.0 >= 1
|
40
|
+
res = res/1000.0 #to seconds
|
41
|
+
if res/60.0 >= 1
|
42
|
+
res = res/60.0
|
43
|
+
if res/60.0 >= 1
|
44
|
+
res = res/60.0
|
45
|
+
if res/24 >= 1
|
46
|
+
res = res/24
|
47
|
+
format(res, "d")
|
48
|
+
else
|
49
|
+
format(res, "h")
|
50
|
+
end
|
51
|
+
else
|
52
|
+
format(res, "m")
|
53
|
+
end
|
54
|
+
else
|
55
|
+
format(res, "s")
|
56
|
+
end
|
57
|
+
else
|
58
|
+
format(res, "ms")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def format(res, unit)
|
64
|
+
"#{res.round(2).to_s.gsub(/\.0$/, '')}#{unit}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/soperf.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require './lib/soperf'
|
4
|
+
require './lib/soperf/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "soperf"
|
@@ -17,7 +17,6 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_runtime_dependency 'highline'
|
21
20
|
spec.add_runtime_dependency 'colorize'
|
22
21
|
|
23
22
|
spec.add_development_dependency "bundler", "~> 1.7"
|
@@ -5,11 +5,11 @@ require_relative '../../lib/soperf/color_helper'
|
|
5
5
|
|
6
6
|
describe 'SoPerf::ColorPicker' do
|
7
7
|
before(:all) do
|
8
|
-
@picker = lambda { SoPerf::
|
8
|
+
@picker = lambda { SoPerf::ColorHelper.pick_a_color }
|
9
9
|
end
|
10
10
|
|
11
11
|
before(:each) do
|
12
|
-
SoPerf::
|
12
|
+
SoPerf::ColorHelper.reset_color_index
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'should not select the same color twice consecutively' do
|
@@ -24,10 +24,10 @@ describe 'SoPerf::ColorPicker' do
|
|
24
24
|
|
25
25
|
it 'should reset the color index' do
|
26
26
|
5.times do |i|
|
27
|
-
SoPerf::
|
27
|
+
SoPerf::ColorHelper.reset_color_index
|
28
28
|
color1 = @picker.call
|
29
29
|
i.times { @picker.call }
|
30
|
-
SoPerf::
|
30
|
+
SoPerf::ColorHelper.reset_color_index
|
31
31
|
expect(@picker.call).to eq color1
|
32
32
|
end
|
33
33
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: soperf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wesley Boynton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: highline
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ! '>='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ! '>='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: colorize
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,10 +71,12 @@ files:
|
|
85
71
|
- lib/soperf.rb
|
86
72
|
- lib/soperf/box_drawing_chars.rb
|
87
73
|
- lib/soperf/chart.rb
|
74
|
+
- lib/soperf/chart_container.rb
|
88
75
|
- lib/soperf/color_helper.rb
|
76
|
+
- lib/soperf/render_job.rb
|
89
77
|
- lib/soperf/row.rb
|
90
|
-
- lib/soperf/
|
91
|
-
- lib/soperf/
|
78
|
+
- lib/soperf/soperf_helpers.rb
|
79
|
+
- lib/soperf/version.rb
|
92
80
|
- soperf.gemspec
|
93
81
|
- spec/lib/chart_spec.rb
|
94
82
|
- spec/lib/color_picker_spec.rb
|
@@ -116,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
104
|
version: '0'
|
117
105
|
requirements: []
|
118
106
|
rubyforge_project:
|
119
|
-
rubygems_version: 2.
|
107
|
+
rubygems_version: 2.4.6
|
120
108
|
signing_key:
|
121
109
|
specification_version: 4
|
122
110
|
summary: Ascii table generator for performance metrics
|
data/lib/soperf/time_helper.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module SoPerf
|
2
|
-
module TimeHelper
|
3
|
-
def translate_time(val)
|
4
|
-
if val == 0
|
5
|
-
0
|
6
|
-
else
|
7
|
-
res = val
|
8
|
-
if res/1000.0 >= 1
|
9
|
-
res = res/1000.0 #to seconds
|
10
|
-
if res/60.0 >= 1
|
11
|
-
res = res/60.0
|
12
|
-
if res/60.0 >= 1
|
13
|
-
res = res/60.0
|
14
|
-
if res/24 >= 1
|
15
|
-
res = res/24
|
16
|
-
"#{res.to_s.gsub(/\.0$/, '')}d"
|
17
|
-
else
|
18
|
-
"#{res.to_s.gsub(/\.0$/, '')}h"
|
19
|
-
end
|
20
|
-
else
|
21
|
-
"#{res.to_s.gsub(/\.0$/, '')}m"
|
22
|
-
end
|
23
|
-
else
|
24
|
-
"#{res.to_s.gsub(/\.0$/, '')}s"
|
25
|
-
end
|
26
|
-
else
|
27
|
-
"#{res.to_s.gsub(/\.0$/, '')}ms"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|