glimmer-libui-cc-graphs_and_charts 0.1.3 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aefbc0c06b3968b4e633e3d923cf886e64421d5debea0e0e8a2376a54b45df86
4
- data.tar.gz: beb20ca4b10e5ff0187becd7e1d3aeb087033a35093ea932dcde4a4b980ae22f
3
+ metadata.gz: 13c6855a27c49f14aaa6bc865f8d954a4500a86b99943446a9b9c7d8f153bd87
4
+ data.tar.gz: 1fb52e2748e28024d4dbd46f9077a4b1e14aae00367487c16b622b514404cf56
5
5
  SHA512:
6
- metadata.gz: 619d28542b4a45eaa32b1f71e912ca24e11ba48ececef50bb7a5503ee0854a17591df78b2e6202f90625b747947b661f5a247e8eeb4c4fdf6ef1cf7ae8bbce6f
7
- data.tar.gz: 1d48203f5a1a03e0c84eb60301085bd89c4cf589a41214b825d07ea22afa2a910fc331f80a62802e1c7e2b2d4f29b0daab63150da1cbb8c48eed76f27926b331
6
+ metadata.gz: 0ce8817b76f6b9cc5ac0c5fc88223aa4c07625f747d3a79dc95569055862a77e65578543134be4fff45f783a83098d509abf27f7db48fe1bd4fdf1412a4c9fc0
7
+ data.tar.gz: 933bdaeb6f80038e708b13dee69f43c7532fe2facc25a37f1598858179b9f8efb08d7a3665b085fee975e90c319df5ce08bc2913430103ae42933d52a738d243
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.1.5
4
+
5
+ - Render circles for every point in addition to the lines connecting all the points
6
+ - 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 custimizing the circle of every rendered point and selected point.
8
+ - Avoid rendering on top of the grid markers on the left side
9
+ - Optimize performance of rendering grid markers and showing mouse hover selection stats of a point
10
+
11
+ ## 0.1.4
12
+
13
+ - Fix issue with crashing at `lib/glimmer/view/line_graph.rb:243:in y_value_max_for_all_lines': undefined method max for nil:NilClass`
14
+
3
15
  ## 0.1.3
4
16
 
