glimmer-libui-cc-graphs_and_charts 0.3.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +49 -8
- data/VERSION +1 -1
- data/examples/graphs_and_charts/{basic_line_graph_relative.rb → basic_line_graph_relative_reverse_x.rb} +1 -0
- data/examples/graphs_and_charts/basic_line_graph_reverse_x.rb +52 -0
- data/glimmer-libui-cc-graphs_and_charts.gemspec +5 -4
- data/lib/glimmer/view/line_graph.rb +58 -15
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '01195bf257b2d2c5d68720d762b2787e56824304a1524ddee62bd6107cd4ce87'
|
4
|
+
data.tar.gz: 55118796cfc077ee9265f35f5126ef51b3a4ec9661eca624f098194c13136bca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb736fcd7e72aba035fa0709c74d68fe5d4ac5fceb4baca02541aa8a6e65b62f4383af211457886413bac2f38852b4f31a81f99b2e70e8ae99a8abe4537ea53b
|
7
|
+
data.tar.gz: 605148fa95182c42c31c31eb7932e452ebdbc54806b1b8cbb51fbdb5f5fe1b4dd1a6021efad71623ded0eeb5a9481d4065b120bc25c7c209efd2df29cc377e57
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.4.0
|
4
|
+
|
5
|
+
- Support `reverse_x` option; when `false`, line graphs are drawn naturally from left to right, and when `true`, line graphs are drawn like before from right to left.
|
6
|
+
- Rename previous line graph examples to indicate that they have reverse_x as `true`
|
7
|
+
- Add new `examples/graphs_and_charts/basic_line_graph.rb` example that renders line graphs naturally from left to right.
|
8
|
+
|
3
9
|
## 0.3.0
|
4
10
|
|
5
11
|
- Initial implementation of `bubble_chart` custom control
|
data/README.md
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
# Graphs and Charts 0.
|
1
|
+
# Graphs and Charts 0.4.0 (Alpha)
|
2
2
|
## [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui) Custom Controls
|
3
3
|
[](http://badge.fury.io/rb/glimmer-libui-cc-graphs_and_charts)
|
4
4
|
[](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
5
5
|
|
6
|
-
Graphs and Charts (Custom Controls for [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui))
|
6
|
+
Graphs and Charts (Custom Controls for [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui)). It is used in [Kuiq (Sidekiq UI)](https://github.com/mperham/kuiq).
|
7
7
|
|
8
8
|

|
9
9
|
|
10
|
-

|
11
11
|
|
12
12
|

|
13
13
|
|
@@ -16,7 +16,7 @@ Graphs and Charts (Custom Controls for [Glimmer DSL for LibUI](https://github.co
|
|
16
16
|
Add this line to Bundler `Gemfile`:
|
17
17
|
|
18
18
|
```ruby
|
19
|
-
gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.
|
19
|
+
gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.4.0'
|
20
20
|
```
|
21
21
|
|
22
22
|
Run:
|
@@ -176,12 +176,53 @@ line_graph(
|
|
176
176
|
|
177
177
|

|
178
178
|
|
179
|
-
**
|
179
|
+
**Absolute Mode (reverse x):**
|
180
|
+
|
181
|
+
It supports any `Numeric` y-axis values in addition to `Time` x-axis values.
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
line_graph(
|
185
|
+
reverse_x: true,
|
186
|
+
width: 900,
|
187
|
+
height: 300,
|
188
|
+
lines: [
|
189
|
+
{
|
190
|
+
name: 'Stock 1',
|
191
|
+
stroke: [163, 40, 39, thickness: 2],
|
192
|
+
values: {
|
193
|
+
Time.new(2030, 12, 1) => 80,
|
194
|
+
Time.new(2030, 12, 2) => 36,
|
195
|
+
Time.new(2030, 12, 4) => 10,
|
196
|
+
Time.new(2030, 12, 5) => 60,
|
197
|
+
Time.new(2030, 12, 6) => 20,
|
198
|
+
},
|
199
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
200
|
+
},
|
201
|
+
{
|
202
|
+
name: 'Stock 2',
|
203
|
+
stroke: [47, 109, 104, thickness: 2],
|
204
|
+
values: {
|
205
|
+
Time.new(2030, 12, 1) => 62,
|
206
|
+
Time.new(2030, 12, 2) => 0,
|
207
|
+
Time.new(2030, 12, 3) => 90,
|
208
|
+
Time.new(2030, 12, 5) => 0,
|
209
|
+
Time.new(2030, 12, 7) => 17,
|
210
|
+
},
|
211
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
212
|
+
},
|
213
|
+
],
|
214
|
+
)
|
215
|
+
```
|
216
|
+
|
217
|
+

|
218
|
+
|
219
|
+
**Relative Mode (reverse x):**
|
180
220
|
|
181
221
|
Currently, it only supports `Integer` y-axis values in addition to `Time` x-axis values.
|
182
222
|
|
183
223
|
```ruby
|
184
224
|
line_graph(
|
225
|
+
reverse_x: true,
|
185
226
|
width: 900,
|
186
227
|
height: 300,
|
187
228
|
graph_point_distance: :width_divided_by_point_count,
|
@@ -207,7 +248,7 @@ line_graph(
|
|
207
248
|
)
|
208
249
|
```
|
209
250
|
|
210
|
-

|
251
|
+

|
211
252
|
|
212
253
|
Look into [lib/glimmer/view/line_graph.rb](/lib/glimmer/view/line_graph.rb) to learn about all supported options.
|
213
254
|
|
@@ -266,7 +307,7 @@ end
|
|
266
307
|
BasicLineGraph.launch
|
267
308
|
```
|
268
309
|
|
269
|
-

|
310
|
+

|
270
311
|
|
271
312
|
**Basic Line Graph Relative Example:**
|
272
313
|
|
@@ -314,7 +355,7 @@ end
|
|
314
355
|
BasicLineGraphRelative.launch
|
315
356
|
```
|
316
357
|
|
317
|
-

|
358
|
+

|
318
359
|
|
319
360
|
### Bubble Chart
|
320
361
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# This line is only needed when running the example from inside the project directory
|
2
|
+
$LOAD_PATH.prepend(File.expand_path(File.join(__dir__, '..', '..', 'lib'))) if File.exist?(File.join(__dir__, '..', '..', 'lib'))
|
3
|
+
|
4
|
+
require 'glimmer-dsl-libui'
|
5
|
+
require 'glimmer/view/line_graph'
|
6
|
+
|
7
|
+
class BasicLineGraph
|
8
|
+
include Glimmer::LibUI::Application
|
9
|
+
|
10
|
+
body {
|
11
|
+
window('Basic Line Graph', 900, 300) { |main_window|
|
12
|
+
@line_graph = line_graph(
|
13
|
+
reverse_x: true,
|
14
|
+
width: 900,
|
15
|
+
height: 300,
|
16
|
+
lines: [
|
17
|
+
{
|
18
|
+
name: 'Stock 1',
|
19
|
+
stroke: [163, 40, 39, thickness: 2],
|
20
|
+
values: {
|
21
|
+
Time.new(2030, 12, 1) => 2,
|
22
|
+
Time.new(2030, 12, 2) => 2.5,
|
23
|
+
Time.new(2030, 12, 4) => 1,
|
24
|
+
Time.new(2030, 12, 5) => 0,
|
25
|
+
Time.new(2030, 12, 6) => 2,
|
26
|
+
},
|
27
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
28
|
+
},
|
29
|
+
{
|
30
|
+
name: 'Stock 2',
|
31
|
+
stroke: [47, 109, 104, thickness: 2],
|
32
|
+
values: {
|
33
|
+
Time.new(2030, 12, 1) => 2,
|
34
|
+
Time.new(2030, 12, 2) => 0,
|
35
|
+
Time.new(2030, 12, 3) => 2.5,
|
36
|
+
Time.new(2030, 12, 5) => 1,
|
37
|
+
Time.new(2030, 12, 7) => 2,
|
38
|
+
},
|
39
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
40
|
+
},
|
41
|
+
],
|
42
|
+
)
|
43
|
+
|
44
|
+
on_content_size_changed do
|
45
|
+
@line_graph.width = main_window.content_size[0]
|
46
|
+
@line_graph.height = main_window.content_size[1]
|
47
|
+
end
|
48
|
+
}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
BasicLineGraph.launch
|
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-libui-cc-graphs_and_charts 0.
|
5
|
+
# stub: glimmer-libui-cc-graphs_and_charts 0.4.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-libui-cc-graphs_and_charts".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.4.0".freeze
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Andy Maleh".freeze]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2025-01-27"
|
15
15
|
s.description = "Graphs and Charts (Glimmer DSL for LibUI Custom Controls), like Line Graph, Bar Chart, and Bubble Chart.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -27,7 +27,8 @@ Gem::Specification.new do |s|
|
|
27
27
|
"examples/graphs_and_charts/basic_bar_chart.rb",
|
28
28
|
"examples/graphs_and_charts/basic_bubble_chart.rb",
|
29
29
|
"examples/graphs_and_charts/basic_line_graph.rb",
|
30
|
-
"examples/graphs_and_charts/
|
30
|
+
"examples/graphs_and_charts/basic_line_graph_relative_reverse_x.rb",
|
31
|
+
"examples/graphs_and_charts/basic_line_graph_reverse_x.rb",
|
31
32
|
"glimmer-libui-cc-graphs_and_charts.gemspec",
|
32
33
|
"lib/glimmer-libui-cc-graphs_and_charts.rb",
|
33
34
|
"lib/glimmer/view/bar_chart.rb",
|
@@ -74,6 +74,7 @@ module Glimmer
|
|
74
74
|
option :graph_status_height, default: DEFAULT_GRAPH_STATUS_HEIGHT
|
75
75
|
|
76
76
|
option :display_attributes_on_hover, default: false
|
77
|
+
option :reverse_x, default: false
|
77
78
|
|
78
79
|
before_body do
|
79
80
|
self.lines = [lines] if lines.is_a?(Hash)
|
@@ -112,8 +113,13 @@ module Glimmer
|
|
112
113
|
|
113
114
|
if @hover_point && lines && lines[0] && @points && @points[lines[0]] && !@points[lines[0]].empty?
|
114
115
|
x = @hover_point[:x]
|
115
|
-
|
116
|
-
|
116
|
+
if lines[0][:x_interval_in_seconds]
|
117
|
+
closest_point_index = ((width - graph_padding_width - x) / graph_point_distance_for_line(lines[0])).round
|
118
|
+
else
|
119
|
+
closest_point_index = :absolute
|
120
|
+
end
|
121
|
+
if closest_point_index == :absolute || closest_point_index != @closest_point_index
|
122
|
+
# TODO look into optimizing this for absolute mode
|
117
123
|
@closest_point_index = closest_point_index
|
118
124
|
graph_area.queue_redraw_all
|
119
125
|
end
|
@@ -275,12 +281,14 @@ module Glimmer
|
|
275
281
|
end
|
276
282
|
|
277
283
|
def all_line_graphs
|
278
|
-
lines.each
|
284
|
+
lines.each(&method(:single_line_graph))
|
279
285
|
end
|
280
286
|
|
281
287
|
def single_line_graph(graph_line)
|
282
288
|
last_point = nil
|
283
289
|
points = calculate_points(graph_line)
|
290
|
+
# points are already calculated as reversed before here, so here we reverse again if needed
|
291
|
+
points = reverse_x_in_points(points) if !reverse_x
|
284
292
|
points.to_a.each do |point|
|
285
293
|
if last_point
|
286
294
|
line(last_point[:x], last_point[:y], point[:x], point[:y]) {
|
@@ -343,6 +351,22 @@ module Glimmer
|
|
343
351
|
@points[graph_line]
|
344
352
|
end
|
345
353
|
|
354
|
+
def reverse_x_in_points(points)
|
355
|
+
# TODO look into optimizing operations below by not iterating 3 times (perhaps one iteration could do everything)
|
356
|
+
points = points.map do |point|
|
357
|
+
point.merge(x: width_drawable.to_f - point[:x])
|
358
|
+
end
|
359
|
+
min_point = points.min_by {|point| point[:x]}
|
360
|
+
if min_point[:x] < 0
|
361
|
+
points.each do |point|
|
362
|
+
point[:x] = point[:x] - min_point[:x]
|
363
|
+
end
|
364
|
+
end
|
365
|
+
points.each do |point|
|
366
|
+
point[:x] = point[:x] + graph_padding_width.to_f
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
346
370
|
# this is the multiplier that we must multiply by the relative x value
|
347
371
|
def x_resolution
|
348
372
|
@x_resolution ||= width_drawable.to_f / x_value_range_for_all_lines.to_f
|
@@ -472,7 +496,19 @@ module Glimmer
|
|
472
496
|
|
473
497
|
if @hover_point && lines && lines[0] && @points && @points[lines[0]] && !@points[lines[0]].empty?
|
474
498
|
x = @hover_point[:x]
|
475
|
-
|
499
|
+
if @closest_point_index == :absolute # used in absolute mode
|
500
|
+
# TODO this is making a wrong assumption that there will be a point for every line
|
501
|
+
# some lines might end up with no points, so we need to filter them out
|
502
|
+
# we should start with the point across all lines that is closest to the mouse hover point
|
503
|
+
# and then pick up points that match its X value
|
504
|
+
closest_points = lines.map do |line|
|
505
|
+
line_points = @points[line]
|
506
|
+
point_distances_from_hover_point = line_points.map { |point| [point, PerfectShape::Point.point_distance(point[:x], point[:y], @hover_point[:x], @hover_point[:y])] }
|
507
|
+
closest_point = point_distances_from_hover_point.min_by(&:last).first
|
508
|
+
end
|
509
|
+
else
|
510
|
+
closest_points = lines.map { |line| @points[line][@closest_point_index] }
|
511
|
+
end
|
476
512
|
closest_x = closest_points[0]&.[](:x)
|
477
513
|
line(closest_x, graph_padding_height, closest_x, height - graph_padding_height) {
|
478
514
|
stroke graph_stroke_hover_line
|
@@ -488,14 +524,21 @@ module Glimmer
|
|
488
524
|
stroke stroke_value
|
489
525
|
}
|
490
526
|
end
|
491
|
-
text_label = formatted_x_value(@closest_point_index)
|
527
|
+
text_label = formatted_x_value(@closest_point_index, closest_points)
|
492
528
|
text_label_width = estimate_width_of_text(text_label, DEFAULT_GRAPH_FONT_MARKER_TEXT)
|
493
529
|
lines_with_closest_points = lines.each_with_index.map do |line, index|
|
494
530
|
next if closest_points[index].nil?
|
495
531
|
|
496
532
|
line
|
497
533
|
end.compact
|
498
|
-
closest_point_texts = lines_with_closest_points.map
|
534
|
+
closest_point_texts = lines_with_closest_points.each_with_index.map do |line, index|
|
535
|
+
if @closest_point_index == :absolute
|
536
|
+
line_point = closest_points[index]
|
537
|
+
"#{line[:name]}: #{line_point[:y_value]}"
|
538
|
+
else
|
539
|
+
"#{line[:name]}: #{line[:y_values][@closest_point_index]}"
|
540
|
+
end
|
541
|
+
end
|
499
542
|
closest_point_text_widths = closest_point_texts.map do |text|
|
500
543
|
estimate_width_of_text(text, graph_font_marker_text)
|
501
544
|
end
|
@@ -536,12 +579,10 @@ module Glimmer
|
|
536
579
|
end
|
537
580
|
end
|
538
581
|
|
539
|
-
def formatted_x_value(x_value_index)
|
540
|
-
# Today, we make the assumption that all lines have points along the same x-axis values
|
541
|
-
# TODO In the future, we can support different x values along different lines
|
582
|
+
def formatted_x_value(x_value_index, closest_points)
|
542
583
|
graph_line = lines[0]
|
543
584
|
x_value_format = graph_line[:x_value_format] || :to_s
|
544
|
-
x_value = calculated_x_value(x_value_index)
|
585
|
+
x_value = calculated_x_value(x_value_index, closest_points)
|
545
586
|
if (x_value_format.is_a?(Symbol) || x_value_format.is_a?(String))
|
546
587
|
x_value.send(x_value_format)
|
547
588
|
else
|
@@ -549,11 +590,13 @@ module Glimmer
|
|
549
590
|
end
|
550
591
|
end
|
551
592
|
|
552
|
-
def calculated_x_value(x_value_index)
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
593
|
+
def calculated_x_value(x_value_index, closest_points = nil)
|
594
|
+
if x_value_index == :absolute # absolute mode
|
595
|
+
closest_points.first[:x_value]
|
596
|
+
else # relative mode
|
597
|
+
graph_line = lines[0]
|
598
|
+
graph_line[:x_value_start] - (graph_line[:x_interval_in_seconds] * x_value_index)
|
599
|
+
end
|
557
600
|
end
|
558
601
|
|
559
602
|
def estimate_width_of_text(text_string, font_properties)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-libui-cc-graphs_and_charts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer-dsl-libui
|
@@ -89,7 +89,8 @@ files:
|
|
89
89
|
- examples/graphs_and_charts/basic_bar_chart.rb
|
90
90
|
- examples/graphs_and_charts/basic_bubble_chart.rb
|
91
91
|
- examples/graphs_and_charts/basic_line_graph.rb
|
92
|
-
- examples/graphs_and_charts/
|
92
|
+
- examples/graphs_and_charts/basic_line_graph_relative_reverse_x.rb
|
93
|
+
- examples/graphs_and_charts/basic_line_graph_reverse_x.rb
|
93
94
|
- glimmer-libui-cc-graphs_and_charts.gemspec
|
94
95
|
- lib/glimmer-libui-cc-graphs_and_charts.rb
|
95
96
|
- lib/glimmer/view/bar_chart.rb
|