glimmer-libui-cc-graphs_and_charts 0.1.7 → 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: c2a02d818ffec27e5d64eafa181c90e1362b62ea8f201018fe92705b0d95a664
4
- data.tar.gz: 6de4a548a1c74d91cc389663d9917311bd66523402ba984ac05a250d8cff5baa
3
+ metadata.gz: acbf90f4dea0bb8e51f88a168609f66ba4213edc6a5c2d914fac53b56d8f0a16
4
+ data.tar.gz: 9c8683f23025fd089c727b8588f0abcd0a67c0a0b7823b72c8b50cfb214e47e6
5
5
  SHA512:
6
- metadata.gz: 738a36dedf90e91774876d7cc41f545edb00ac03d65cd6bf89eaf30eac5374b4abfa591d007d971476a02dd854ca14a262a7fcda34fdc24ac531b17509ee0dcf
7
- data.tar.gz: 2039bf32f7d8fb7930c24fda0eba1def6c30db968d452cb219a7ceab604bfed450b87b8d68ae061d75017ea59f6161d46b9fbebd8ab5581727116ebfd32fec82
6
+ metadata.gz: 62efa378b3b353e714f5d46a31f2d6c10e7ee6100d20e8d7e3f804a5b256e580d32a650c193453ee5db9b9d297abd04c322669e75f8c6ffc68093a3896991c87
7
+ data.tar.gz: f684d8493aeea2180ce75bf5d99cb6a21c40a31475e818ec9ae1282426a56c1f3d3f2edb515ba80b79aa03021509680a25f9c51d4b73100384cf5829a35e767c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.2.0
4
+
5
+ - Initial implementation of `bar_chart` custom control
6
+ - New `examples/graphs_and_charts/basic_bar_chart.rb`
7
+
8
+ ## 0.1.8
9
+
10
+ - Fix the display of grid marker lines when passing `values` with non-Integer y-axis values (especially max y-axis value being non-Integer). It now shows highest grid marker having a non-Integer value while keeping smaller values as Integer (e.g. 1, 2, 3, 3.75).
11
+
3
12
  ## 0.1.7
4
13
 
