glimmer-libui-cc-graphs_and_charts 0.1.5 → 0.1.7
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 +12 -1
- data/README.md +110 -8
- data/VERSION +1 -1
- data/examples/graphs_and_charts/basic_line_graph.rb +23 -16
- data/examples/graphs_and_charts/basic_line_graph_relative.rb +49 -0
- data/glimmer-libui-cc-graphs_and_charts.gemspec +4 -3
- data/lib/glimmer/view/line_graph.rb +104 -11
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2a02d818ffec27e5d64eafa181c90e1362b62ea8f201018fe92705b0d95a664
|
4
|
+
data.tar.gz: 6de4a548a1c74d91cc389663d9917311bd66523402ba984ac05a250d8cff5baa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 738a36dedf90e91774876d7cc41f545edb00ac03d65cd6bf89eaf30eac5374b4abfa591d007d971476a02dd854ca14a262a7fcda34fdc24ac531b17509ee0dcf
|
7
|
+
data.tar.gz: 2039bf32f7d8fb7930c24fda0eba1def6c30db968d452cb219a7ceab604bfed450b87b8d68ae061d75017ea59f6161d46b9fbebd8ab5581727116ebfd32fec82
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,21 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.1.7
|
4
|
+
|
5
|
+
- Scale `y` axis when using `values` option to fill up the vertical graph height if all y-axis values are smaller than `1`
|
6
|
+
|
7
|
+
## 0.1.6
|
8
|
+
|
9
|
+
- Support passing line `values` as a `Hash` map of x-axis values to y-axis values instead of using the combination of `y_values`, `x_value_start`, and `x_interval_in_seconds`
|
10
|
+
- Rename `examples/graphs_and_charts/basic_line_graph.rb` to `examples/graphs_and_charts/basic_line_graph_relative.rb`
|
11
|
+
- New `examples/graphs_and_charts/basic_line_graph.rb` (replacing older example that got renamed to `basic_line_graph_relative.rb`)
|
12
|
+
- Add graph auto-scaling logic to both `examples/graphs_and_charts/basic_line_graph.rb` & `examples/graphs_and_charts/basic_line_graph_relative.rb`
|
13
|
+
|
3
14
|
## 0.1.5
|
4
15
|
|
5
16
|
- Render circles for every point in addition to the lines connecting all the points
|
6
17
|
- Render a single point if there is only 1 value in `lines` `y_values` instead of rendering nothing until 2 values exist at least
|
7
|
-
- Support `graph_point_radius`, `graph_selected_point_radius`, and `graph_fill_selected_point` options for
|
18
|
+
- Support `graph_point_radius`, `graph_selected_point_radius`, and `graph_fill_selected_point` options for customizing the circle of every rendered point and selected point.
|
8
19
|
- Avoid rendering on top of the grid markers on the left side
|
9
20
|
- Optimize performance of rendering grid markers and showing mouse hover selection stats of a point
|
10
21
|
|
data/README.md
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
# Graphs and Charts 0.1.
|
1
|
+
# Graphs and Charts 0.1.7 (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
6
|
Graphs and Charts (Custom Controls) for [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui)
|
7
7
|
|
8
|
-

|
8
|
+

