tty-pie 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +114 -6
- data/examples/fill.rb +1 -1
- data/examples/format.rb +16 -0
- data/lib/tty/pie.rb +30 -12
- data/lib/tty/pie/data_item.rb +34 -5
- data/lib/tty/pie/version.rb +1 -1
- data/spec/unit/add_spec.rb +1 -1
- data/spec/unit/color_spec.rb +27 -8
- data/spec/unit/fill_spec.rb +22 -2
- data/spec/unit/legend_spec.rb +108 -6
- data/spec/unit/{draw_spec.rb → render_spec.rb} +15 -9
- data/spec/unit/reset_spec.rb +23 -0
- data/spec/unit/update_spec.rb +2 -2
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22d6cb76f39389059b746df28e9409d99ab1591d77edbe9f76bc1e9a7ea5e332
|
4
|
+
data.tar.gz: 9e735e70ab7286e7ae5a0ee3e2d949f0734f8e002b37cf82b685f31e7729b7f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 291a12624a6fd02557e4f47c7535580dc215574d3804df5c7da454be0d9f50514a1776e58ea7fd9f73008c3cfe4a3f6405b116864d603e7635b40c76c9179738
|
7
|
+
data.tar.gz: d248aef95ff8a16ba71dc28c3da25d13d65b5360effe61b5893fc7088f3c32e82406e83f8738f8708f6fd436cf684e9a7786d6a49587a8b02498b1deecf6f855
|
data/CHANGELOG.md
CHANGED
@@ -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
|
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
|
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
|
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
|
189
|
+
### 2.4 render
|
189
190
|
|
190
|
-
Once a pie chart has been initialized use the `
|
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.
|
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.
|
data/examples/fill.rb
CHANGED
data/examples/format.rb
ADDED
@@ -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
|
data/lib/tty/pie.rb
CHANGED
@@ -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,
|
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
|
-
|
84
|
-
|
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
|
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(
|
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
|
-
|
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
|
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
|
|
data/lib/tty/pie/data_item.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
data/lib/tty/pie/version.rb
CHANGED
data/spec/unit/add_spec.rb
CHANGED
data/spec/unit/color_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe TTY::Pie, ':color option' do
|
4
|
-
it "
|
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.
|
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 "
|
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.
|
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 "
|
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.
|
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 "
|
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.
|
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",
|
data/spec/unit/fill_spec.rb
CHANGED
@@ -9,10 +9,10 @@ RSpec.describe TTY::Pie, ':fill option' do
|
|
9
9
|
]
|
10
10
|
}
|
11
11
|
|
12
|
-
it "
|
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.
|
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
|
data/spec/unit/legend_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe TTY::Pie, ':legend option' do
|
4
|
-
it "
|
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.
|
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 "
|
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.
|
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 "
|
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.
|
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, '#
|
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 "
|
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.
|
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 "
|
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.
|
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 "
|
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.
|
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 "
|
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.
|
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
|
data/spec/unit/update_spec.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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:
|
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
|