15 Commits

Author SHA1 Message Date
kojix2
50de2bac48 v0.1.2 2020-07-31 11:19:04 +09:00
kojix2
eabc36b581 Fix styles and more 2020-07-30 16:33:08 +09:00
kojix2
5f979d2e85 Add barplot and scatterplot 2020-07-30 15:54:08 +09:00
kojix2
8536abc061 Use headers as series name 2020-07-30 15:08:09 +09:00
kojix2
b4856e45d0 Standing on the shoulders of CSV library. 2020-07-30 13:42:51 +09:00
kojix2
87a8af4957 v0.1.1 2020-07-30 12:48:47 +09:00
kojix2
09271ab6c3 Minor fix 2020-07-30 12:47:02 +09:00
kojix2
0110b70936 Refactoring parsers 2020-07-30 12:44:31 +09:00
kojix2
9859cd0213 Improved parser 2020-07-30 11:48:27 +09:00
kojix2
cb43796e3f Improved parser 2020-07-30 11:08:36 +09:00
kojix2
958ce45635 Improved permeability on pipelines 2020-07-30 10:37:20 +09:00
kojix2
203e48e0ed Fix a link in README.md 2020-07-29 21:36:27 +09:00
kojix2
155a0821d3 Add width and height 2020-07-29 19:02:20 +09:00
kojix2
4a49711d57 Add lineplot 2020-07-29 18:24:08 +09:00
kojix2
e69d1caed7 Add command.rb 2020-07-29 17:01:39 +09:00
4 changed files with 153 additions and 44 deletions

View File

