inkplot 0.1.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.
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Inkplot
4
+ VERSION = "0.1.0"
5
+ end
data/lib/inkplot.rb ADDED
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "inkplot/version"
4
+ require_relative "inkplot/core"
5
+ require_relative "inkplot/renderers/svg"
6
+
7
+ module Inkplot
8
+ class Error < StandardError; end
9
+
10
+ class Config
11
+ attr_accessor :font
12
+ end
13
+
14
+ Series = Struct.new(:type, :points, :label, :color, :options, keyword_init: true)
15
+ Scene = Struct.new(:width, :height, :background, :clip, :marks, :elements, keyword_init: true)
16
+
17
+ class << self
18
+ def config = @config ||= Config.new
19
+
20
+ def plot(width: 640, height: 360, theme: :light, **)
21
+ builder = Builder.new(width: width, height: height, theme: theme, **)
22
+ yield builder if block_given?
23
+ Chart.new(builder)
24
+ end
25
+
26
+ def line(data, values = nil, x: nil, y: nil, color: nil, title: nil, x_label: nil, y_label: nil, **)
27
+ quick(:line, data, values, x:, y:, color:, title:, x_label:, y_label:, **)
28
+ end
29
+
30
+ def scatter(data, values = nil, x: nil, y: nil, size: nil, color: nil, title: nil, x_label: nil, y_label: nil, **)
31
+ quick(:scatter, data, values, x:, y:, size:, color:, title:, x_label:, y_label:, **)
32
+ end
33
+
34
+ def bar(data, horizontal: false, title: nil, x_label: nil, y_label: nil, **options)
35
+ chart_options, mark_options = options.partition { |key, _| %i[width height theme].include?(key) }.map(&:to_h)
36
+ builder = Builder.new(**chart_options, title:, x_label:, y_label:)
37
+ if horizontal
38
+ builder.bar(data, horizontal: true, **mark_options)
39
+ else
40
+ builder.bar(data, **mark_options)
41
+ end
42
+ Chart.new(builder)
43
+ end
44
+
45
+ def sparkline(values)
46
+ values = values.filter_map { |value| Data.number(value) }
47
+ return "" if values.empty?
48
+
49
+ low, high = values.minmax
50
+ glyphs = "▁▂▃▄▅▆▇█"
51
+ return glyphs[3] * values.length if low == high
52
+
53
+ values.map { |value| glyphs[((value - low) / (high - low) * 7).round] }.join
54
+ end
55
+
56
+ private
57
+
58
+ def quick(type, data, values = nil, x:, y:, size: nil, color: nil, title: nil, x_label: nil, y_label: nil, **options)
59
+ chart_options, mark_options = options.partition { |key, _| %i[width height theme].include?(key) }.map(&:to_h)
60
+ builder = Builder.new(**chart_options, title:, x_label:, y_label:)
61
+ if color && Data.records?(data)
62
+ Data.rows(data, x:, y:, size:, group: color).group_by { |point| point[:group] }.each do |group, points|
63
+ builder.add(type, points, label: group.to_s, **mark_options)
64
+ end
65
+ else
66
+ builder.add(type, Data.points(data, values, x:, y:, size:), **mark_options)
67
+ end
68
+ Chart.new(builder)
69
+ end
70
+ end
71
+ end
data/sig/inkplot.rbs ADDED
@@ -0,0 +1,36 @@
1
+ module Inkplot
2
+ VERSION: String
3
+
4
+ class Config
5
+ attr_accessor font: String?
6
+ end
7
+
8
+ class Builder
9
+ def title: (String value) -> String
10
+ def x_axis: (?label: String?, ?type: Symbol?, ?scale: Symbol?, ?min: untyped, ?max: untyped, ?order: Array[untyped]?) -> Hash[Symbol, untyped]
11
+ def y_axis: (?label: String?, ?type: Symbol?, ?scale: Symbol?, ?min: untyped, ?max: untyped) -> Hash[Symbol, untyped]
12
+ def legend: (?position: Symbol) -> Hash[Symbol, Symbol]
13
+ def line: (untyped x, ?untyped y, ?label: String?, ?color: String?, ?dash: bool, ?gaps: Symbol, **untyped options) -> Builder
14
+ def scatter: (untyped x, ?untyped y, ?label: String?, ?color: String?, ?size: untyped, **untyped options) -> Builder
15
+ def area: (untyped x, ?untyped y, ?label: String?, ?color: String?, **untyped options) -> Builder
16
+ def step: (untyped x, ?untyped y, ?label: String?, ?color: String?, **untyped options) -> Builder
17
+ def bar: (untyped categories, ?untyped values, ?label: String?, ?color: String?, ?horizontal: bool, ?stacked: bool, **untyped options) -> Builder
18
+ def hline: (Numeric value, ?label: String?, ?color: String?, ?dash: bool) -> Array[Hash[Symbol, untyped]]
19
+ def vline: (untyped value, ?label: String?, ?color: String?, ?dash: bool) -> Array[Hash[Symbol, untyped]]
20
+ end
21
+
22
+ class Chart
23
+ attr_reader builder: Builder
24
+ attr_reader width: Integer
25
+ attr_reader height: Integer
26
+ def to_svg: (?width: Integer, ?height: Integer) -> String
27
+ def save: (String | _Path path, ?width: Integer, ?height: Integer) -> String | _Path
28
+ end
29
+
30
+ def self.config: () -> Config
31
+ def self.plot: (?width: Integer, ?height: Integer, ?theme: Symbol, **untyped options) { (Builder) -> void } -> Chart
32
+ def self.line: (untyped data, ?untyped values, ?x: untyped, ?y: untyped, ?color: untyped, ?title: String?, ?x_label: String?, ?y_label: String?, **untyped options) -> Chart
33
+ def self.scatter: (untyped data, ?untyped values, ?x: untyped, ?y: untyped, ?size: untyped, ?color: untyped, ?title: String?, ?x_label: String?, ?y_label: String?, **untyped options) -> Chart
34
+ def self.bar: (untyped data, ?horizontal: bool, ?title: String?, ?x_label: String?, ?y_label: String?, **untyped options) -> Chart
35
+ def self.sparkline: (Array[untyped] values) -> String
36
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inkplot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yudai Takada
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rake
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '13.0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '13.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rbs
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rubocop
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.0'
68
+ description: Build line, bar, scatter, and other charts as standalone SVG.
69
+ email:
70
+ - t.yudai92@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".rubocop.yml"
76
+ - CHANGELOG.md
77
+ - LICENSE.txt
78
+ - README.md
79
+ - Rakefile
80
+ - bench/inkplot.rb
81
+ - examples/gallery.rb
82
+ - examples/gallery/01-line.svg
83
+ - examples/gallery/02-line-gaps.svg
84
+ - examples/gallery/03-series.svg
85
+ - examples/gallery/04-scatter.svg
86
+ - examples/gallery/05-bars.svg
87
+ - examples/gallery/06-horizontal-bars.svg
88
+ - examples/gallery/07-grouped-bars.svg
89
+ - examples/gallery/08-stacked-bars.svg
90
+ - examples/gallery/10-area.svg
91
+ - examples/gallery/11-step.svg
92
+ - examples/gallery/README.md
93
+ - lib/inkplot.rb
94
+ - lib/inkplot/core.rb
95
+ - lib/inkplot/renderers/svg.rb
96
+ - lib/inkplot/version.rb
97
+ - sig/inkplot.rbs
98
+ homepage: https://github.com/rbgfx/inkplot
99
+ licenses:
100
+ - MIT
101
+ metadata:
102
+ homepage_uri: https://github.com/rbgfx/inkplot
103
+ source_code_uri: https://github.com/rbgfx/inkplot/tree/main
104
+ rubygems_mfa_required: 'true'
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 3.2.0
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubygems_version: 4.0.16
120
+ specification_version: 4
121
+ summary: SVG charts for Ruby
122
+ test_files: []