5
17
  - Fix issue with crashing if lines had points that did not share the same x-axis values as opposed to all points in all lines falling on the same x-axis values
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Graphs and Charts 0.1.3 (Alpha)
1
+ # Graphs and Charts 0.1.5 (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)
@@ -12,7 +12,7 @@ Graphs and Charts (Custom Controls) for [Glimmer DSL for LibUI](https://github.c
12
12
  Add this line to Bundler `Gemfile`:
13
13
 
14
14
  ```ruby
15
- gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.1.3'
15
+ gem 'glimmer-libui-cc-graphs_and_charts', '~> 0.1.5'
16
16
  ```
17
17
 
18
18
  Run:
@@ -71,6 +71,8 @@ line_graph(
71
71
 
72
72
  ![basic line graph](/screenshots/glimmer-libui-cc-graphs_and_charts-mac-basic-line-graph.png)
73
73
 
74
+ Look into [lib/glimmer/view/line_graph.rb](/lib/glimmer/view/line_graph.rb) to learn about all supported options.
75
+
74
76
  Basic Line Graph Example:
75
77
 
76
78
  [examples/graphs_and_charts/basic_line_graph.rb](/examples/graphs_and_charts/basic_line_graph.rb)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.5
@@ -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.3 ruby lib
5
+ # stub: glimmer-libui-cc-graphs_and_charts 0.1.5 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.3".freeze
9
+ s.version = "0.1.5".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-19"
14
+ s.date = "2023-12-21"
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 = [
@@ -4,12 +4,21 @@ module Glimmer
4
4
  module View
5
5
  # General-Purpose Line Graph Custom Control
6
6
  class LineGraph
7
+ class << self
8
+ def interpret_color(color_object)
9
+ @color_cache ||= {}
10
+ @color_cache[color_object] ||= Glimmer::LibUI.interpret_color(color_object)
11
+ end
12
+ end
13
+
7
14
  include Glimmer::LibUI::CustomControl
8
15
 
9
16
  DEFAULT_GRAPH_PADDING_WIDTH = 5.0
10
17
  DEFAULT_GRAPH_PADDING_HEIGHT = 5.0
11
- DEFAULT_GRAPH_GRID_MARKER_PADDING_WIDTH = 30.0
18
+ DEFAULT_GRAPH_GRID_MARKER_PADDING_WIDTH = 37.0
12
19
  DEFAULT_GRAPH_POINT_DISTANCE = 15.0
20
+ DEFAULT_GRAPH_POINT_RADIUS = 1.0
21
+ DEFAULT_GRAPH_SELECTED_POINT_RADIUS = 3.0
13
22
 
14
23
  DEFAULT_GRAPH_STROKE_GRID = [185, 184, 185]
15
24
  DEFAULT_GRAPH_STROKE_MARKER = [185, 184, 185]
@@ -17,6 +26,8 @@ module Glimmer
17
26
  DEFAULT_GRAPH_STROKE_PERIODIC_LINE = [121, 121, 121, thickness: 1, dashes: [1, 1]]
18
27
  DEFAULT_GRAPH_STROKE_HOVER_LINE = [133, 133, 133]
19
28
 
29
+ DEFAULT_GRAPH_FILL_SELECTED_POINT = :white
30
+
20
31
  DEFAULT_GRAPH_COLOR_MARKER_TEXT = [96, 96, 96]
21
32
  DEFAULT_GRAPH_COLOR_PERIOD_TEXT = [163, 40, 39]
22
33
 
@@ -44,6 +55,8 @@ module Glimmer
44
55
  option :graph_padding_height, default: DEFAULT_GRAPH_PADDING_HEIGHT
45
56
  option :graph_grid_marker_padding_width, default: DEFAULT_GRAPH_GRID_MARKER_PADDING_WIDTH
46
57
  option :graph_point_distance, default: DEFAULT_GRAPH_POINT_DISTANCE
58
+ option :graph_point_radius, default: DEFAULT_GRAPH_POINT_RADIUS
59
+ option :graph_selected_point_radius, default: DEFAULT_GRAPH_SELECTED_POINT_RADIUS
47
60
 
48
61
  option :graph_stroke_grid, default: DEFAULT_GRAPH_STROKE_GRID
49
62
  option :graph_stroke_marker, default: DEFAULT_GRAPH_STROKE_MARKER
@@ -51,6 +64,8 @@ module Glimmer
51
64
  option :graph_stroke_periodic_line, default: DEFAULT_GRAPH_STROKE_PERIODIC_LINE
52
65
  option :graph_stroke_hover_line, default: DEFAULT_GRAPH_STROKE_HOVER_LINE
53
66
 
67
+ option :graph_fill_selected_point, default: DEFAULT_GRAPH_FILL_SELECTED_POINT
68
+
54
69
  option :graph_color_marker_text, default: DEFAULT_GRAPH_COLOR_MARKER_TEXT
55
70
  option :graph_color_period_text, default: DEFAULT_GRAPH_COLOR_PERIOD_TEXT
56
71
 
@@ -93,7 +108,7 @@ module Glimmer
93
108
 
94
109
  if @hover_point && lines && lines[0] && @points && @points[lines[0]] && !@points[lines[0]].empty?
95
110
  x = @hover_point[:x]
96
- closest_point_index = @points[lines[0]].each_with_index.min_by { |point, index| (point[:x] - x).abs }[1]
111
+ closest_point_index = ((width - graph_padding_width - x) / graph_point_distance_for_line(lines[0])).round
97
112
  if closest_point_index != @closest_point_index
98
113
  @closest_point_index = closest_point_index
99
114
  graph_area.queue_redraw_all
@@ -118,6 +133,11 @@ module Glimmer
118
133
  @y_value_max_for_all_lines = nil
119
134
  @grid_marker_points = nil
120
135
  @points = nil
136
+ @grid_marker_number_values = nil
137
+ @grid_marker_numbers = nil
138
+ @graph_stroke_marker_values = nil
139
+ @mod_values = nil
140
+ @estimated_widths_of_text = nil
121
141
  end
122
142
 
123
143
  def calculate_dynamic_options
@@ -127,8 +147,10 @@ module Glimmer
127
147
  def calculate_graph_point_distance_per_line
128
148
  return unless graph_point_distance == :width_divided_by_point_count
129
149
 
130
- @graph_point_distance_per_line = lines.inject({}) do |hash, line|
131
- hash.merge(line => (width - 2.0*graph_padding_width - graph_grid_marker_padding_width) / (line[:y_values].size - 1).to_f)
150
+ @graph_point_distance_per_line ||= lines.inject({}) do |hash, line|
151
+ value = (width - 2.0*graph_padding_width - graph_grid_marker_padding_width) / (line[:y_values].size - 1).to_f
152
+ value = [value, width - 2.0*graph_padding_width - graph_grid_marker_padding_width].min
153
+ hash.merge(line => value)
132
154
  end
133
155
  end
134
156
 
@@ -149,12 +171,25 @@ module Glimmer
149
171
  line(graph_padding_width, height - graph_padding_height, width - graph_padding_width, height - graph_padding_height) {
150
172
  stroke graph_stroke_grid
151
173
  }
174
+ grid_marker_number_font = graph_font_marker_text.merge(size: 11)
175
+ @grid_marker_number_values ||= []
176
+ @grid_marker_numbers ||= []
177
+ @graph_stroke_marker_values ||= []
178
+ @mod_values ||= []
152
179
  grid_marker_points.each_with_index do |marker_point, index|
153
- grid_marker_number_value = (grid_marker_points.size - index).to_i
154
- grid_marker_number = (grid_marker_number_value >= 1000) ? "#{grid_marker_number_value / 1000}K" : grid_marker_number_value.to_s
155
- graph_stroke_marker_value = Glimmer::LibUI.interpret_color(graph_stroke_marker)
156
- graph_stroke_marker_value[:thickness] = (index != grid_marker_points.size - 1 ? 2 : 1) if graph_stroke_marker_value[:thickness].nil?
157
- mod_value = (2 * ((grid_marker_points.size / max_marker_count) + 1))
180
+ @grid_marker_number_values[index] ||= (grid_marker_points.size - index).to_i
181
+ grid_marker_number_value = @grid_marker_number_values[index]
182
+ @grid_marker_numbers[index] ||= (grid_marker_number_value >= 1000) ? "#{grid_marker_number_value / 1000}K" : grid_marker_number_value.to_s
183
+ grid_marker_number = @grid_marker_numbers[index]
184
+ @graph_stroke_marker_values[index] ||= LineGraph.interpret_color(graph_stroke_marker).tap do |color_hash|
185
+ color_hash[:thickness] = (index != grid_marker_points.size - 1 ? 2 : 1) if color_hash[:thickness].nil?
186
+ end
187
+ graph_stroke_marker_value = @graph_stroke_marker_values[index]
188
+ @mod_values[index] ||= begin
189
+ mod_value_multiplier = ((grid_marker_points.size / max_marker_count) + 1)
190
+ [((mod_value_multiplier <= 2 ? 2 : 5) * mod_value_multiplier), 1].max
191
+ end
192
+ mod_value = @mod_values[index]
158
193
  comparison_value = (mod_value > 2) ? 0 : 1
159
194
  if mod_value > 2
160
195
  if grid_marker_number_value % mod_value == comparison_value
@@ -173,7 +208,6 @@ module Glimmer
173
208
  }
174
209
  end
175
210
  if grid_marker_number_value % mod_value == comparison_value
176
- grid_marker_number_font = graph_font_marker_text.merge(size: 11)
177
211
  grid_marker_number_width = estimate_width_of_text(grid_marker_number, grid_marker_number_font)
178
212
  text(marker_point[:x] + 4 + 3, marker_point[:y] - 6, grid_marker_number_width) {
179
213
  string(grid_marker_number) {
@@ -216,6 +250,11 @@ module Glimmer
216
250
  stroke graph_line[:stroke]
217
251
  }
218
252
  end
253
+ if last_point.nil? || graph_point_radius > 1
254
+ circle(point[:x], point[:y], graph_point_radius) {
255
+ fill graph_line[:stroke]
256
+ }
257
+ end
219
258
  last_point = point
220
259
  end
221
260
  end
@@ -239,7 +278,7 @@ module Glimmer
239
278
  def y_value_max_for_all_lines
240
279
  if @y_value_max_for_all_lines.nil?
241
280
  line_visible_y_values = lines.map { |line| line[:y_values][0, max_visible_point_count(line)] }
242
- all_visible_y_values = line_visible_y_values.reduce(:+)
281
+ all_visible_y_values = line_visible_y_values.reduce(:+) || []
243
282
  @y_value_max_for_all_lines = all_visible_y_values.max.to_f
244
283
  end
245
284
  @y_value_max_for_all_lines
@@ -257,14 +296,16 @@ module Glimmer
257
296
  points
258
297
  end
259
298
 
260
- def max_visible_point_count(graph_line) = (width / graph_point_distance_for_line(graph_line)).to_i + 1
299
+ def max_visible_point_count(graph_line) = ((width - graph_grid_marker_padding_width) / graph_point_distance_for_line(graph_line)).to_i + 1
261
300
 
262
301
  def periodic_lines
263
302
  return unless lines && lines[0] && lines[0][:x_interval_in_seconds] && lines[0][:x_interval_in_seconds] == DAY_IN_SECONDS
264
303
  day_count = lines[0][:y_values].size
265
304
  case day_count
266
305
  when ..7
267
- @points[lines[0]].each do |point|
306
+ @points[lines[0]].each_with_index do |point, index|
307
+ next if index == 0
308
+
268
309
  line(point[:x], graph_padding_height, point[:x], height - graph_padding_height) {
269
310
  stroke graph_stroke_periodic_line
270
311
  }
@@ -323,68 +364,64 @@ module Glimmer
323
364
  x = @hover_point[:x]
324
365
  closest_points = lines.map { |line| @points[line][@closest_point_index] }
325
366
  closest_x = closest_points[0]&.[](:x)
326
- closest_x_distance = PerfectShape::Point.point_distance(x.to_f, 0, closest_x.to_f, 0)
327
- # Today, we make the assumption that all lines have points along the same x-axis values
328
- # TODO In the future, we can support different x values along different lines
329
- if closest_x_distance < graph_point_distance_for_line(lines[0])
330
- line(closest_x, graph_padding_height, closest_x, height - graph_padding_height) {
331
- stroke graph_stroke_hover_line
367
+ line(closest_x, graph_padding_height, closest_x, height - graph_padding_height) {
368
+ stroke graph_stroke_hover_line
369
+ }
370
+ closest_points.each_with_index do |closest_point, index|
371
+ next unless closest_point && closest_point[:x] && closest_point[:y]
372
+
373
+ circle(closest_point[:x], closest_point[:y], graph_selected_point_radius) {
374
+ fill graph_fill_selected_point == :line_stroke ? lines[index][:stroke] : graph_fill_selected_point
375
+ stroke_value = lines[index][:stroke].dup
376
+ stroke_value << {} unless stroke_value.last.is_a?(Hash)
377
+ stroke_value.last[:thickness] = 2
378
+ stroke stroke_value
332
379
  }
333
- closest_points.each_with_index do |closest_point, index|
334
- next unless closest_point && closest_point[:x] && closest_point[:y]
335
-
336
- circle(closest_point[:x], closest_point[:y], 4) {
337
- fill lines[index][:stroke]
338
- }
339
- circle(closest_point[:x], closest_point[:y], 2) {
340
- fill :white
341
- }
342
- end
343
- text_label = formatted_x_value(@closest_point_index)
344
- text_label_width = estimate_width_of_text(text_label, DEFAULT_GRAPH_FONT_MARKER_TEXT)
345
- lines_with_closest_points = lines.each_with_index.map do |line, index|
346
- next if closest_points[index].nil?
347
-
348
- line
349
- end
350
- closest_point_texts = lines_with_closest_points.map { |line| "#{line[:name]}: #{line[:y_values][@closest_point_index]}" }
351
- closest_point_text_widths = closest_point_texts.map do |text|
352
- estimate_width_of_text(text, graph_font_marker_text)
353
- end
354
- square_size = 12.0
355
- square_to_label_padding = 10.0
356
- label_padding = 10.0
357
- text_label_x = width - graph_padding_width - text_label_width - label_padding -
358
- (lines_with_closest_points.size*(square_size + square_to_label_padding) + (lines_with_closest_points.size - 1)*label_padding + closest_point_text_widths.sum)
359
- text_label_y = height + graph_padding_height
380
+ end
381
+ text_label = formatted_x_value(@closest_point_index)
382
+ text_label_width = estimate_width_of_text(text_label, DEFAULT_GRAPH_FONT_MARKER_TEXT)
383
+ lines_with_closest_points = lines.each_with_index.map do |line, index|
384
+ next if closest_points[index].nil?
385
+
386
+ line
387
+ end.compact
388
+ closest_point_texts = lines_with_closest_points.map { |line| "#{line[:name]}: #{line[:y_values][@closest_point_index]}" }
389
+ closest_point_text_widths = closest_point_texts.map do |text|
390
+ estimate_width_of_text(text, graph_font_marker_text)
391
+ end
392
+ square_size = 12.0
393
+ square_to_label_padding = 10.0
394
+ label_padding = 10.0
395
+ text_label_x = width - graph_padding_width - text_label_width - label_padding -
396
+ (lines_with_closest_points.size*(square_size + square_to_label_padding) + (lines_with_closest_points.size - 1)*label_padding + closest_point_text_widths.sum)
397
+ text_label_y = height + graph_padding_height
360
398
 
361
- text(text_label_x, text_label_y, text_label_width) {
362
- string(text_label) {
363
- font DEFAULT_GRAPH_FONT_MARKER_TEXT
364
- color graph_color_marker_text
365
- }
399
+ text(text_label_x, text_label_y, text_label_width) {
400
+ string(text_label) {
401
+ font DEFAULT_GRAPH_FONT_MARKER_TEXT
402
+ color graph_color_marker_text
366
403
  }
404
+ }
367
405
 
368
- relative_x = text_label_x + text_label_width
369
- lines_with_closest_points.size.times do |index|
370
- square_x = relative_x + label_padding
406
+ relative_x = text_label_x + text_label_width
407
+ lines_with_closest_points.size.times do |index|
408
+ square_x = relative_x + label_padding
371
409
 
372
- square(square_x, text_label_y + 2, square_size) {
373
- fill lines_with_closest_points[index][:stroke]
374
- }
410
+ square(square_x, text_label_y + 2, square_size) {
411
+ fill lines_with_closest_points[index][:stroke]
412
+ }
375
413
 
376
- attribute_label_x = square_x + square_size + square_to_label_padding
377
- attribute_text = closest_point_texts[index]
378
- attribute_text_width = closest_point_text_widths[index]
379
- relative_x = attribute_label_x + attribute_text_width
414
+ attribute_label_x = square_x + square_size + square_to_label_padding
415
+ attribute_text = closest_point_texts[index]
416
+ attribute_text_width = closest_point_text_widths[index]
417
+ relative_x = attribute_label_x + attribute_text_width
380
418
 
381
- text(attribute_label_x, text_label_y, attribute_text_width) {
382
- string(attribute_text) {
383
- font graph_font_marker_text
384
- color graph_color_marker_text
385
- }
419
+ text(attribute_label_x, text_label_y, attribute_text_width) {
420
+ string(attribute_text) {
421
+ font graph_font_marker_text
422
+ color graph_color_marker_text
386
423
  }
387
- end
424
+ }
388
425
  end
389
426
  end
390
427
  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.3
4
+ version: 0.1.5
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-19 00:00:00.000000000 Z
11
+ date: 2023-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer-dsl-libui