@@ -5,7 +5,7 @@
Create ASCII charts on the terminal with data from standard streams in the pipeline.
:bar_chart: Powered by [UnicodePlot](https://github.com/kojix2/uplot)
:bar_chart: Powered by [UnicodePlot](https://github.com/red-data-tools/unicode_plot.rb)
:construction: Under development

View File

@@ -1,46 +1,6 @@
require 'uplot/version'
require 'unicode_plot'
require 'optparse'
require 'uplot/version'
require 'uplot/command.rb'
module Uplot
class Command
def initialize(argv)
@params = {}
@ptype = nil
parse_options(argv)
end
def parse_options(argv)
parser = OptionParser.new
parser.order!(argv)
@ptype = argv.shift
subparsers = Hash.new do |_h, k|
warn "no such subcommand: #{k}"
exit 1
end
subparsers['hist'] = OptionParser.new.tap do |sub|
sub.on('--nbins VAL') { |v| @params[:nbins] = v.to_i }
sub.on('-p') { |v| @params[:p] = v }
end
subparsers[@ptype].parse!(argv) unless argv.empty?
end
def run
input_lines = readlines.map(&:chomp)
case @ptype
when 'hist', 'histogram'
histogram(input_lines).render
end
puts input_lines if @params[:p]
end
def histogram(input_lines)
series = input_lines.map(&:to_f)
UnicodePlot.histogram(series, nbins: @params[:nbins])
end
end
end

149
lib/uplot/command.rb Normal file
View File

@@ -0,0 +1,149 @@
require 'optparse'
require 'csv'
module Uplot
class Command
def initialize(argv)
@params = {}
@ptype = nil
@headers = nil
@delimiter = "\t"
@output = false
parse_options(argv)
end
def create_parser
OptionParser.new do |opt|
opt.on('-o', '--output', TrueClass) { |v| @output = v }
opt.on('-d', '--delimiter VAL', String) { |v| @delimiter = v }
opt.on('-H', '--headers', TrueClass) { |v| @headers = v }
opt.on('-t', '--title VAL', String) { |v| @params[:title] = v }
opt.on('-w', '--width VAL', Numeric) { |v| @params[:width] = v }
opt.on('-h', '--height VAL', Numeric) { |v| @params[:height] = v }
opt.on('-b', '--border VAL', Numeric) { |v| @params[:border] = v }
opt.on('-m', '--margin VAL', Numeric) { |v| @params[:margin] = v }
opt.on('-p', '--padding VAL', Numeric) { |v| @params[:padding] = v }
opt.on('-l', '--labels', TrueClass) { |v| @params[:labels] = v }
end
end
def parse_options(argv)
main_parser = create_parser
parsers = Hash.new { |h, k| h[k] = create_parser }
parsers['hist'] .on('--nbins VAL', Numeric) { |v| @params[:nbins] = v }
parsers['histogram'] = parsers['hist']
parsers['lineplot'] = parsers['line']
parsers['lineplots'] = parsers['lines']
parsers['scatterplot'] = parsers['scatter']
parsers['barplot'] = parsers['bar']
parsers['boxplot'] = parsers['box']
parsers.default = nil
main_parser.banner = <<~MSG
Usage:\tuplot <command> [options]
Command:\t#{parsers.keys.join(' ')}
MSG
main_parser.order!(argv)
@ptype = argv.shift
unless parsers.has_key?(@ptype)
warn "unrecognized command '#{@ptype}'"
exit 1
end
parser = parsers[@ptype]
parser.parse!(argv) unless argv.empty?
end
def run
# Sometimes the input file does not end with a newline code.
while input = Kernel.gets(nil)
input.freeze
data, headers = preprocess(input)
case @ptype
when 'hist', 'histogram'
histogram(data, headers)
when 'line', 'lineplot'
line(data, headers)
when 'lines'
lines(data, headers)
when 'scatter', 'scatterplot'
scatter(data, headers)
when 'bar', 'barplot'
barplot(data, headers)
when 'box', 'boxplot'
boxplot(data, headers)
end.render($stderr)
print input if @output
end
end
def preprocess(input)
data = CSV.parse(input, col_sep: @delimiter)
if @headers
headers = data.shift
data = data.transpose
[data, headers]
else
data = data.transpose
[data, nil]
end
end
def barplot(data, headers)
@params[:title] ||= headers[1] if headers
UnicodePlot.barplot(data[0], data[1].map(&:to_f), **@params)
end
def histogram(data, headers)
@params[:title] ||= headers[0] if headers # labels?
series = data[0].map(&:to_f)
UnicodePlot.histogram(series, **@params.compact)
end
def line(data, headers)
if data.size == 1
@params[:name] ||= headers[0] if headers
y = data[0]
x = (1..y.size).to_a
else
@params[:name] ||= headers[1] if headers
x = data[0]
y = data[1]
end
x = x.map(&:to_f)
y = y.map(&:to_f)
UnicodePlot.lineplot(x, y, **@params.compact)
end
def lines(data, headers)
data.map! { |series| series.map(&:to_f) }
@params[:name] ||= headers[1] if headers
plot = UnicodePlot.lineplot(data[0], data[1], **@params.compact)
2.upto(data.size - 1) do |i|
UnicodePlot.lineplot!(plot, data[0], data[i], name: headers[i])
end
plot
end
def scatter(data, headers)
data.map! { |series| series.map(&:to_f) }
@params[:name] ||= headers[1] if headers
plot = UnicodePlot.scatterplot(data[0], data[1], **@params.compact)
2.upto(data.size - 1) do |i|
UnicodePlot.scatterplot!(plot, data[0], data[i], name: headers[i])
end
plot
end
def boxplot(data, headers)
headers ||= (1..data.size).to_a
data.map! { |series| series.map(&:to_f) }
plot = UnicodePlot.boxplot(headers[0], data[0], **@params.compact)
1.upto(data.size - 1) do |i|
UnicodePlot.boxplot!(plot, headers[i], data[i])
end
plot
end
end
end

View File

@@ -1,3 +1,3 @@
module Uplot
VERSION = '0.1.0'.freeze
VERSION = '0.1.2'.freeze
end