youplot 0.3.1 → 0.4.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.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module YouPlot
4
- VERSION = '0.3.1'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: youplot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-04 00:00:00.000000000 Z
11
+ date: 2021-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: unicode_plot
@@ -94,8 +94,7 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description: "Create ASCII charts on the terminal with data from standard streams
98
- in the \npipeline. \n"
97
+ description: A command line tool for Unicode Plotting
99
98
  email:
100
99
  - 2xijok@gmail.com
101
100
  executables:
@@ -110,11 +109,12 @@ files:
110
109
  - exe/youplot
111
110
  - lib/youplot.rb
112
111
  - lib/youplot/backends/processing.rb
113
- - lib/youplot/backends/unicode_plot_backend.rb
112
+ - lib/youplot/backends/unicode_plot.rb
114
113
  - lib/youplot/command.rb
115
- - lib/youplot/command/params.rb
116
- - lib/youplot/command/parser.rb
117
- - lib/youplot/dsv_reader.rb
114
+ - lib/youplot/dsv.rb
115
+ - lib/youplot/options.rb
116
+ - lib/youplot/parameters.rb
117
+ - lib/youplot/parser.rb
118
118
  - lib/youplot/version.rb
119
119
  homepage: https://github.com/kojix2/youplot
120
120
  licenses:
@@ -135,8 +135,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
135
  - !ruby/object:Gem::Version
136
136
  version: '0'
137
137
  requirements: []
138
- rubygems_version: 3.1.4
138
+ rubygems_version: 3.2.15
139
139
  signing_key:
140
140
  specification_version: 4
