tty-pie 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11c000927f796d72dc81d3c669f54a8c3bd4ef61c3da69abf0b9057ddc8cbe60
4
- data.tar.gz: d5504fe31f97866a694aeb8920787a6f88b865a4d7feae193eb6457e869f0e98
3
+ metadata.gz: 22d6cb76f39389059b746df28e9409d99ab1591d77edbe9f76bc1e9a7ea5e332
4
+ data.tar.gz: 9e735e70ab7286e7ae5a0ee3e2d949f0734f8e002b37cf82b685f31e7729b7f8
5
5
  SHA512:
6
- metadata.gz: abb3e24bee240ea3262e3db8de2e88a1013591355c1385e155c32c01c34cc336b7ce873eb8a946905e2e09a086ce59bba36d053a33cc2015610347b468c283b6
7
- data.tar.gz: 64891d4c43466f012af0594575f3197588cb40494cf35dacd2023bc5f59705601b9f6a898012b843cabc7a53dcbd0f170a086f057f727d947319fa0c0de60803
6
+ metadata.gz: 291a12624a6fd02557e4f47c7535580dc215574d3804df5c7da454be0d9f50514a1776e58ea7fd9f73008c3cfe4a3f6405b116864d603e7635b40c76c9179738
7
+ data.tar.gz: d248aef95ff8a16ba71dc28c3da25d13d65b5360effe61b5893fc7088f3c32e82406e83f8738f8708f6fd436cf684e9a7786d6a49587a8b02498b1deecf6f855
@@ -1,7 +1,24 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.2.0] - 2019-01-11
4
+
5
+ ### Added
6
+ * Add :colors for specifying array of colors to rotate through
7
+ * Add :format, :precision & :delimiter keys to legend for declaring custom formatting
8
+ * Add #reset call to clear data
9
+
10
+ ### Changed
11
+
12
+ * Change to allow specifying fill characters via :fill parameter
13
+ * Change #draw to #render to keep consistent with other libs
14
+ * Change #update to return instance
15
+
16
+ ### Fixed
17
+ * Fix legend alignment when paired with absolute positioning
18
+
3
19
  ## [v0.1.0] - 2018-08-14
4
20
 
5
21
  * Initial implementation and release
6
22
 
23
+ [v0.2.0]: https://github.com/piotrmurach/tty-pie/compare/v0.1.0...v0.2.0
7
24
  [v0.1.0]: https://github.com/piotrmurach/tty-pie/compare/v0.1.0