|
9
9
|
|
10
10
|
## Setup
|
11
11
|
|
12
12
|
Add this line to Bundler `Gemfile`:
|
13
13
|
|
14
14
|
```ruby
|
15
|
-
gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.1.
|
15
|
+
gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.1.7'
|
16
16
|
```
|
17
17
|
|
18
18
|
Run:
|
@@ -42,12 +42,59 @@ require 'glimmer/view/line_graph'
|
|
42
42
|
This makes the `line_graph` [Glimmer DSL for LibUI Custom Control](https://github.com/AndyObtiva/glimmer-dsl-libui#custom-components) available in the Glimmer GUI DSL.
|
43
43
|
You can then nest `line_graph` under `window` or some container like `vertical_box`. By the way, `line_graph` is implemented on top of the [`area` Glimmer DSL for LibUI control](https://github.com/AndyObtiva/glimmer-dsl-libui#area-api).
|
44
44
|
|
45
|
+
Note that you can use in absolute mode or relative mode for determining x-axis values starting from newest point to oldest point along the time x-axis:
|
46
|
+
- Absolute Mode: pass `values` which maps x-axis values to y-axis values
|
47
|
+
- Relative Mode: pass `y_values`, `x_value_start`, and `x_interval_in_seconds` (x-axis values are calculated automatically in a uniform way from `x_value_start` deducting `x_interval_in_seconds`)
|
48
|
+
|
49
|
+
**Absolute Mode:**
|
50
|
+
|
51
|
+
It supports any `Numeric` y-axis values in addition to `Time` x-axis values.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
@line_graph = line_graph(
|
55
|
+
width: 900,
|
56
|
+
height: 300,
|
57
|
+
lines: [
|
58
|
+
{
|
59
|
+
name: 'Stock 1',
|
60
|
+
stroke: [163, 40, 39, thickness: 2],
|
61
|
+
values: {
|
62
|
+
Time.new(2030, 12, 1) => 80,
|
63
|
+
Time.new(2030, 12, 2) => 36,
|
64
|
+
Time.new(2030, 12, 4) => 10,
|
65
|
+
Time.new(2030, 12, 5) => 60,
|
66
|
+
Time.new(2030, 12, 6) => 20,
|
67
|
+
},
|
68
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
69
|
+
},
|
70
|
+
{
|
71
|
+
name: 'Stock 2',
|
72
|
+
stroke: [47, 109, 104, thickness: 2],
|
73
|
+
values: {
|
74
|
+
Time.new(2030, 12, 1) => 62,
|
75
|
+
Time.new(2030, 12, 2) => 0,
|
76
|
+
Time.new(2030, 12, 3) => 90,
|
77
|
+
Time.new(2030, 12, 5) => 0,
|
78
|
+
Time.new(2030, 12, 7) => 17,
|
79
|
+
},
|
80
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
81
|
+
},
|
82
|
+
],
|
83
|
+
)
|
84
|
+
```
|
85
|
+
|
86
|
+

|
87
|
+
|
88
|
+
**Relative Mode:**
|
89
|
+
|
90
|
+
Currently, it only supports `Integer` y-axis values in addition to `Time` x-axis values.
|
91
|
+
|
45
92
|
```ruby
|
46
93
|
line_graph(
|
47
94
|
width: 900,
|
48
95
|
height: 300,
|
49
96
|
graph_point_distance: :width_divided_by_point_count,
|
50
|
-
|
97
|
+
series: [
|
51
98
|
{
|
52
99
|
name: 'Feature A',
|
53
100
|
stroke: [163, 40, 39, thickness: 2],
|
@@ -69,11 +116,11 @@ line_graph(
|
|
69
116
|
)
|
70
117
|
```
|
71
118
|
|
72
|
-

|
119
|
+

|
73
120
|
|
74
121
|
Look into [lib/glimmer/view/line_graph.rb](/lib/glimmer/view/line_graph.rb) to learn about all supported options.
|
75
122
|
|
76
|
-
Basic Line Graph Example
|
123
|
+
**Basic Line Graph Example:**
|
77
124
|
|
78
125
|
[examples/graphs_and_charts/basic_line_graph.rb](/examples/graphs_and_charts/basic_line_graph.rb)
|
79
126
|
|
@@ -81,6 +128,61 @@ Basic Line Graph Example:
|
|
81
128
|
require 'glimmer-dsl-libui'
|
82
129
|
require 'glimmer/view/line_graph'
|
83
130
|
|
131
|
+
class BasicLineGraph
|
132
|
+
include Glimmer::LibUI::Application
|
133
|
+
|
134
|
+
body {
|
135
|
+
window('Basic Line Graph', 900, 300) { |main_window|
|
136
|
+
@line_graph = line_graph(
|
137
|
+
width: 900,
|
138
|
+
height: 300,
|
139
|
+
lines: [
|
140
|
+
{
|
141
|
+
name: 'Stock 1',
|
142
|
+
stroke: [163, 40, 39, thickness: 2],
|
143
|
+
values: {
|
144
|
+
Time.new(2030, 12, 1) => 80,
|
145
|
+
Time.new(2030, 12, 2) => 36,
|
146
|
+
Time.new(2030, 12, 4) => 10,
|
147
|
+
Time.new(2030, 12, 5) => 60,
|
148
|
+
Time.new(2030, 12, 6) => 20,
|
149
|
+
},
|
150
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
151
|
+
},
|
152
|
+
{
|
153
|
+
name: 'Stock 2',
|
154
|
+
stroke: [47, 109, 104, thickness: 2],
|
155
|
+
values: {
|
156
|
+
Time.new(2030, 12, 1) => 62,
|
157
|
+
Time.new(2030, 12, 2) => 0,
|
158
|
+
Time.new(2030, 12, 3) => 90,
|
159
|
+
Time.new(2030, 12, 5) => 0,
|
160
|
+
Time.new(2030, 12, 7) => 17,
|
161
|
+
},
|
162
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
163
|
+
},
|
164
|
+
],
|
165
|
+
)
|
166
|
+
|
167
|
+
on_content_size_changed do
|
168
|
+
@line_graph.width = main_window.content_size[0]
|
169
|
+
@line_graph.height = main_window.content_size[1]
|
170
|
+
end
|
171
|
+
}
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
BasicLineGraph.launch
|
176
|
+
```
|
177
|
+
|
178
|
+

|
179
|
+
|
180
|
+
**Basic Line Graph Relative Example:**
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
require 'glimmer-dsl-libui'
|
184
|
+
require 'glimmer/view/line_graph'
|
185
|
+
|
84
186
|
class BasicLineGraph
|
85
187
|
include Glimmer::LibUI::Application
|
86
188
|
|
@@ -94,7 +196,7 @@ class BasicLineGraph
|
|
94
196
|
width: 900,
|
95
197
|
height: 300,
|
96
198
|
graph_point_distance: :width_divided_by_point_count,
|
97
|
-
|
199
|
+
series: [
|
98
200
|
{
|
99
201
|
name: 'Feature A',
|
100
202
|
stroke: [163, 40, 39, thickness: 2],
|
@@ -121,7 +223,7 @@ end
|
|
121
223
|
BasicLineGraph.launch
|
122
224
|
```
|
123
225
|
|
124
|
-

|
226
|
+

|
125
227
|
|
126
228
|
Contributing to glimmer-libui-cc-graphs_and_charts
|
127
229
|
------------------------------------------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.7
|
@@ -7,36 +7,43 @@ require 'glimmer/view/line_graph'
|
|
7
7
|
class BasicLineGraph
|
8
8
|
include Glimmer::LibUI::Application
|
9
9
|
|
10
|
-
before_body do
|
11
|
-
@start_time = Time.now
|
12
|
-
end
|
13
|
-
|
14
10
|
body {
|
15
|
-
window('Basic Line Graph', 900,
|
16
|
-
line_graph(
|
11
|
+
window('Basic Line Graph', 900, 300) { |main_window|
|
12
|
+
@line_graph = line_graph(
|
17
13
|
width: 900,
|
18
14
|
height: 300,
|
19
|
-
graph_point_distance: :width_divided_by_point_count,
|
20
15
|
lines: [
|
21
16
|
{
|
22
|
-
name: '
|
17
|
+
name: 'Stock 1',
|
23
18
|
stroke: [163, 40, 39, thickness: 2],
|
24
|
-
|
25
|
-
|
19
|
+
values: {
|
20
|
+
Time.new(2030, 12, 1) => 80,
|
21
|
+
Time.new(2030, 12, 2) => 36,
|
22
|
+
Time.new(2030, 12, 4) => 10,
|
23
|
+
Time.new(2030, 12, 5) => 60,
|
24
|
+
Time.new(2030, 12, 6) => 20,
|
25
|
+
},
|
26
26
|
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
27
|
-
y_values: [80, 36, 10, 60, 20, 110, 16, 5, 36, 1, 77, 15, 3, 34, 8, 63, 12, 17, 90, 28, 70]
|
28
27
|
},
|
29
28
|
{
|
30
|
-
name: '
|
29
|
+
name: 'Stock 2',
|
31
30
|
stroke: [47, 109, 104, thickness: 2],
|
32
|
-
|
33
|
-
|
31
|
+
values: {
|
32
|
+
Time.new(2030, 12, 1) => 62,
|
33
|
+
Time.new(2030, 12, 2) => 0,
|
34
|
+
Time.new(2030, 12, 3) => 90,
|
35
|
+
Time.new(2030, 12, 5) => 0,
|
36
|
+
Time.new(2030, 12, 7) => 17,
|
37
|
+
},
|
34
38
|
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
35
|
-
y_values: [62, 0, 90, 0, 0, 27, 0, 56, 0, 0, 24, 0, 60, 0, 30, 0, 47, 0, 38, 90, 0]
|
36
39
|
},
|
37
40
|
],
|
38
|
-
display_attributes_on_hover: true,
|
39
41
|
)
|
42
|
+
|
43
|
+
on_content_size_changed do
|
44
|
+
@line_graph.width = main_window.content_size[0]
|
45
|
+
@line_graph.height = main_window.content_size[1]
|
46
|
+
end
|
40
47
|
}
|
41
48
|
}
|
42
49
|
end
|
@@ -0,0 +1,49 @@
|
|
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
|
+
before_body do
|
11
|
+
@start_time = Time.now
|
12
|
+
end
|
13
|
+
|
14
|
+
body {
|
15
|
+
window('Basic Line Graph', 900, 330) { |main_window|
|
16
|
+
@line_graph = line_graph(
|
17
|
+
width: 900,
|
18
|
+
height: 300,
|
19
|
+
graph_point_distance: :width_divided_by_point_count,
|
20
|
+
lines: [
|
21
|
+
{
|
22
|
+
name: 'Feature A',
|
23
|
+
stroke: [163, 40, 39, thickness: 2],
|
24
|
+
x_value_start: @start_time,
|
25
|
+
x_interval_in_seconds: 8,
|
26
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
27
|
+
y_values: [80, 36, 10, 60, 20, 110, 16, 5, 36, 1, 77, 15, 3, 34, 8, 63, 12, 17, 90, 28, 70]
|
28
|
+
},
|
29
|
+
{
|
30
|
+
name: 'Feature B',
|
31
|
+
stroke: [47, 109, 104, thickness: 2],
|
32
|
+
x_value_start: @start_time,
|
33
|
+
x_interval_in_seconds: 8,
|
34
|
+
x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
|
35
|
+
y_values: [62, 0, 90, 0, 0, 27, 0, 56, 0, 0, 24, 0, 60, 0, 30, 0, 47, 0, 38, 90, 0]
|
36
|
+
},
|
37
|
+
],
|
38
|
+
display_attributes_on_hover: true,
|
39
|
+
)
|
40
|
+
|
41
|
+
on_content_size_changed do
|
42
|
+
@line_graph.width = main_window.content_size[0]
|
43
|
+
@line_graph.height = main_window.content_size[1] - 30
|
44
|
+
end
|
45
|
+
}
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
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.1.
|
5
|
+
# stub: glimmer-libui-cc-graphs_and_charts 0.1.7 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.1.
|
9
|
+
s.version = "0.1.7".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 = "2023-12-
|
14
|
+
s.date = "2023-12-23"
|
15
15
|
s.description = "Graphs and Charts (Custom Controls) for Glimmer DSL for LibUI, like Line Graph.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
"README.md",
|
26
26
|
"VERSION",
|
27
27
|
"examples/graphs_and_charts/basic_line_graph.rb",
|
28
|
+
"examples/graphs_and_charts/basic_line_graph_relative.rb",
|
28
29
|
"glimmer-libui-cc-graphs_and_charts.gemspec",
|
29
30
|
"lib/glimmer-libui-cc-graphs_and_charts.rb",
|
30
31
|
"lib/glimmer/view/line_graph.rb"
|
@@ -131,6 +131,11 @@ module Glimmer
|
|
131
131
|
def clear_drawing_cache
|
132
132
|
@graph_point_distance_per_line = nil
|
133
133
|
@y_value_max_for_all_lines = nil
|
134
|
+
@x_resolution = nil
|
135
|
+
@y_resolution = nil
|
136
|
+
@x_value_range_for_all_lines = nil
|
137
|
+
@x_value_min_for_all_lines = nil
|
138
|
+
@x_value_max_for_all_lines = nil
|
134
139
|
@grid_marker_points = nil
|
135
140
|
@points = nil
|
136
141
|
@grid_marker_number_values = nil
|
@@ -145,15 +150,23 @@ module Glimmer
|
|
145
150
|
end
|
146
151
|
|
147
152
|
def calculate_graph_point_distance_per_line
|
148
|
-
return unless graph_point_distance == :width_divided_by_point_count
|
153
|
+
return unless lines[0]&.[](:y_values) && graph_point_distance == :width_divided_by_point_count
|
149
154
|
|
150
155
|
@graph_point_distance_per_line ||= lines.inject({}) do |hash, line|
|
151
156
|
value = (width - 2.0*graph_padding_width - graph_grid_marker_padding_width) / (line[:y_values].size - 1).to_f
|
152
|
-
value = [value,
|
157
|
+
value = [value, width_drawable].min
|
153
158
|
hash.merge(line => value)
|
154
159
|
end
|
155
160
|
end
|
156
161
|
|
162
|
+
def width_drawable
|
163
|
+
width - 2.0*graph_padding_width - graph_grid_marker_padding_width
|
164
|
+
end
|
165
|
+
|
166
|
+
def height_drawable
|
167
|
+
height - 2.0*graph_padding_height
|
168
|
+
end
|
169
|
+
|
157
170
|
def graph_point_distance_for_line(line)
|
158
171
|
@graph_point_distance_per_line&.[](line) || graph_point_distance
|
159
172
|
end
|
@@ -176,8 +189,15 @@ module Glimmer
|
|
176
189
|
@grid_marker_numbers ||= []
|
177
190
|
@graph_stroke_marker_values ||= []
|
178
191
|
@mod_values ||= []
|
192
|
+
if lines && lines.all? {|line| line[:values]} && !y_value_max_for_all_lines.nil? && y_value_max_for_all_lines > 1
|
193
|
+
return
|
194
|
+
end
|
179
195
|
grid_marker_points.each_with_index do |marker_point, index|
|
180
|
-
@grid_marker_number_values[index] ||=
|
196
|
+
@grid_marker_number_values[index] ||= begin
|
197
|
+
value = (grid_marker_points.size - index).to_i
|
198
|
+
value = y_value_max_for_all_lines if !y_value_max_for_all_lines.nil? && y_value_max_for_all_lines.to_i != y_value_max_for_all_lines && grid_marker_points.size == 1
|
199
|
+
value
|
200
|
+
end
|
181
201
|
grid_marker_number_value = @grid_marker_number_values[index]
|
182
202
|
@grid_marker_numbers[index] ||= (grid_marker_number_value >= 1000) ? "#{grid_marker_number_value / 1000}K" : grid_marker_number_value.to_s
|
183
203
|
grid_marker_number = @grid_marker_numbers[index]
|
@@ -207,7 +227,7 @@ module Glimmer
|
|
207
227
|
stroke graph_stroke_marker_line
|
208
228
|
}
|
209
229
|
end
|
210
|
-
if grid_marker_number_value % mod_value == comparison_value
|
230
|
+
if grid_marker_number_value % mod_value == comparison_value || grid_marker_number_value != grid_marker_number_value.to_i
|
211
231
|
grid_marker_number_width = estimate_width_of_text(grid_marker_number, grid_marker_number_font)
|
212
232
|
text(marker_point[:x] + 4 + 3, marker_point[:y] - 6, grid_marker_number_width) {
|
213
233
|
string(grid_marker_number) {
|
@@ -221,10 +241,10 @@ module Glimmer
|
|
221
241
|
|
222
242
|
def grid_marker_points
|
223
243
|
if @grid_marker_points.nil?
|
224
|
-
|
244
|
+
graph_y_max = [y_value_max_for_all_lines, y_value_max_for_all_lines.between?(0, 1) ? y_value_max_for_all_lines : 1].max
|
225
245
|
current_graph_height = (height - graph_padding_height * 2)
|
226
|
-
division_height = current_graph_height /
|
227
|
-
@grid_marker_points =
|
246
|
+
division_height = current_graph_height / graph_y_max
|
247
|
+
@grid_marker_points = graph_y_max.ceil.times.map do |marker_index|
|
228
248
|
x = graph_padding_width
|
229
249
|
y = graph_padding_height + marker_index * division_height
|
230
250
|
{x: x, y: y}
|
@@ -244,7 +264,7 @@ module Glimmer
|
|
244
264
|
def single_line_graph(graph_line)
|
245
265
|
last_point = nil
|
246
266
|
points = calculate_points(graph_line)
|
247
|
-
points.each do |point|
|
267
|
+
points.to_a.each do |point|
|
248
268
|
if last_point
|
249
269
|
line(last_point[:x], last_point[:y], point[:x], point[:y]) {
|
250
270
|
stroke graph_line[:stroke]
|
@@ -260,14 +280,22 @@ module Glimmer
|
|
260
280
|
end
|
261
281
|
|
262
282
|
def calculate_points(graph_line)
|
283
|
+
if lines[0]&.[](:y_values)
|
284
|
+
calculate_points_relative(graph_line)
|
285
|
+
else
|
286
|
+
calculate_points_absolute(graph_line)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def calculate_points_relative(graph_line)
|
263
291
|
@points ||= {}
|
264
292
|
if @points[graph_line].nil?
|
265
293
|
y_values = graph_line[:y_values] || []
|
266
294
|
y_values = y_values[0, max_visible_point_count(graph_line)]
|
267
|
-
|
295
|
+
graph_y_max = [y_value_max_for_all_lines, 1].max
|
268
296
|
points = y_values.each_with_index.map do |y_value, index|
|
269
297
|
x = width - graph_padding_width - (index * graph_point_distance_for_line(graph_line))
|
270
|
-
y = ((height - graph_padding_height) - y_value * ((height - graph_padding_height * 2) /
|
298
|
+
y = ((height - graph_padding_height) - y_value * ((height - graph_padding_height * 2) / graph_y_max))
|
271
299
|
{x: x, y: y, index: index, y_value: y_value}
|
272
300
|
end
|
273
301
|
@points[graph_line] = translate_points(graph_line, points)
|
@@ -275,9 +303,74 @@ module Glimmer
|
|
275
303
|
@points[graph_line]
|
276
304
|
end
|
277
305
|
|
306
|
+
def calculate_points_absolute(graph_line)
|
307
|
+
@points ||= {}
|
308
|
+
if @points[graph_line].nil?
|
309
|
+
values = graph_line[:values] || []
|
310
|
+
# all points are visible when :values is supplied because we stretch the graph to show them all
|
311
|
+
graph_y_max = [y_value_max_for_all_lines, 1].max
|
312
|
+
x_value_range_for_all_lines
|
313
|
+
points = values.each_with_index.map do |(x_value, y_value), index|
|
314
|
+
relative_x_value = x_value - x_value_min_for_all_lines
|
315
|
+
scaled_x_value = x_value_range_for_all_lines == 0 ? 0 : relative_x_value.to_f * x_resolution.to_f
|
316
|
+
scaled_y_value = y_value_max_for_all_lines == 0 ? 0 : y_value.to_f * y_resolution.to_f
|
317
|
+
x = width - graph_padding_width - scaled_x_value
|
318
|
+
y = height - graph_padding_height - scaled_y_value
|
319
|
+
{x: x, y: y, index: index, x_value: x_value, y_value: y_value}
|
320
|
+
end
|
321
|
+
# Translation is not supported today
|
322
|
+
# TODO consider supporting in the future
|
323
|
+
# @points[graph_line] = translate_points(graph_line, points)
|
324
|
+
@points[graph_line] = points
|
325
|
+
end
|
326
|
+
@points[graph_line]
|
327
|
+
end
|
328
|
+
|
329
|
+
# this is the multiplier that we must multiply by the relative x value
|
330
|
+
def x_resolution
|
331
|
+
@x_resolution ||= width_drawable.to_f / x_value_range_for_all_lines.to_f
|
332
|
+
end
|
333
|
+
|
334
|
+
# this is the multiplier that we must multiply by the relative y value
|
335
|
+
def y_resolution
|
336
|
+
# TODO in the future, we will use the y range, but today, we assume it starts at 0
|
337
|
+
@y_resolution ||= height_drawable.to_f / y_value_max_for_all_lines.to_f
|
338
|
+
end
|
339
|
+
|
340
|
+
def x_value_range_for_all_lines
|
341
|
+
@x_value_range_for_all_lines ||= x_value_max_for_all_lines - x_value_min_for_all_lines
|
342
|
+
end
|
343
|
+
|
344
|
+
def x_value_min_for_all_lines
|
345
|
+
if @x_value_min_for_all_lines.nil?
|
346
|
+
line_visible_x_values = lines.map { |line| line[:values].to_h.keys }
|
347
|
+
all_visible_x_values = line_visible_x_values.reduce(:+) || []
|
348
|
+
# Right now, we assume Time objects
|
349
|
+
# TODO support String representations of Time (w/ some auto-detection of format)
|
350
|
+
@x_value_min_for_all_lines = all_visible_x_values.min
|
351
|
+
end
|
352
|
+
@x_value_min_for_all_lines
|
353
|
+
end
|
354
|
+
|
355
|
+
def x_value_max_for_all_lines
|
356
|
+
if @x_value_max_for_all_lines.nil?
|
357
|
+
line_visible_x_values = lines.map { |line| line[:values].to_h.keys }
|
358
|
+
all_visible_x_values = line_visible_x_values.reduce(:+) || []
|
359
|
+
# Right now, we assume Time objects
|
360
|
+
# TODO support String representations of Time (w/ some auto-detection of format)
|
361
|
+
@x_value_max_for_all_lines = all_visible_x_values.max
|
362
|
+
end
|
363
|
+
@x_value_max_for_all_lines
|
364
|
+
end
|
365
|
+
|
278
366
|
def y_value_max_for_all_lines
|
279
367
|
if @y_value_max_for_all_lines.nil?
|
280
|
-
|
368
|
+
if lines[0]&.[](:y_values)
|
369
|
+
line_visible_y_values = lines.map { |line| line[:y_values][0, max_visible_point_count(line)] }
|
370
|
+
else
|
371
|
+
# When using :values , we always stretch the graph so that all points are visible
|
372
|
+
line_visible_y_values = lines.map { |line| line[:values].to_h.values }
|
373
|
+
end
|
281
374
|
all_visible_y_values = line_visible_y_values.reduce(:+) || []
|
282
375
|
@y_value_max_for_all_lines = all_visible_y_values.max.to_f
|
283
376
|
end
|
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.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
11
|
+
date: 2023-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer-dsl-libui
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- README.md
|
82
82
|
- VERSION
|
83
83
|
- examples/graphs_and_charts/basic_line_graph.rb
|
84
|
+
- examples/graphs_and_charts/basic_line_graph_relative.rb
|
84
85
|
- glimmer-libui-cc-graphs_and_charts.gemspec
|
85
86
|
- lib/glimmer-libui-cc-graphs_and_charts.rb
|
86
87
|
- lib/glimmer/view/line_graph.rb
|