5
14
  - Scale `y` axis when using `values` option to fill up the vertical graph height if all y-axis values are smaller than `1`
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
- # Graphs and Charts 0.1.7 (Alpha)
1
+ # Graphs and Charts 0.2.0 (Alpha)
2
2
  ## [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui) Custom Controls
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-libui-cc-graphs_and_charts.svg)](http://badge.fury.io/rb/glimmer-libui-cc-graphs_and_charts)
4
4
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](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
+ ![bar chart](/screenshots/glimmer-libui-cc-graphs_and_charts-mac-basic-bar-chart.png)
9
+
8
10
  ![line graph](/screenshots/glimmer-libui-cc-graphs_and_charts-mac-basic-line-graph-relative.png)
9
11
 
10
12
  ## Setup
@@ -12,7 +14,7 @@ Graphs and Charts (Custom Controls) for [Glimmer DSL for LibUI](https://github.c
12
14
  Add this line to Bundler `Gemfile`:
13
15
 
14
16
  ```ruby
15
- gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.1.7'
17
+ gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.2.0'
16
18
  ```
17
19
 
18
20
  Run:
@@ -31,6 +33,89 @@ However, if you prefer to load all graphs and charts, add this line to your Ruby
31
33
  require 'glimmer-libui-cc-graphs_and_charts'
32
34
  ```
33
35
 
36
+ ### Bar Chart
37
+
38
+ To load the `bar_chart` custom control, add this line to your Ruby file:
39
+
40
+ ```ruby
41
+ require 'glimmer/view/bar_chart'
42
+ ```
43
+
44
+ This makes the `bar_chart` [Glimmer DSL for LibUI Custom Control](https://github.com/AndyObtiva/glimmer-dsl-libui#custom-components) available in the Glimmer GUI DSL.
45
+ You can then nest `bar_chart` under `window` or some container like `vertical_box`. By the way, `bar_chart` is implemented on top of the [`area` Glimmer DSL for LibUI control](https://github.com/AndyObtiva/glimmer-dsl-libui#area-api).
46
+
47
+ `values` are a `Hash` map of `String` x-axis values to `Numeric` y-axis values.
48
+
49
+ ```ruby
50
+ bar_chart(
51
+ width: 900,
52
+ height: 300,
53
+ values: {
54
+ 'Jan' => 30,
55
+ 'Feb' => 49,
56
+ 'Mar' => 58,
57
+ 'Apr' => 63,
58
+ 'May' => 72,
59
+ 'Jun' => 86,
60
+ 'Jul' => 95,
61
+ 'Aug' => 100,
62
+ 'Sep' => 84,
63
+ 'Oct' => 68,
64
+ 'Nov' => 52,
65
+ 'Dec' => 36,
66
+ }
67
+ )
68
+ ```
69
+
70
+ ![basic bar chart](/screenshots/glimmer-libui-cc-graphs_and_charts-mac-basic-bar-chart.png)
71
+
72
+ Look into [lib/glimmer/view/bar_chart.rb](/lib/glimmer/view/bar_chart.rb) to learn about all supported options.
73
+
74
+ **Basic Bar Chart Example:**
75
+
76
+ [examples/graphs_and_charts/basic_bar_chart.rb](/examples/graphs_and_charts/basic_bar_chart.rb)
77
+
78
+ ```ruby
79
+ require 'glimmer-dsl-libui'
80
+ require 'glimmer/view/bar_chart'
81
+
82
+ class BasicBarChart
83
+ include Glimmer::LibUI::Application
84
+
85
+ body {
86
+ window('Basic Bar Chart', 900, 300) { |main_window|
87
+ @bar_chart = bar_chart(
88
+ width: 900,
89
+ height: 300,
90
+ values: {
91
+ 'Jan' => 30,
92
+ 'Feb' => 49,
93
+ 'Mar' => 58,
94
+ 'Apr' => 63,
95
+ 'May' => 72,
96
+ 'Jun' => 86,
97
+ 'Jul' => 95,
98
+ 'Aug' => 100,
99
+ 'Sep' => 84,
100
+ 'Oct' => 68,
101
+ 'Nov' => 52,
102
+ 'Dec' => 36,
103
+ }
104
+ )
105
+
106
+ on_content_size_changed do
107
+ @bar_chart.width = main_window.content_size[0]
108
+ @bar_chart.height = main_window.content_size[1]
109
+ end
110
+ }
111
+ }
112
+ end
113
+
114
+ BasicBarChart.launch
115
+ ```
116
+
117
+ ![basic bar chart](/screenshots/glimmer-libui-cc-graphs_and_charts-mac-basic-bar-chart.png)
118
+
34
119
  ### Line Graph
35
120
 
36
121
  To load the `line_graph` custom control, add this line to your Ruby file:
@@ -51,36 +136,36 @@ Note that you can use in absolute mode or relative mode for determining x-axis v
51
136
  It supports any `Numeric` y-axis values in addition to `Time` x-axis values.
52
137
 
53
138
  ```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
- )
139
+ line_graph(
140
+ width: 900,
141
+ height: 300,
142
+ lines: [
143
+ {
144
+ name: 'Stock 1',
145
+ stroke: [163, 40, 39, thickness: 2],
146
+ values: {
147
+ Time.new(2030, 12, 1) => 80,
148
+ Time.new(2030, 12, 2) => 36,
149
+ Time.new(2030, 12, 4) => 10,
150
+ Time.new(2030, 12, 5) => 60,
151
+ Time.new(2030, 12, 6) => 20,
152
+ },
153
+ x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
154
+ },
155
+ {
156
+ name: 'Stock 2',
157
+ stroke: [47, 109, 104, thickness: 2],
158
+ values: {
159
+ Time.new(2030, 12, 1) => 62,
160
+ Time.new(2030, 12, 2) => 0,
161
+ Time.new(2030, 12, 3) => 90,
162
+ Time.new(2030, 12, 5) => 0,
163
+ Time.new(2030, 12, 7) => 17,
164
+ },
165
+ x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
166
+ },
167
+ ],
168
+ )
84
169
  ```
85
170
 
86
171
  ![basic line graph](/screenshots/glimmer-libui-cc-graphs_and_charts-mac-basic-line-graph.png)
@@ -183,7 +268,7 @@ BasicLineGraph.launch
183
268
  require 'glimmer-dsl-libui'
184
269
  require 'glimmer/view/line_graph'
185
270
 
186
- class BasicLineGraph
271
+ class BasicLineGraphRelative
187
272
  include Glimmer::LibUI::Application
188
273
 
189
274
  before_body do
@@ -191,7 +276,7 @@ class BasicLineGraph
191
276
  end
192
277
 
193
278
  body {
194
- window('Basic Line Graph', 900, 330) {
279
+ window('Basic Line Graph Relative', 900, 330) {
195
280
  line_graph(
196
281
  width: 900,
197
282
  height: 300,
@@ -220,7 +305,7 @@ class BasicLineGraph
220
305
  }
221
306
  end
222
307
 
223
- BasicLineGraph.launch
308
+ BasicLineGraphRelative.launch
224
309
  ```
225
310
 
226
311
  ![basic line graph relative](/screenshots/glimmer-libui-cc-graphs_and_charts-mac-basic-line-graph-relative.png)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.7
1
+ 0.2.0
@@ -0,0 +1,39 @@
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/bar_chart'
6
+
7
+ class BasicBarChart
8
+ include Glimmer::LibUI::Application
9
+
10
+ body {
11
+ window('Basic Bar Chart', 900, 300) { |main_window|
12
+ @bar_chart = bar_chart(
13
+ width: 900,
14
+ height: 300,
15
+ values: {
16
+ 'Jan' => 30,
17
+ 'Feb' => 49,
18
+ 'Mar' => 58,
19
+ 'Apr' => 63,
20
+ 'May' => 72,
21
+ 'Jun' => 86,
22
+ 'Jul' => 95,
23
+ 'Aug' => 100,
24
+ 'Sep' => 84,
25
+ 'Oct' => 68,
26
+ 'Nov' => 52,
27
+ 'Dec' => 36,
28
+ }
29
+ )
30
+
31
+ on_content_size_changed do
32
+ @bar_chart.width = main_window.content_size[0]
33
+ @bar_chart.height = main_window.content_size[1]
34
+ end
35
+ }
36
+ }
37
+ end
38
+
39
+ BasicBarChart.launch
@@ -17,11 +17,11 @@ class BasicLineGraph
17
17
  name: 'Stock 1',
18
18
  stroke: [163, 40, 39, thickness: 2],
19
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,
20
+ Time.new(2030, 12, 1) => 2,
21
+ Time.new(2030, 12, 2) => 2.5,
22
+ Time.new(2030, 12, 4) => 1,
23
+ Time.new(2030, 12, 5) => 0,
24
+ Time.new(2030, 12, 6) => 2,
25
25
  },