141
- summary: Create Ascii charts on your terminal.
141
+ summary: A command line tool for Unicode Plotting
142
142
  test_files: []
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module YouPlot
4
- class Command
5
- # UnicodePlot parameters.
6
- # * Normally in a Ruby program, you might use hash for the parameter object.
7
- # * Here, I use Struct for 2 safety reason.
8
- # * The keys are static in Struct.
9
- # * Struct does not conflict with keyword arguments. Hash dose.
10
- Params = Struct.new(
11
- # Sort me!
12
- :title,
13
- :width,
14
- :height,
15
- :border,
16
- :margin,
17
- :padding,
18
- :color,
19
- :xlabel,
20
- :ylabel,
21
- :labels,
22
- :symbol,
23
- :xscale,
24
- :nbins,
25
- :closed,
26
- :canvas,
27
- :xlim,
28
- :ylim,
29
- :grid,
30
- :name
31
- ) do
32
- def to_hc
33
- to_h.compact
34
- end
35
- end
36
- end
37
- end
@@ -1,277 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'optparse'
4
- require_relative 'params'
5
-
6
- module YouPlot
7
- class Command
8
- class Parser
9
- attr_reader :command, :params,
10
- :delimiter, :transpose, :headers, :pass, :output, :fmt,
11
- :color_names, :encoding, :debug
12
-
13
- def initialize
14
- @command = nil
15
- @params = Params.new
16
-
17
- @delimiter = "\t"
18
- @transpose = false
19
- @headers = nil
20
- @pass = false
21
- @output = $stderr
22
- @fmt = 'xyy'
23
- @encoding = nil
24
- @debug = false
25
- @color_names = false
26
- end
27
-
28
- def create_default_parser
29
- OptionParser.new do |opt|
30
- opt.program_name = 'YouPlot'
31
- opt.version = YouPlot::VERSION
32
- opt.summary_width = 24
33
- opt.on_tail('') # Add a blank line at the end
34
- opt.separator('')
35
- opt.on('Common options:')
36
- opt.on('-O', '--pass [VAL]', 'file to output standard input data to [stdout]',
37
- 'for inserting YouPlot in the middle of Unix pipes') do |v|
38
- @pass = v || $stdout
39
- end
40
- opt.on('-o', '--output VAL', 'file to output results to [stderr]') do |v|
41
- @output = v
42
- end
43
- opt.on('-d', '--delimiter VAL', String, 'use DELIM instead of TAB for field delimiter') do |v|
44
- @delimiter = v
45
- end
46
- opt.on('-H', '--headers', TrueClass, 'specify that the input has header row') do |v|
47
- @headers = v
48
- end
49
- opt.on('-T', '--transpose', TrueClass, 'transpose the axes of the input data') do |v|
50
- @transpose = v
51
- end
52
- opt.on('-t', '--title VAL', String, 'print string on the top of plot') do |v|
53
- params.title = v
54
- end
55
- opt.on('-x', '--xlabel VAL', String, 'print string on the bottom of the plot') do |v|
56
- params.xlabel = v
57
- end
58
- opt.on('-y', '--ylabel VAL', String, 'print string on the far left of the plot') do |v|
59
- params.ylabel = v
60
- end
61
- opt.on('-w', '--width VAL', Integer, 'number of characters per row') do |v|
62
- params.width = v
63
- end
64
- opt.on('-h', '--height VAL', Numeric, 'number of rows') do |v|
65
- params.height = v
66
- end
67
- opt.on('-b', '--border VAL', String, 'specify the style of the bounding box') do |v|
68
- params.border = v.to_sym
69
- end
70
- opt.on('-m', '--margin VAL', Numeric, 'number of spaces to the left of the plot') do |v|
71
- params.margin = v
72
- end
73
- opt.on('-p', '--padding VAL', Numeric, 'space of the left and right of the plot') do |v|
74
- params.padding = v
75
- end
76
- opt.on('-c', '--color VAL', String, 'color of the drawing') do |v|
77
- params.color = v =~ /\A[0-9]+\z/ ? v.to_i : v.to_sym
78
- end
79
- opt.on('--[no-]labels', TrueClass, 'hide the labels') do |v|
80
- params.labels = v
81
- end
82
- opt.on('--encoding VAL', String, 'Specify the input encoding') do |v|
83
- @encoding = v
84
- end
85
- # Optparse adds the help option, but it doesn't show up in usage.
86
- # This is why you need the code below.
87
- opt.on('--help', 'print sub-command help menu') do
88
- puts opt.help
89
- exit
90
- end
91
- opt.on('--debug', TrueClass, 'print preprocessed data') do |v|
92
- @debug = v
93
- end
94
- yield opt if block_given?
95
- end
96
- end
97
-
98
- def main_parser
99
- @main_parser ||= create_default_parser do |main_parser|
100
- # Here, help message is stored in the banner.
101
- # Because help of main_parser may be referred by `sub_parser`.
102
-
103
- main_parser.banner = \
104
- <<~MSG
105
-
106
- Program: YouPlot (Tools for plotting on the terminal)
107
- Version: #{YouPlot::VERSION} (using UnicodePlot #{UnicodePlot::VERSION})
108
- Source: https://github.com/kojix2/youplot
109
-
110
- Usage: uplot <command> [options] <in.tsv>
111
-
112
- Commands:
113
- barplot bar draw a horizontal barplot
114
- histogram hist draw a horizontal histogram
115
- lineplot line draw a line chart
116
- lineplots lines draw a line chart with multiple series
117
- scatter s draw a scatter plot
118
- density d draw a density plot
119
- boxplot box draw a horizontal boxplot
120
- colors show the list of available colors
121
-
122
- count c draw a baplot based on the number of
123
- occurrences (slow)
124
-
125
- General options:
126
- --help print command specific help menu
127
- --version print the version of YouPlot
128
- MSG
129
-
130
- # Actually, main_parser can take common optional arguments.
131
- # However, these options dose not be shown in the help menu.
132
- # I think the main help should be simple.
133
- main_parser.on('--help', 'print sub-command help menu') do
134
- puts main_parser.banner
135
- puts
136
- exit
137
- end
138
- end
139
- end
140
-
141
- def sub_parser
142
- @sub_parser ||= create_default_parser do |parser|
143
- parser.banner = <<~MSG
144
-
145
- Usage: YouPlot #{command} [options] <in.tsv>
146
-
147
- Options for #{command}:
148
- MSG
149
-
150
- case command
151
-
152
- # If you type only `uplot` in the terminal.
153
- when nil
154
- warn main_parser.banner
155
- warn "\n"
156
- exit 1
157
-
158
- when :barplot, :bar
159
- parser.on_head('--symbol VAL', String, 'character to be used to plot the bars') do |v|
160
- params.symbol = v
161
- end
162
- parser.on_head('--xscale VAL', String, 'axis scaling') do |v|
163
- params.xscale = v
164
- end
165
- parser.on_head('--fmt VAL', String, 'xy : header is like x, y...', 'yx : header is like y, x...') do |v|
166
- @fmt = v
167
- end
168
-
169
- when :count, :c
170
- parser.on_head('--symbol VAL', String, 'character to be used to plot the bars') do |v|
171
- params.symbol = v
172
- end
173
-
174
- when :histogram, :hist
175
- parser.on_head('-n', '--nbins VAL', Numeric, 'approximate number of bins') do |v|
176
- params.nbins = v
177
- end
178
- parser.on_head('--closed VAL', String) do |v|
179
- params.closed = v
180
- end
181
- parser.on_head('--symbol VAL', String, 'character to be used to plot the bars') do |v|
182
- params.symbol = v
183
- end
184
-
185
- when :lineplot, :line
186
- parser.on_head('--canvas VAL', String, 'type of canvas') do |v|
187
- params.canvas = v
188
- end
189
- parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
190
- params.xlim = v.take(2)
191
- end
192
- parser.on_head('--ylim VAL', Array, 'plotting range for the y coordinate') do |v|
193
- params.ylim = v.take(2)
194
- end
195
- parser.on_head('--fmt VAL', String, 'xy : header is like x, y...', 'yx : header is like y, x...') do |v|
196
- @fmt = v
197
- end
198
-
199
- when :lineplots, :lines
200
- parser.on_head('--canvas VAL', String) do |v|
201
- params.canvas = v
202
- end
203
- parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
204
- params.xlim = v.take(2)
205
- end
206
- parser.on_head('--ylim VAL', Array, 'plotting range for the y coordinate') do |v|
207
- params.ylim = v.take(2)
208
- end
209
- parser.on_head('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...', 'xyy : header is like x, y1, y2, y2, y3...') do |v|
210
- @fmt = v
211
- end
212
-
213
- when :scatter, :s
214
- parser.on_head('--canvas VAL', String) do |v|
215
- params.canvas = v
216
- end
217
- parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
218
- params.xlim = v.take(2)
219
- end
220
- parser.on_head('--ylim VAL', Array, 'plotting range for the y coordinate') do |v|
221
- params.ylim = v.take(2)
222
- end
223
- parser.on_head('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...', 'xyy : header is like x, y1, y2, y2, y3...') do |v|
224
- @fmt = v
225
- end
226
-
227
- when :density, :d
228
- parser.on_head('--grid', TrueClass) do |v|
229
- params.grid = v
230
- end
231
- parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
232
- params.xlim = v.take(2)
233
- end
234
- parser.on_head('--ylim VAL', Array, 'plotting range for the y coordinate') do |v|
235
- params.ylim = v.take(2)
236
- end
237
- parser.on('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...', 'xyy : header is like x, y1, y2, y2, y3...') do |v|
238
- @fmt = v
239
- end
240
-
241
- when :boxplot, :box
242
- parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
243
- params.xlim = v.take(2)
244
- end
245
-
246
- when :colors
247
- parser.on_head('-n', '--names', 'show color names only', TrueClass) do |v|
248
- @color_names = v
249
- end
250
-
251
- else
252
- warn "uplot: unrecognized command '#{command}'"
253
- exit 1
254
- end
255
- end
256
- end
257
-
258
- def parse_options(argv = ARGV)
259
- begin
260
- main_parser.order!(argv)
261
- rescue OptionParser::ParseError => e
262
- warn "uplot: #{e.message}"
263
- exit 1
264
- end
265
-
266
- @command = argv.shift&.to_sym
267
-
268
- begin
269
- sub_parser.parse!(argv)
270
- rescue OptionParser::ParseError => e
271
- warn "uplot: #{e.message}"
272
- exit 1
273
- end
274
- end
275
- end
276
- end
277
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'csv'
4
-
5
- module YouPlot
6
- # Read and interpret Delimiter-separated values format file or stream.
7
- module DSVReader
8
- module_function
9
-
10
- def input(input, delimiter, headers, transpose)
11
- arr = parse_as_csv(input, delimiter)
12
- headers = get_headers(arr, headers, transpose)
13
- series = get_series(arr, headers, transpose)
14
- if headers.nil?
15
- Data.new(headers, series)
16
- else
17
- if headers.include?(nil)
18
- warn "\e[35mHeaders contains nil in it.\e[0m"
19
- elsif headers.include? ''
20
- warn "\e[35mHeaders contains \"\" in it.\e[0m"
21
- end
22
- h_size = headers.size
23
- s_size = series.size
24
- if h_size == s_size
25
- Data.new(headers, series)
26
- elsif h_size > s_size
27
- warn "\e[35mThe number of headers is greater than the number of series.\e[0m"
28
- exit 1
29
- elsif h_size < s_size
30
- warn "\e[35mThe number of headers is less than the number of series.\e[0m"
31
- exit 1
32
- end
33
- end
34
- end
35
-
36
- def parse_as_csv(input, delimiter)
37
- CSV.parse(input, col_sep: delimiter)
38
- .delete_if do |i|
39
- i == [] or i.all? nil
40
- end
41
- end
42
-
43
- # Transpose different sized ruby arrays
44
- # https://stackoverflow.com/q/26016632
45
- def transpose2(arr)
46
- Array.new(arr.map(&:length).max) { |i| arr.map { |e| e[i] } }
47
- end
48
-
49
- def get_headers(arr, headers, transpose)
50
- if headers
51
- if transpose
52
- arr.map(&:first)
53
- else
54
- arr[0]
55
- end
56
- end
57
- end
58
-
59
- def get_series(arr, headers, transpose)
60
- if transpose
61
- if headers
62
- arr.map { |row| row[1..-1] }
63
- else
64
- arr
65
- end
66
- elsif headers
67
- transpose2(arr[1..-1])
68
- else
69
- transpose2(arr)
70
- end
71
- end
72
- end
73
- end