data/README.md CHANGED
@@ -48,14 +48,15 @@ Or install it yourself as:
48
48
  * [2.1 data](#21-data)
49
49
  * [2.2 add](#22-add)
50
50
  * [2.3 update](#23-update)
51
- * [2.4 draw](#24-draw)
51
+ * [2.4 render](#24-render)
52
52
  * [2.5 position](#25-position)
53
53
  * [2.6 radius](#26-radius)
54
54
  * [2.7 legend](#27-legend)
55
+ * [2.7.1 format](#271-format)
55
56
 
56
57
  ## 1. Usage
57
58
 
58
- To draw a pie chart you need to provide an array of data items:
59
+ To render a pie chart you need to provide an array of data items:
59
60
 
60
61
  ```ruby
61
62
  data = [
@@ -95,7 +96,7 @@ print pie_chart
95
96
 
96
97
  ### 2.1 data
97
98
 
98
- To draw a pie chart you need to provide data. A single data item is just a Ruby hash that can contain the following keys:
99
+ To render a pie chart you need to provide data. A single data item is just a Ruby hash that can contain the following keys:
99
100
 
100
101
  * `:name` - used for setting the entry name in legend
101
102
  * `:value` - used for calculating actual pie slice size
@@ -185,14 +186,14 @@ new_data = [
185
186
  pie_chart.update(new_data)
186
187
  ```
187
188
 
188
- ### 2.4 draw
189
+ ### 2.4 render
189
190
 
190
- Once a pie chart has been initialized use the `draw` or `to_s` method to return a string representation of the chart.
191
+ Once a pie chart has been initialized use the `render` or `to_s` method to return a string representation of the chart.
191
192
 
192
193
  To actually show it in a terminal, you need to print it:
193
194
 
194
195
  ```ruby
195
- print pie_chart.draw
196
+ print pie_chart.render
196
197
  # => this will render chart in terminal
197
198
  ```
198
199
 
@@ -235,6 +236,9 @@ You can control how the legend is displayed using the `:legend` keyword and hash
235
236
 
236
237
  * `:left` - used to determine spacing between a chart and a legend, defaults to `4` columns
237
238
  * `:line` - used to determine spacing between legend labels, defaults to `1` line
239
+ * `:format` - used to format a display label using template named strings
240
+ * `:precision` - used to determine currency display decimal places, defaults to `2`
241
+ * `:delimiter` - used to set thousands delimiter in currency format
238
242
 
239
243
  For example, to place a legend `10` columns away from the pie chart and separate each label by `2` lines do:
240
244
 
@@ -256,6 +260,110 @@ print pie_chart
256
260
  # +** x LTC 18.37%
257
261
  ```
258
262
 
263
+ #### 2.7.1 format
264
+
265
+ The `:format` uses Ruby's [format sequences](https://ruby-doc.org/core-2.5.0/Kernel.html#method-i-format) and named strings placeholders:
266
+
267
+ * `<label>` - the icon matching pie chart display
268
+ * `<name>` - the label name provided in data
269
+ * `<value>` - the label value provided in data, by default not displayed
270
+ * `<currency>` - the label value formatted as currency
271
+ * `<percent>` - the percent automatically calculated from data
272
+
273
+ By default the label is formatted according to the following pattern with named strings:
274
+
275
+ ```ruby
276
+ "%<label>s %<name>s %<percent>.2f%%"
277
+ ```
278
+
279
+ Given data items:
280
+
281
+ ```ruby
282
+ data = [
283
+ { name: 'BTC', value: 5977.12345, fill: '*' },
284
+ { name: 'BCH', value: 3045.2, fill: '+' },
285
+ { name: 'LTC', value: 2030.444, fill: 'x' }
286
+ ]
287
+ ```
288
+
289
+ The legend will show:
290
+
291
+ ```ruby
292
+ # =>
293
+ # x** * BTC 54.08%
294
+ # xxxx*****
295
+ # ++++xx*******
296
+ # ++++++******* + BCH 27.55%
297
+ # ++++++*******
298
+ # ++++*****
299
+ # +** x LTC 18.37%
300
+ ```
301
+
302
+ To display value together with percent, use `<value>` named string in the format:
303
+
304
+ ```ruby
305
+ legend: {
306
+ format: "%<label>s %<name>s %<value>d (%<percent>.2f%%)"
307
+ }
308
+ ```
309
+
310
+ The legend will show:
311
+
312
+ ```ruby
313
+ # =>
314
+ # x** * BTC 5977 (54.08%)
315
+ # xxxx*****
316
+ # ++++xx*******
317
+ # ++++++******* + BCH 3045 (27.55%)
318
+ # ++++++*******
319
+ # ++++*****
320
+ # +** x LTC 2030 (18.37%)
321
+ ```
322
+
323
+ To display value as currency use `<currency>` name string in the format:
324
+
325
+ ```ruby
326
+ legend: {
327
+ format: "%<label>s %<name>s $%<currency>s (%<percent>.0f%%)"
328
+ }
329
+ ```
330
+
331
+ The legend will show:
332
+
333
+ ```ruby
334
+ # =>
335
+ # x** * BTC $5,977 (54%)
336
+ # xxxx*****
337
+ # ++++xx*******
338
+ # ++++++******* + BCH $3,045 (28%)
339
+ # ++++++*******
340
+ # ++++*****
341
+ # +** x LTC $2,030 (18%)
342
+ ```
343
+
344
+ The currency can be further customised using `:precision` and `:delimiter` keys:
345
+
346
+ ```ruby
347
+ legend: {
348
+ format: "%<label>s %<name>s $%<currency>s (%<percent>.0f%%)",
349
+ precision: 3,
350
+ delimiter: '*'
351
+ }
352
+ ```
353
+
354
+ The legend will show:
355
+
356
+ ```ruby
357
+ # =>
358
+ # x** * BTC $5*977.123 (54%)
359
+ # xxxx*****
360
+ # ++++xx*******
361
+ # ++++++******* + BCH $3*045.200 (28%)
362
+ # ++++++*******
363
+ # ++++*****
364
+ # +** x LTC $2*030.444 (18%)
365
+ ```
366
+
259
367
  ## Development
260
368
 
261
369
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -9,4 +9,4 @@ data = [
9
9
 
10
10
  pie = TTY::Pie.new(data: data, radius: 10)
11
11
 
12
- puts pie.draw
12
+ puts pie
@@ -0,0 +1,16 @@
1
+ require_relative '../lib/tty-pie'
2
+
3
+ data = [
4
+ { name: 'BTC', value: 5977, color: :yellow },
5
+ { name: 'BCH', value: 3045, color: :green },
6
+ { name: 'LTC', value: 2030, color: :magenta },
7
+ ]
8
+
9
+ pie = TTY::Pie.new(
10
+ data: data,
11
+ legend: {
12
+ format: "%<label>s %<name>s $%<currency>s (%<percent>.0f%%)"
13
+ }
14
+ )
15
+
16
+ puts pie
@@ -28,6 +28,8 @@ module TTY
28
28
 
29
29
  attr_reader :fill
30
30
 
31
+ attr_reader :colors
32
+
31
33
  attr_reader :legend
32
34
 
33
35
  # Create pie chart
@@ -41,23 +43,26 @@ module TTY
41
43
  # @param [Integer] top
42
44
  # @param [Integer] left
43
45
  # @param [Integer] radius
44
- # @param [Boolean] legend
46
+ # @param [Hash,Boolean] legend
45
47
  # @param [String] fill
46
48
  # @param [Float] aspect_ratio
47
49
  #
48
50
  # @api public
49
- def initialize(data: [], top: nil, left: nil, radius: 10, legend: {}, fill: POINT_SYMBOL, aspect_ratio: 2)
51
+ def initialize(data: [], top: nil, left: nil, radius: 10,
52
+ legend: {}, fill: POINT_SYMBOL, aspect_ratio: 2,
53
+ colors: [])
50
54
  @data = data.dup
51
55
  @top = top
52
56
  @left = left
53
57
  @radius = radius
54
58
  @legend = legend
55
- @fill = fill
59
+ @fill = Array(fill)
60
+ @colors = Array(colors)
56
61
  @aspect_ratio = aspect_ratio
57
62
  @center_x = (left || 0) + radius * aspect_ratio
58
63
  @center_y = (top || 0) + radius
59
64
 
60
- @pastel = Pastel.new
65
+ @pastel = Pastel.new(enabled: !!colors)
61
66
  @cursor = TTY::Cursor
62
67
  end
63
68
 
@@ -77,11 +82,11 @@ module TTY
77
82
  # @api private
78
83
  def data_items
79
84
  total_value = total
80
- @data.map do |item|
85
+ @data.each_with_index.map do |item, i|
81
86
  percent = (item[:value] * 100) / total_value.to_f
82
- color_fill = item[:fill] || fill
83
- DataItem.new(item[:name], item[:value], percent,
84
- item.fetch(:color, false), color_fill)
87
+ color_fill = item[:fill] || fill[i % fill.size]
88
+ color = colors && !colors.empty? ? colors[i % colors.size] : item.fetch(:color, false)
89
+ DataItem.new(item[:name], item[:value], percent, color, color_fill)
85
90
  end
86
91
  end
87
92
 
@@ -105,6 +110,7 @@ module TTY
105
110
  # @api public
106
111
  def update(data)
107
112
  @data = data
113
+ self
108
114
  end
109
115
 
110
116
  # Draw a pie based on the provided data
@@ -112,12 +118,13 @@ module TTY
112
118
  # @return [String]
113
119
  #
114
120
  # @api public
115
- def draw
121
+ def render
116
122
  items = data_items
123
+ return '' if items.empty?
117
124
  angles = data_angles(items)
118
125
  output = []
119
126
 
120
- labels = items.map(&:to_label)
127
+ labels = items.map { |item| item.to_label(legend) }
121
128
  label_vert_space = legend_line
122
129
  label_horiz_space = legend_left
123
130
  label_offset = labels.size / 2
@@ -147,7 +154,9 @@ module TTY
147
154
  output << cursor.move_to(center_x + aspect_ratio * radius + label_horiz_space, center_y + y)
148
155
  end
149
156
  if labels_range.include?(y)
150
- output << ' ' * ((center_x - width) + label_horiz_space) if top.nil?
157
+ if top.nil?
158
+ output << ' ' * ((center_x - (left.to_i + width)) + label_horiz_space)
159
+ end
151
160
  output << labels[label_offset + y / label_vert_space]
152
161
  end
153
162
  end
@@ -157,7 +166,16 @@ module TTY
157
166
 
158
167
  output.join
159
168
  end
160
- alias to_s draw
169
+ alias to_s render
170
+
171
+ # Reset data
172
+ #
173
+ # @api public
174
+ def clear
175
+ @data = []
176
+ self
177
+ end
178
+ alias reset clear
161
179
 
162
180
  private
163
181
 
@@ -1,10 +1,13 @@
1
- # frozen_string_literal
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'pastel'
4
4
 
5
5
  module TTY
6
6
  class Pie
7
+ # Encapsulates a single data item
7
8
  class DataItem
9
+ LABEL_FORMAT = '%<label>s %<name>s %<percent>.2f%%'
10
+
8
11
  attr_accessor :name
9
12
 
10
13
  attr_accessor :value
@@ -26,7 +29,7 @@ module TTY
26
29
  @color = color
27
30
  @percent = percent
28
31
  @fill = fill
29
- @pastel = Pastel.new
32
+ @pastel = Pastel.new(enabled: !!color)
30
33
  end
31
34
 
32
35
  # The item start angle
@@ -38,13 +41,39 @@ module TTY
38
41
 
39
42
  # Convert a data item into a legend label
40
43
  #
44
+ # @param [Hash] legend
45
+ #
41
46
  # @return [String]
42
47
  #
43
48
  # @api private
44
- def to_label
45
- percent_fmt = '%.2f' % percent
49
+ def to_label(legend)
50
+ pattern = legend && legend[:format] || LABEL_FORMAT
51
+ precision = legend && legend[:precision] || 2
52
+ delimiter = legend && legend[:delimiter] || ','
53
+
46
54
  label = color ? @pastel.decorate(fill, color) : fill
47
- "#{label} #{name} #{percent_fmt}%"
55
+ currency = number_to_currency(value, precision: precision,
56
+ delimiter: delimiter)
57
+
58
+ format(pattern, label: label, name: name, value: value,
59
+ percent: percent, currency: currency)
60
+ end
61
+
62
+ # Convert a number to a currency
63
+ #
64
+ # @param [Numeric] value
65
+ # @param [Integer] precision
66
+ # @param [String] delimiter
67
+ #
68
+ # @return [String]
69
+ #
70
+ # @api private
71
+ def number_to_currency(value, precision: 2, delimiter: ',')
72
+ whole, part = value.to_s.split('.')
73
+ unless part.nil?
74
+ part = format("%.#{precision}f", part.to_f / 10**part.size)[1..-1]
75
+ end
76
+ "#{whole.gsub(/(\d)(?=(\d{3})+(?!\d))/, "\\1#{delimiter}")}#{part}"
48
77
  end
49
78
  end
50
79
  end # Pie
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Pie
5
- VERSION = "0.1.0".freeze
5
+ VERSION = "0.2.0"
6
6
  end # Pie
7
7
  end # TTY
@@ -8,7 +8,7 @@ RSpec.describe TTY::Pie, '#add' do
8
8
  pie << { name: 'BCH', value: 3045, fill: '+' }
9
9
  pie << { name: 'LTC', value: 2030, fill: 'x' }
10
10
 
11
- output = pie.draw
11
+ output = pie.render
12
12
 
13
13
  expect(output).to eq([
14
14
  " x** * BTC 54.08%\n",
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe TTY::Pie, ':color option' do
4
- it "draws a pie chart without colors" do
4
+ it "renders a pie chart without colors" do
5
5
  data = [
6
6
  { name: 'BTC', value: 5977, fill: '*' },
7
7
  { name: 'BCH', value: 3045, fill: '+' },
@@ -9,7 +9,7 @@ RSpec.describe TTY::Pie, ':color option' do
9
9
  ]
10
10
  pie = TTY::Pie.new(data: data, radius: 2)
11
11
 
12
- output = pie.draw
12
+ output = pie.render
13
13
 
14
14
  expect(output).to eq([
15
15
  " x** * BTC 54.08%\n",
@@ -20,7 +20,26 @@ RSpec.describe TTY::Pie, ':color option' do
20
20
  ].join)
21
21
  end
22
22
 
23
- it "draws a pie chart with colors" do
23
+ it "renders a pie chart with colors as a parameter" do
24
+ data = [
25
+ { name: 'BTC', value: 5977, fill: '*' },
26
+ { name: 'BCH', value: 3045, fill: '+' },
27
+ { name: 'LTC', value: 2030, fill: 'x' }
28
+ ]
29
+ pie = TTY::Pie.new(data: data, radius: 2, colors: %i[yellow green magenta])
30
+
31
+ output = pie.render
32
+ expected_output = [
33
+ " \e[35mx\e[0m\e[33m*\e[0m\e[33m*\e[0m \e[33m*\e[0m BTC 54.08%\n",
34
+ " \e[32m+\e[0m\e[35mx\e[0m\e[35mx\e[0m\e[33m*\e[0m\e[33m*\e[0m\e[33m*\e[0m\e[33m*\e[0m\n",
35
+ "\e[32m+\e[0m\e[32m+\e[0m\e[32m+\e[0m\e[32m+\e[0m\e[33m*\e[0m\e[33m*\e[0m\e[33m*\e[0m\e[33m*\e[0m\e[33m*\e[0m \e[32m+\e[0m BCH 27.55%\n",
36
+ " \e[32m+\e[0m\e[32m+\e[0m\e[32m+\e[0m\e[33m*\e[0m\e[33m*\e[0m\e[33m*\e[0m\e[33m*\e[0m\n",
37
+ " \e[32m+\e[0m\e[33m*\e[0m\e[33m*\e[0m \e[35mx\e[0m LTC 18.37%\n"
38
+ ].join
39
+ expect(output).to eq(expected_output)
40
+ end
41
+
42
+ it "renders a pie chart with colors" do
24
43
  data = [
25
44
  { name: 'BTC', value: 5977, color: :bright_yellow },
26
45
  { name: 'BCH', value: 3045, color: :bright_green },
@@ -28,7 +47,7 @@ RSpec.describe TTY::Pie, ':color option' do
28
47
  ]
29
48
  pie = TTY::Pie.new(data: data, radius: 2)
30
49
 
31
- output = pie.draw
50
+ output = pie.render
32
51
 
33
52
  expect(output).to eq([
34
53
  " \e[95m•\e[0m\e[93m•\e[0m\e[93m•\e[0m",
@@ -42,7 +61,7 @@ RSpec.describe TTY::Pie, ':color option' do
42
61
  ].join)
43
62
  end
44
63
 
45
- it "draw a pie chart with legend and cursor positioning" do
64
+ it "renders a pie chart with legend and cursor positioning" do
46
65
  data = [
47
66
  { name: 'BTC', value: 5977, color: :bright_yellow },
48
67
  { name: 'BCH', value: 3045, color: :bright_green },
@@ -50,7 +69,7 @@ RSpec.describe TTY::Pie, ':color option' do
50
69
  ]
51
70
  pie = TTY::Pie.new(data: data, radius: 2, left: 50, top: 10)
52
71
 
53
- output = pie.draw
72
+ output = pie.render
54
73
 
55
74
  expect(output).to eq([
56
75
  "\e[11;54H\e[95m•\e[0m\e[11;55H\e[93m•\e[0m\e[11;56H\e[93m•\e[0m",
@@ -64,7 +83,7 @@ RSpec.describe TTY::Pie, ':color option' do
64
83
  ].join)
65
84
  end
66
85
 
67
- it "draw a pie chart without legend and with cursor positioning" do
86
+ it "renders a pie chart without legend and with cursor positioning" do
68
87
  data = [
69
88
  { name: 'BTC', value: 5977, color: :bright_yellow },
70
89
  { name: 'BCH', value: 3045, color: :bright_green },
@@ -72,7 +91,7 @@ RSpec.describe TTY::Pie, ':color option' do
72
91
  ]
73
92
  pie = TTY::Pie.new(data: data, radius: 2, left: 50, top: 10, legend: false)
74
93
 
75
- output = pie.draw
94
+ output = pie.render
76
95
 
77
96
  expect(output).to eq([
78
97
  "\e[11;54H\e[95m•\e[0m\e[11;55H\e[93m•\e[0m\e[11;56H\e[93m•\e[0m\n",
@@ -9,10 +9,10 @@ RSpec.describe TTY::Pie, ':fill option' do
9
9
  ]
10
10
  }
11
11
 
12
- it "draws a pie chart with custom fill per data item" do
12
+ it "renders a pie chart with custom fill per data item" do
13
13
  pie = TTY::Pie.new(data: data, radius: 2)
14
14
 
15
- output = pie.draw
15
+ output = pie.render
16
16
 
17
17
  expect(output).to eq([
18
18
  " \e[95mx\e[0m\e[93m*\e[0m\e[93m*\e[0m",
@@ -24,4 +24,24 @@ RSpec.describe TTY::Pie, ':fill option' do
24
24
  " \e[95mx\e[0m LTC 18.37%\n"
25
25
  ].join)
26
26
  end
27
+
28
+ it "renders with custom fill chars per instance" do
29
+ data_without_fill = data.map { |item| item.delete(:fill); item }
30
+ pie = TTY::Pie.new(data: data_without_fill, radius: 2, fill: %w[* + x])
31
+
32
+ output = pie.render
33
+
34
+ expected_output = [
35
+ " \e[95mx\e[0m\e[93m*\e[0m\e[93m*\e[0m",
36
+ " \e[93m*\e[0m BTC 54.08%\n",
37
+ " \e[92m+\e[0m\e[95mx\e[0m\e[95mx\e[0m\e[93m*\e[0m\e[93m*\e[0m\e[93m*\e[0m\e[93m*\e[0m\n\e[92m+\e[0m\e[92m+\e[0m\e[92m+\e[0m\e[92m+\e[0m\e[93m*\e[0m\e[93m*\e[0m\e[93m*\e[0m\e[93m*\e[0m\e[93m*\e[0m",
38
+ " \e[92m+\e[0m BCH 27.55%\n",
39
+ " \e[92m+\e[0m\e[92m+\e[0m\e[92m+\e[0m\e[93m*\e[0m\e[93m*\e[0m\e[93m*\e[0m\e[93m*\e[0m\n",
40
+ " \e[92m+\e[0m\e[93m*\e[0m\e[93m*\e[0m",
41
+ " \e[95mx\e[0m LTC 18.37%\n"
42
+
43
+ ].join
44
+
45
+ expect(output).to eq(expected_output)
46
+ end
27
47
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe TTY::Pie, ':legend option' do
4
- it "draws legend at default location with 1 line separator" do
4
+ it "renders legend at default location with 1 line separator" do
5
5
  data = [
6
6
  { name: 'BTC', value: 5977, fill: '*' },
7
7
  { name: 'BCH', value: 3045, fill: '+' },
@@ -10,7 +10,7 @@ RSpec.describe TTY::Pie, ':legend option' do
10
10
 
11
11
  pie = TTY::Pie.new(data: data, radius: 2)
12
12
 
13
- output = pie.draw
13
+ output = pie.render
14
14
 
15
15
  expect(output).to eq([
16
16
  " x** * BTC 54.08%\n",
@@ -21,7 +21,7 @@ RSpec.describe TTY::Pie, ':legend option' do
21
21
  ].join)
22
22
  end
23
23
 
24
- it "draws legend next to chart without any line separator" do
24
+ it "renders legend next to chart without any line separator" do
25
25
  data = [
26
26
  { name: 'BTC', value: 5977, fill: '*' },
27
27
  { name: 'BCH', value: 3045, fill: '+' },
@@ -30,7 +30,7 @@ RSpec.describe TTY::Pie, ':legend option' do
30
30
 
31
31
  pie = TTY::Pie.new(data: data, radius: 2, legend: {left: 0, line: 0})
32
32
 
33
- output = pie.draw
33
+ output = pie.render
34
34
 
35
35
  expect(output).to eq([
36
36
  " x**\n",
@@ -41,7 +41,7 @@ RSpec.describe TTY::Pie, ':legend option' do
41
41
  ].join)
42
42
  end
43
43
 
44
- it "draws legend at custom location with line separator" do
44
+ it "renders legend at custom location with line separator" do
45
45
  data = [
46
46
  { name: 'BTC', value: 5977, fill: '*' },
47
47
  { name: 'BCH', value: 3045, fill: '+' },
@@ -50,7 +50,7 @@ RSpec.describe TTY::Pie, ':legend option' do
50
50
 
51
51
  pie = TTY::Pie.new(data: data, radius: 3, legend: {left: 10, line: 2})
52
52
 
53
- output = pie.draw
53
+ output = pie.render
54
54
 
55
55
  expect(output).to eq([
56
56
  " x** * BTC 54.08%\n",
@@ -62,4 +62,106 @@ RSpec.describe TTY::Pie, ':legend option' do
62
62
  " +** x LTC 18.37%\n"
63
63
  ].join)
64
64
  end
65
+
66
+ it "renders legend next to chart without any line separator" do
67
+ data = [
68
+ { name: 'BTC', value: 5977, fill: '*' },
69
+ { name: 'BCH', value: 3045, fill: '+' },
70
+ { name: 'LTC', value: 2030, fill: 'x' }
71
+ ]
72
+
73
+ pie = TTY::Pie.new(data: data, left: 2, top: 2, radius: 2, legend: {left: 2, line: 0})
74
+
75
+ output = pie.render
76
+
77
+ expected_output = [
78
+ "\e[3;6Hx\e[3;7H*\e[3;8H*\e[3;13H\n",
79
+ "\e[4;4H+\e[4;5Hx\e[4;6Hx\e[4;7H*\e[4;8H*\e[4;9H*\e[4;10H*\e[4;13H* BTC 54.08%\n",
80
+ "\e[5;3H+\e[5;4H+\e[5;5H+\e[5;6H+\e[5;7H*\e[5;8H*\e[5;9H*\e[5;10H*\e[5;11H*\e[5;13H+ BCH 27.55%\n",
81
+ "\e[6;4H+\e[6;5H+\e[6;6H+\e[6;7H*\e[6;8H*\e[6;9H*\e[6;10H*\e[6;13Hx LTC 18.37%\n",
82
+ "\e[7;6H+\e[7;7H*\e[7;8H*\e[7;13H\n"
83
+ ].join
84
+
85
+ expect(output).to eq(expected_output)
86
+ end
87
+
88
+ it "renders legend with a custom format" do
89
+ data = [
90
+ { name: 'BTC', value: 5977, fill: '*' },
91
+ { name: 'BCH', value: 3045, fill: '+' },
92
+ { name: 'LTC', value: 2030, fill: 'x' }
93
+ ]
94
+
95
+ pie = TTY::Pie.new(
96
+ data: data,
97
+ radius: 2,
98
+ legend: {
99
+ format: "%<label>s %<name>s %<value>d (%<percent>.2f%%)"
100
+ }
101
+ )
102
+
103
+ output = pie.render
104
+
105
+ expect(output).to eq([
106
+ " x** * BTC 5977 (54.08%)\n",
107
+ " +xx****\n",
108
+ "++++***** + BCH 3045 (27.55%)\n",
109
+ " +++****\n",
110
+ " +** x LTC 2030 (18.37%)\n"
111
+ ].join)
112
+ end
113
+
114
+ it "renders legend with a custom format & value as currency" do
115
+ data = [
116
+ { name: 'BTC', value: 5977.12345, fill: '*' },
117
+ { name: 'BCH', value: 3045.2, fill: '+' },
118
+ { name: 'LTC', value: 2030.444, fill: 'x' }
119
+ ]
120
+
121
+ pie = TTY::Pie.new(
122
+ data: data,
123
+ radius: 2,
124
+ legend: {
125
+ format: "%<label>s %<name>s $%<currency>s (%<percent>.0f%%)"
126
+ }
127
+ )
128
+
129
+ output = pie.render
130
+
131
+ expect(output).to eq([
132
+ " x** * BTC $5,977.12 (54%)\n",
133
+ " +xx****\n",
134
+ "++++***** + BCH $3,045.20 (28%)\n",
135
+ " +++****\n",
136
+ " +** x LTC $2,030.44 (18%)\n"
137
+ ].join)
138
+ end
139
+
140
+ it "renders legend with a custom format and currency precision & delimiter" do
141
+ data = [
142
+ { name: 'BTC', value: 5977.12345, fill: '*' },
143
+ { name: 'BCH', value: 3045.2, fill: '+' },
144
+ { name: 'LTC', value: 2030.444, fill: 'x' }
145
+ ]
146
+
147
+ pie = TTY::Pie.new(
148
+ data: data,
149
+ radius: 2,
150
+ legend: {
151
+ format: "%<label>s %<name>s $%<currency>s (%<percent>.0f%%)",
152
+ precision: 3,
153
+ delimiter: '*'
154
+ }
155
+ )
156
+
157
+ output = pie.render
158
+
159
+ expect(output).to eq([
160
+ " x** * BTC $5*977.123 (54%)\n",
161
+ " +xx****\n",
162
+ "++++***** + BCH $3*045.200 (28%)\n",
163
+ " +++****\n",
164
+ " +** x LTC $2*030.444 (18%)\n"
165
+ ].join)
166
+ end
65
167
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe TTY::Pie, '#draw' do
3
+ RSpec.describe TTY::Pie, '#render' do
4
4
  let(:data) {
5
5
  [
6
6
  { name: 'BTC', value: 5977 },
@@ -9,10 +9,16 @@ RSpec.describe TTY::Pie, '#draw' do
9
9
  ]
10
10
  }
11
11
 
12
- it "draws a pie chart with legend and without cursor positioning" do
12
+ it "renders chart with no data" do
13
+ pie = TTY::Pie.new(data: [], radius: 2)
14
+
15
+ expect(pie.render).to eq('')
16
+ end
17
+
18
+ it "renders a pie chart with legend and without cursor positioning" do
13
19
  pie = TTY::Pie.new(data: data, radius: 2)
14
20
 
15
- output = pie.draw
21
+ output = pie.render
16
22
 
17
23
  expect(output).to eq([
18
24
  " ••• • BTC 54.08%\n",
@@ -23,10 +29,10 @@ RSpec.describe TTY::Pie, '#draw' do
23
29
  ].join)
24
30
  end
25
31
 
26
- it "draws a pie chart without legend and without cursor positioning" do
32
+ it "renders a pie chart without legend and without cursor positioning" do
27
33
  pie = TTY::Pie.new(data: data, radius: 2, legend: false)
28
34
 
29
- output = pie.draw
35
+ output = pie.render
30
36
 
31
37
  expect(output).to eq([
32
38
  " •••\n",
@@ -37,10 +43,10 @@ RSpec.describe TTY::Pie, '#draw' do
37
43
  ].join)
38
44
  end
39
45
 
40
- it "draw a pie chart with legend and cursor positioning" do
46
+ it "render a pie chart with legend and cursor positioning" do
41
47
  pie = TTY::Pie.new(data: data, radius: 2, left: 50, top: 10)
42
48
 
43
- output = pie.draw
49
+ output = pie.render
44
50
 
45
51
  expect(output).to eq([
46
52
  "\e[11;54H•\e[11;55H•\e[11;56H•\e[11;63H• BTC 54.08%\n",
@@ -52,10 +58,10 @@ RSpec.describe TTY::Pie, '#draw' do
52
58
  ].join)
53
59
  end
54
60
 
55
- it "draw a pie chart without legend and with cursor positioning" do
61
+ it "render a pie chart without legend and with cursor positioning" do
56
62
  pie = TTY::Pie.new(data: data, radius: 2, left: 50, top: 10, legend: false)
57
63
 
58
- output = pie.draw
64
+ output = pie.render
59
65
 
60
66
  expect(output).to eq([
61
67
  "\e[11;54H\•\e[11;55H•\e[11;56H•\n",
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::Pie, '#reset' do
4
+ it "resets current data" do
5
+ data = [ { name: 'BTC', value: 5977, fill: '*' } ]
6
+
7
+ pie = TTY::Pie.new(data: data, radius: 2)
8
+
9
+ output = pie.render
10
+
11
+ expect(output).to eq([
12
+ " ***\n",
13
+ " *******\n",
14
+ "********* * BTC 100.00%\n",
15
+ " *******\n",
16
+ " ***\n"
17
+ ].join)
18
+
19
+ pie.reset
20
+
21
+ expect(pie.render).to eq('')
22
+ end
23
+ end
@@ -6,7 +6,7 @@ RSpec.describe TTY::Pie, '#update' do
6
6
 
7
7
  pie = TTY::Pie.new(data: data, radius: 2)
8
8
 
9
- output = pie.draw
9
+ output = pie.render
10
10
 
11
11
  expect(output).to eq([
12
12
  " ***\n",
@@ -18,7 +18,7 @@ RSpec.describe TTY::Pie, '#update' do
18
18
 
19
19
  pie.update([{name: 'LTC', value: 2030, fill: 'x'}])
20
20
 
21
- output = pie.draw
21
+ output = pie.render
22
22
 
23
23
  expect(output).to eq([
24
24
  " xxx\n",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-pie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-25 00:00:00.000000000 Z
11
+ date: 2019-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pastel
@@ -95,6 +95,7 @@ files:
95
95
  - bin/setup
96
96
  - examples/basic.rb
97
97
  - examples/fill.rb
98
+ - examples/format.rb
98
99
  - lib/tty-pie.rb
99
100
  - lib/tty/pie.rb
100
101
  - lib/tty/pie/data_item.rb
@@ -102,9 +103,10 @@ files:
102
103
  - spec/spec_helper.rb
103
104
  - spec/unit/add_spec.rb
104
105
  - spec/unit/color_spec.rb
105
- - spec/unit/draw_spec.rb
106
106
  - spec/unit/fill_spec.rb
107
107
  - spec/unit/legend_spec.rb
108
+ - spec/unit/render_spec.rb
109
+ - spec/unit/reset_spec.rb
108
110
  - spec/unit/update_spec.rb
109
111
  - tasks/console.rake
110
112
  - tasks/coverage.rake