26
26
  x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
27
27
  },
@@ -29,11 +29,11 @@ class BasicLineGraph
29
29
  name: 'Stock 2',
30
30
  stroke: [47, 109, 104, thickness: 2],
31
31
  values: {
32
- Time.new(2030, 12, 1) => 62,
32
+ Time.new(2030, 12, 1) => 2,
33
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,
34
+ Time.new(2030, 12, 3) => 2.5,
35
+ Time.new(2030, 12, 5) => 1,
36
+ Time.new(2030, 12, 7) => 2,
37
37
  },
38
38
  x_value_format: -> (time) {time.strftime("%a %d %b %Y %T GMT")},
39
39
  },
@@ -4,7 +4,7 @@ $LOAD_PATH.prepend(File.expand_path(File.join(__dir__, '..', '..', 'lib'))) if F
4
4
  require 'glimmer-dsl-libui'
5
5
  require 'glimmer/view/line_graph'
6
6
 
7
- class BasicLineGraph
7
+ class BasicLineGraphRelative
8
8
  include Glimmer::LibUI::Application
9
9
 
10
10
  before_body do
@@ -12,7 +12,7 @@ class BasicLineGraph
12
12
  end
13
13
 
14
14
  body {
15
- window('Basic Line Graph', 900, 330) { |main_window|
15
+ window('Basic Line Graph Relative', 900, 330) { |main_window|
16
16
  @line_graph = line_graph(
17
17
  width: 900,
18
18
  height: 300,
@@ -46,4 +46,4 @@ class BasicLineGraph
46
46
  }
47
47
  end
48
48
 
49
- BasicLineGraph.launch
49
+ BasicLineGraphRelative.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.7 ruby lib
5
+ # stub: glimmer-libui-cc-graphs_and_charts 0.2.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.1.7".freeze
9
+ s.version = "0.2.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 = "2023-12-23"
14
+ s.date = "2023-12-29"
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 = [
@@ -24,15 +24,17 @@ Gem::Specification.new do |s|
24
24
  "LICENSE.txt",
25
25
  "README.md",
26
26
  "VERSION",
27
+ "examples/graphs_and_charts/basic_bar_chart.rb",
27
28
  "examples/graphs_and_charts/basic_line_graph.rb",
28
29
  "examples/graphs_and_charts/basic_line_graph_relative.rb",
29
30
  "glimmer-libui-cc-graphs_and_charts.gemspec",
30
31
  "lib/glimmer-libui-cc-graphs_and_charts.rb",
32
+ "lib/glimmer/view/bar_chart.rb",
31
33
  "lib/glimmer/view/line_graph.rb"
32
34
  ]
33
35
  s.homepage = "http://github.com/AndyObtiva/glimmer-libui-cc-graphs_and_charts".freeze
34
36
  s.licenses = ["MIT".freeze]
35
- s.rubygems_version = "3.5.1".freeze
37
+ s.rubygems_version = "3.5.3".freeze
36
38
  s.summary = "Graphs and Charts - Glimmer DSL for LibUI Custom Controls".freeze
37
39
 
38
40
  s.specification_version = 4
@@ -0,0 +1,249 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ module Glimmer
4
+ module View
5
+ # General-Purpose Bar Chart Custom Control
6
+ class BarChart
7
+ class << self
8
+ def interpret_color(color_object)
9
+ # TODO refactor move this method to somewhere common like Glimmer module
10
+ @color_cache ||= {}
11
+ @color_cache[color_object] ||= Glimmer::LibUI.interpret_color(color_object)
12
+ end
13
+ end
14
+
15
+ include Glimmer::LibUI::CustomControl
16
+
17
+ DEFAULT_CHART_PADDING_WIDTH = 5.0
18
+ DEFAULT_CHART_PADDING_HEIGHT = 5.0
19
+ DEFAULT_CHART_GRID_MARKER_PADDING_WIDTH = 37.0
20
+ DEFAULT_CHART_BAR_PADDING_WIDTH_PERCENTAGE = 30.0
21
+
22
+ DEFAULT_CHART_STROKE_GRID = [185, 184, 185]
23
+ DEFAULT_CHART_STROKE_MARKER = [185, 184, 185]
24
+ DEFAULT_CHART_STROKE_MARKER_LINE = [217, 217, 217, thickness: 1, dashes: [1, 1]]
25
+
26
+ DEFAULT_CHART_COLOR_BAR = [92, 122, 190]
27
+ DEFAULT_CHART_COLOR_MARKER_TEXT = [96, 96, 96]
28
+
29
+ DEFAULT_CHART_FONT_MARKER_TEXT = {family: "Arial", size: 14}
30
+
31
+ option :width, default: 600
32
+ option :height, default: 200
33
+
34
+ option :chart_padding_width, default: DEFAULT_CHART_PADDING_WIDTH
35
+ option :chart_padding_height, default: DEFAULT_CHART_PADDING_HEIGHT
36
+ option :chart_grid_marker_padding_width, default: DEFAULT_CHART_GRID_MARKER_PADDING_WIDTH
37
+ option :chart_bar_padding_width_percentage, default: DEFAULT_CHART_BAR_PADDING_WIDTH_PERCENTAGE
38
+
39
+ option :chart_stroke_grid, default: DEFAULT_CHART_STROKE_GRID
40
+ option :chart_stroke_marker, default: DEFAULT_CHART_STROKE_MARKER
41
+ option :chart_stroke_marker_line, default: DEFAULT_CHART_STROKE_MARKER_LINE
42
+
43
+ option :chart_color_bar, default: DEFAULT_CHART_COLOR_BAR
44
+ option :chart_color_marker_text, default: DEFAULT_CHART_COLOR_MARKER_TEXT
45
+
46
+ option :chart_font_marker_text, default: DEFAULT_CHART_FONT_MARKER_TEXT
47
+
48
+ # Hash map of x-axis values (String) to y-axis values (Numeric)
49
+ # Example:
50
+ # {
51
+ # '1' => 38,
52
+ # '2' => 83,
53
+ # '3' => 48,
54
+ # '4' => 83,
55
+ # '5' => 92,
56
+ # '6' => 13,
57
+ # '7' => 03,
58
+ # }
59
+ option :values, default: {}
60
+
61
+ attr_reader :bar_width_including_padding
62
+
63
+ after_body do
64
+ observe(self, :values) do
65
+ clear_drawing_cache
66
+ body_root.queue_redraw_all
67
+ end
68
+ observe(self, :width) do
69
+ clear_drawing_cache
70
+ end
71
+ observe(self, :height) do
72
+ clear_drawing_cache
73
+ end
74
+ end
75
+
76
+ body {
77
+ area { |chart_area|
78
+ on_draw do
79
+ calculate_dynamic_options
80
+ chart_background
81
+ grid_lines
82
+ bars
83
+ end
84
+ }
85
+ }
86
+
87
+ private
88
+
89
+ def clear_drawing_cache
90
+ @y_resolution = nil
91
+ @bar_width_including_padding = nil
92
+ @grid_marker_points = nil
93
+ @grid_marker_number_values = nil
94
+ @grid_marker_numbers = nil
95
+ @chart_stroke_marker_values = nil
96
+ @mod_values = nil
97
+ end
98
+
99
+ def calculate_dynamic_options
100
+ calculate_bar_width_including_padding
101
+ end
102
+
103
+ def calculate_bar_width_including_padding
104
+ return if values.empty?
105
+
106
+ @bar_width_including_padding ||= begin
107
+ value = width_drawable / (values.size - 1).to_f
108
+ [value, width_drawable].min
109
+ end
110
+ end
111
+
112
+ def bar_width
113
+ @bar_width_including_padding*((100.0 - chart_bar_padding_width_percentage)/100.0)
114
+ end
115
+
116
+ def bar_padding_width
117
+ @bar_width_including_padding*(chart_bar_padding_width_percentage/100.0)
118
+ end
119
+
120
+ def width_drawable
121
+ width - 2.0*chart_padding_width - chart_grid_marker_padding_width
122
+ end
123
+
124
+ def height_drawable
125
+ height - 2.0*chart_padding_height
126
+ end
127
+
128
+ def chart_background
129
+ rectangle(0, 0, width, height) {
130
+ fill 255, 255, 255
131
+ }
132
+ end
133
+
134
+ def grid_lines
135
+ line(chart_padding_width, chart_padding_height, chart_padding_width, height - chart_padding_height) {
136
+ stroke chart_stroke_grid
137
+ }
138
+ line(chart_padding_width, height - chart_padding_height, width - chart_padding_width, height - chart_padding_height) {
139
+ stroke chart_stroke_grid
140
+ }
141
+ grid_marker_number_font = chart_font_marker_text.merge(size: 11)
142
+ @grid_marker_number_values ||= []
143
+ @grid_marker_numbers ||= []
144
+ @chart_stroke_marker_values ||= []
145
+ @mod_values ||= []
146
+ grid_marker_points.each_with_index do |marker_point, index|
147
+ @grid_marker_number_values[index] ||= begin
148
+ value = (grid_marker_points.size - index).to_i
149
+ value = y_value_max if !y_value_max.nil? && y_value_max.to_i != y_value_max && index == 0
150
+ value
151
+ end
152
+ grid_marker_number_value = @grid_marker_number_values[index]
153
+ @grid_marker_numbers[index] ||= (grid_marker_number_value >= 1000) ? "#{grid_marker_number_value / 1000}K" : grid_marker_number_value.to_s
154
+ grid_marker_number = @grid_marker_numbers[index]
155
+ @chart_stroke_marker_values[index] ||= BarChart.interpret_color(chart_stroke_marker).tap do |color_hash|
156
+ color_hash[:thickness] = (index != grid_marker_points.size - 1 ? 2 : 1) if color_hash[:thickness].nil?
157
+ end
158
+ chart_stroke_marker_value = @chart_stroke_marker_values[index]
159
+ @mod_values[index] ||= begin
160
+ mod_value_multiplier = ((grid_marker_points.size / max_marker_count) + 1)
161
+ [(5 * mod_value_multiplier), 1].max
162
+ end
163
+ mod_value = @mod_values[index]
164
+ comparison_value = (mod_value > 2) ? 0 : 1
165
+ if mod_value > 2
166
+ if grid_marker_number_value % mod_value == comparison_value
167
+ line(marker_point[:x], marker_point[:y], marker_point[:x] + 4, marker_point[:y]) {
168
+ stroke chart_stroke_marker_value
169
+ }
170
+ end
171
+ else
172
+ line(marker_point[:x], marker_point[:y], marker_point[:x] + 4, marker_point[:y]) {
173
+ stroke chart_stroke_marker_value
174
+ }
175
+ end
176
+ if grid_marker_number_value % mod_value == comparison_value && grid_marker_number_value != grid_marker_points.size
177
+ line(marker_point[:x], marker_point[:y], marker_point[:x] + width - chart_padding_width, marker_point[:y]) {
178
+ stroke chart_stroke_marker_line
179
+ }
180
+ end
181
+ if grid_marker_number_value % mod_value == comparison_value || grid_marker_number_value != grid_marker_number_value.to_i
182
+ grid_marker_number_width = estimate_width_of_text(grid_marker_number, grid_marker_number_font)
183
+ text(marker_point[:x] + 4 + 3, marker_point[:y] - 6, grid_marker_number_width) {
184
+ string(grid_marker_number) {
185
+ font grid_marker_number_font
186
+ color chart_color_marker_text
187
+ }
188
+ }
189
+ end
190
+ end
191
+ end
192
+
193
+ def grid_marker_points
194
+ if @grid_marker_points.nil?
195
+ if values.any?
196
+ chart_y_max = [y_value_max, 1].max
197
+ current_chart_height = (height - chart_padding_height * 2)
198
+ y_value_count = chart_y_max.ceil
199
+ @grid_marker_points = chart_y_max.to_i.times.map do |marker_index|
200
+ x = chart_padding_width
201
+ y_value = y_value_count - marker_index
202
+ scaled_y_value = y_value.to_f * y_resolution.to_f
203
+ y = height - chart_padding_height - scaled_y_value
204
+ {x: x, y: y}
205
+ end
206
+ end
207
+ end
208
+
209
+ @grid_marker_points
210
+ end
211
+
212
+ def max_marker_count
213
+ [(0.15*height).to_i, 1].max
214
+ end
215
+
216
+ def bars
217
+ values.each_with_index do |(x_value, y_value), index|
218
+ x = chart_grid_marker_padding_width + chart_padding_width + (index * bar_width_including_padding) + bar_padding_width
219
+ bar_height = y_value * y_resolution
220
+ y = height - chart_padding_height - bar_height
221
+ rectangle(x, y, bar_width, bar_height) {
222
+ fill chart_color_bar
223
+ }
224
+ end
225
+ end
226
+
227
+ # this is the multiplier that we must multiply by the relative y value
228
+ def y_resolution
229
+ # TODO in the future, we will use the y range, but today, we assume it starts at 0
230
+ @y_resolution ||= height_drawable.to_f / y_value_max.to_f
231
+ end
232
+
233
+ def y_value_max
234
+ if @y_value_max.nil?
235
+ @y_value_max = values.values.max.to_f
236
+ end
237
+ @y_value_max
238
+ end
239
+
240
+ def estimate_width_of_text(text_string, font_properties)
241
+ # TODO refactor move this method to somewhere common like Glimmer module
242
+ font_size = font_properties[:size] || 16
243
+ estimated_font_width = 0.6 * font_size
244
+ text_string.chars.size * estimated_font_width
245
+ end
246
+
247
+ end
248
+ end
249
+ end
@@ -142,7 +142,6 @@ module Glimmer
142
142
  @grid_marker_numbers = nil
143
143
  @graph_stroke_marker_values = nil
144
144
  @mod_values = nil
145
- @estimated_widths_of_text = nil
146
145
  end
147
146
 
148
147
  def calculate_dynamic_options
@@ -189,13 +188,10 @@ module Glimmer
189
188
  @grid_marker_numbers ||= []
190
189
  @graph_stroke_marker_values ||= []
191
190
  @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
195
191
  grid_marker_points.each_with_index do |marker_point, index|
196
192
  @grid_marker_number_values[index] ||= begin
197
193
  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
194
+ 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 && index == 0
199
195
  value
200
196
  end
201
197
  grid_marker_number_value = @grid_marker_number_values[index]
@@ -241,15 +237,31 @@ module Glimmer
241
237
 
242
238
  def grid_marker_points
243
239
  if @grid_marker_points.nil?
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
245
- current_graph_height = (height - graph_padding_height * 2)
246
- division_height = current_graph_height / graph_y_max
247
- @grid_marker_points = graph_y_max.ceil.times.map do |marker_index|
248
- x = graph_padding_width
249
- y = graph_padding_height + marker_index * division_height
250
- {x: x, y: y}
240
+ if lines[0]&.[](:y_values)
241
+ graph_y_max = [y_value_max_for_all_lines, 1].max
242
+ current_graph_height = (height - graph_padding_height * 2)
243
+ division_height = current_graph_height / graph_y_max
244
+ @grid_marker_points = graph_y_max.to_i.times.map do |marker_index|
245
+ x = graph_padding_width
246
+ y = graph_padding_height + marker_index * division_height
247
+ {x: x, y: y}
248
+ end
249
+ else
250
+ graph_y_max = y_value_max_for_all_lines
251
+ y_value_count = graph_y_max.ceil
252
+ @grid_marker_points = y_value_count.times.map do |marker_index|
253
+ x = graph_padding_width
254
+ y_value = y_value_count - marker_index
255
+ if marker_index == 0 && graph_y_max.ceil != graph_y_max.to_i
256
+ y_value = graph_y_max
257
+ end
258
+ scaled_y_value = y_value.to_f * y_resolution.to_f
259
+ y = height - graph_padding_height - scaled_y_value
260
+ {x: x, y: y}
261
+ end
251
262
  end
252
263
  end
264
+
253
265
  @grid_marker_points
254
266
  end
255
267
 
@@ -1,4 +1,5 @@
1
1
  $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
2
2
 
3
3
  require 'glimmer-dsl-libui'
4
+ require 'glimmer/view/bar_chart'
4
5
  require 'glimmer/view/line_graph'
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.7
4
+ version: 0.2.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: 2023-12-23 00:00:00.000000000 Z
11
+ date: 2023-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer-dsl-libui
@@ -80,10 +80,12 @@ files:
80
80
  - LICENSE.txt
81
81
  - README.md
82
82
  - VERSION
83
+ - examples/graphs_and_charts/basic_bar_chart.rb
83
84
  - examples/graphs_and_charts/basic_line_graph.rb
84
85
  - examples/graphs_and_charts/basic_line_graph_relative.rb
85
86
  - glimmer-libui-cc-graphs_and_charts.gemspec
86
87
  - lib/glimmer-libui-cc-graphs_and_charts.rb
88
+ - lib/glimmer/view/bar_chart.rb
87
89
  - lib/glimmer/view/line_graph.rb
88
90
  homepage: http://github.com/AndyObtiva/glimmer-libui-cc-graphs_and_charts
89
91
  licenses:
@@ -104,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
106
  - !ruby/object:Gem::Version
105
107
  version: '0'
106
108
  requirements: []
107
- rubygems_version: 3.5.1
109
+ rubygems_version: 3.5.3
108
110
  signing_key:
109
111
  specification_version: 4
110
112
  summary: Graphs and Charts - Glimmer DSL for LibUI Custom Controls