wads 0.1.1 → 0.1.2

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: dffb479b6d7bdc47ff103db3f88b1acece5d0ec672361070aec604eb25aa6e9b
4
- data.tar.gz: b9fd53c1345bc7f5ab18cd0b5ab2eb74cc0b3276cd538cdae6dad414523f9529
3
+ metadata.gz: 2652d96c92be67ffd117365e2eb1ed93c21fd6f6c83cae037c6761f3f70754d5
4
+ data.tar.gz: e1680952ab2bdd333bc518ae7d97bca0a8bfc4033e2b0b9f8bf062e689ee22e9
5
5
  SHA512:
6
- metadata.gz: dbeb4a1dd4f5918d047954b6336219e3dd9429db3de755f56f12f34cf60c4e187d92a967a3cbde88ad02dc35952257da492729f1da762f8b49035775462b4b1b
7
- data.tar.gz: 6c28345cfc8658cd25c1243469ff0fa308aa8278597b48e42f9cdd71b1a4d7e285e3df989d19504ea2f3137a36e593ee6a46116a360d4ed92d627c2b9b334619
6
+ metadata.gz: 2e07cd62b59ca7d4e73176a94f3396f37f2981b6d448ebdd9490f9b6d5c0a69e0cd531805fed3e5512435b2d9a669521b1a047e0d022dd9ee0fb1ffb9ddd1941
7
+ data.tar.gz: 9189a546fe8c0f74fa0e18abbca8de17eacd70b63b7092e09374b4315f832ed359f62add905a3ce9c82641728b569846fc44f04007b2e14bcdb28e0608f35e3d
data/CHANGELOG.md CHANGED
@@ -6,3 +6,7 @@
6
6
 
7
7
  - Added graph data structure and corresponding display widgets
8
8
 
9
+ ## [0.1.2] - 2021-08-30
10
+
11
+ - Fixed bugs with data structures. Added convenience methods to manage child widgets
12
+
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  A number of Ruby Gosu-based (W)idgets (a)nd (D)ata (S)tructures for your applications.
4
4
 
5
+ ![alt Screenshot](https://github.com/dbroemme/ruby-wads/blob/main/media/WadsScreenshot.png?raw=true)
5
6
  ## Installation
6
7
 
7
8
  Add this line to your application’s Gemfile:
@@ -9,7 +10,7 @@ Add this line to your application’s Gemfile:
9
10
  ```
10
11
  gem 'wads'
11
12
  ```
12
- And the run bundle install.
13
+ And then run bundle install.
13
14
 
14
15
  ## Sample Application
15
16
 
@@ -20,7 +21,7 @@ git clone https://github.com/dbroemme/ruby-wads.git
20
21
  cd ruby-wads
21
22
  ./bin/setup
22
23
  ./run
23
- ./run-sample-app -s -g
24
+ ./run-sample-app -s
24
25
  ```
25
26
 
26
27
  This will run the sample NASDAQ stocks analysis that features the use of the
@@ -30,7 +31,12 @@ You can also see the graph capabilities by running the Star Wars analysis exampl
30
31
  This uses a data set that captures all character interactions within Episode 4.
31
32
 
32
33
  ```
33
- ./run-sample-app -j -g
34
+ ./run-sample-app -j
35
+ ```
36
+
37
+ There is also a sample Graph display using the following command.
38
+ ```
39
+ ./run-sample-app -g
34
40
  ```
35
41
 
36
42
  ## References
data/lib/wads/app.rb CHANGED
@@ -33,25 +33,33 @@ class WadsSampleApp < Gosu::Window
33
33
  opts = SampleAppCommand.new.parse.run
34
34
  if opts[:stocks]
35
35
  stats = process_stock_data
36
- if opts[:gui]
36
+ if opts[:text]
37
+ stats.report(Date::DAYNAMES[1..5])
38
+ else
37
39
  @display_widget = SampleStocksDisplay.new(@small_font, stats)
38
40
  show
39
- else
40
- stats.report(Date::DAYNAMES[1..5])
41
41
  end
42
42
 
43
43
  elsif opts[:jedi]
44
44
  graph = process_star_wars_data
45
45
  @display_widget = SampleStarWarsDisplay.new(@small_font, graph)
46
46
  show
47
+
47
48
  elsif opts[:lottery]
48
49
  process_lottery_data
50
+
51
+ elsif opts[:graph]
52
+ graph = create_test_graph
53
+ if not opts[:text]
54
+ @display_widget = SampleGraphDisplay.new(@small_font, graph)
55
+ show
56
+ end
49
57
  else
50
58
  puts " "
51
59
  puts "Select one of the following sample analysis options"
52
60
  puts "-s Run sample stocks analysis"
53
61
  puts "-j Run sample Star Wars character analysis"
54
- puts "-l Run sample analysis of lottery numbers"
62
+ puts "-g Run sample graph display"
55
63
  puts " "
56
64
  exit
57
65
  end
@@ -78,8 +86,10 @@ class WadsSampleApp < Gosu::Window
78
86
  close if id == Gosu::KbEscape
79
87
  # Delegate button events to the primary display widget
80
88
  result = @display_widget.button_down id, mouse_x, mouse_y
81
- if result.close_widget
82
- close
89
+ if not result.nil? and result.is_a? WidgetResult
90
+ if result.close_widget
91
+ close
92
+ end
83
93
  end
84
94
  end
85
95
 
@@ -174,10 +184,26 @@ class WadsSampleApp < Gosu::Window
174
184
  number_of_scenes_together = interaction['value']
175
185
  edge_tags = {}
176
186
  edge_tags["scenes"] = number_of_scenes_together
177
- character_one.add_output_edge(character_two, edge_tags)
187
+ graph.add_edge(character_one, character_two, edge_tags)
178
188
  end
179
189
  graph
180
190
  end
191
+
192
+ def create_test_graph
193
+ g = Graph.new
194
+ g.add("a")
195
+ g.add("b")
196
+ g.add("c")
197
+ g.add("d")
198
+ g.add("e")
199
+ g.add("f")
200
+ g.connect("a", "b")
201
+ g.connect("a", "c")
202
+ g.connect("b", "d")
203
+ g.connect("b", "e")
204
+ g.connect("e", "f")
205
+ g
206
+ end
181
207
  end
182
208
 
183
209
  class SampleStocksDisplay < Widget
@@ -187,15 +213,16 @@ class SampleStocksDisplay < Widget
187
213
  super(10, 100, COLOR_HEADER_BRIGHT_BLUE)
188
214
  set_dimensions(780, 500)
189
215
  set_font(font)
190
- add_child(Document.new(sample_content, x + 5, y + 5, @width, @height, @font))
191
- @exit_button = Button.new("Exit", 380, bottom_edge - 30, @font)
192
- add_child(@exit_button)
216
+ add_document(sample_content, 5, 5, @width, @height)
217
+ add_button("Exit", 380, @height - 30) do
218
+ WidgetResult.new(true)
219
+ end
193
220
 
194
221
  @stats = stats
195
- @data_table = SingleSelectTable.new(@x + 5, @y + 100, # top left corner
196
- 770, 200, # width, height
222
+ @data_table = add_single_select_table(5, 100, # top left corner
223
+ 770, 200, # width, height
197
224
  ["Day", "Min", "Avg", "StdDev", "Max", "p10", "p90"], # column headers
198
- @font, COLOR_WHITE) # font and text color
225
+ COLOR_WHITE) # font and text color
199
226
  @data_table.selected_color = COLOR_LIGHT_GRAY
200
227
  Date::DAYNAMES[1..5].each do |day|
201
228
  min = format_percent(@stats.min(day))
@@ -206,7 +233,7 @@ class SampleStocksDisplay < Widget
206
233
  p90 = format_percent(@stats.percentile(day, 0.90))
207
234
  @data_table.add_row([day, min, avg, std, max, p10, p90], COLOR_HEADER_BRIGHT_BLUE)
208
235
  end
209
- add_child(@data_table)
236
+
210
237
  @selection_text = nil
211
238
  end
212
239
 
@@ -228,21 +255,15 @@ class SampleStocksDisplay < Widget
228
255
  end
229
256
  end
230
257
 
231
- def button_down id, mouse_x, mouse_y
232
- if id == Gosu::MsLeft
233
- if @exit_button.contains_click(mouse_x, mouse_y)
234
- return WidgetResult.new(true)
235
- elsif @data_table.contains_click(mouse_x, mouse_y)
236
- val = @data_table.set_selected_row(mouse_y, 0)
237
- if val.nil?
238
- # nothing to do
239
- else
240
- @selection_text = Text.new("You selected #{val}, a great day!",
241
- x + 5, y + 400, @font)
242
- end
243
- end
244
- end
245
- WidgetResult.new(false)
258
+ def handle_mouse_down mouse_x, mouse_y
259
+ if @data_table.contains_click(mouse_x, mouse_y)
260
+ val = @data_table.set_selected_row(mouse_y, 0)
261
+ if not val.nil?
262
+ @selection_text = Text.new("You selected #{val}, a great day!",
263
+ x + 5, y + 400, @font)
264
+ end
265
+ end
266
+ nil
246
267
  end
247
268
  end
248
269
 
@@ -253,22 +274,24 @@ class SampleStarWarsDisplay < Widget
253
274
  super(10, 100, COLOR_HEADER_BRIGHT_BLUE)
254
275
  set_dimensions(780, 500)
255
276
  set_font(font)
256
- add_child(Document.new(sample_content, x + 5, y + 5, @width, @height, @font))
257
- @exit_button = Button.new("Exit", 380, bottom_edge - 30, @font)
258
- add_child(@exit_button)
259
-
260
277
  @graph = graph
261
- @data_table = SingleSelectTable.new(@x + 5, @y + 70, # top left corner
262
- 770, 180, # width, height
263
- ["Character", "Number of Scenes"], # column headers
264
- @font, COLOR_WHITE, # font and text color
265
- 5) # max visible rows
278
+
279
+ add_document(sample_content, 5, 5, @width, @height)
280
+ add_button("Exit", 370, @height - 30) do
281
+ WidgetResult.new(true)
282
+ end
283
+
284
+ @data_table = add_single_select_table(5, 70, # top left corner
285
+ 770, 180, # width, height
286
+ ["Character", "Number of Scenes"], # column headers
287
+ COLOR_WHITE, # font and text color
288
+ 5) # max visible rows
266
289
  @data_table.selected_color = COLOR_LIGHT_GRAY
290
+
267
291
  @graph.node_list.each do |character|
268
292
  @data_table.add_row([character.name, character.value], character.get_tag("color"))
269
293
  end
270
- add_child(@data_table)
271
- @graph_display = GraphWidget.new(x + 5, y + 260, 770, 200, @font, @color, @graph)
294
+ @graph_display = add_graph_display(5, 260, 770, 200, @graph)
272
295
  end
273
296
 
274
297
  def sample_content
@@ -278,38 +301,40 @@ class SampleStarWarsDisplay < Widget
278
301
  HEREDOC
279
302
  end
280
303
 
281
- def render
282
- @graph_display.draw
283
- end
284
-
285
- def button_down id, mouse_x, mouse_y
286
- if id == Gosu::MsLeft
287
- if @exit_button.contains_click(mouse_x, mouse_y)
288
- return WidgetResult.new(true)
289
- elsif @data_table.contains_click(mouse_x, mouse_y)
290
- val = @data_table.set_selected_row(mouse_y, 0)
291
- if val.nil?
292
- # nothing to do
293
- else
294
- node = @graph.find_node(val)
295
- @graph_display.set_display(node, 2)
296
- end
297
- elsif @graph_display.contains_click(mouse_x, mouse_y)
298
- @graph_display.button_down id, mouse_x, mouse_y
299
- end
300
- elsif id == Gosu::KbUp
304
+ def handle_key_press id, mouse_x, mouse_y
305
+ if id == Gosu::KbUp
301
306
  @data_table.scroll_up
302
307
  elsif id == Gosu::KbDown
303
308
  @data_table.scroll_down
304
309
  end
305
310
  WidgetResult.new(false)
306
- end
307
-
308
- def button_up id, mouse_x, mouse_y
309
- @graph_display.button_up id, mouse_x, mouse_y
310
311
  end
311
312
 
312
- def update update_count, mouse_x, mouse_y
313
- @graph_display.update update_count, mouse_x, mouse_y
313
+ def handle_mouse_down mouse_x, mouse_y
314
+ if @data_table.contains_click(mouse_x, mouse_y)
315
+ val = @data_table.set_selected_row(mouse_y, 0)
316
+ if not val.nil?
317
+ node = @graph.find_node(val)
318
+ @graph_display.set_center_node(node, 2)
319
+ end
320
+ end
321
+ nil
314
322
  end
323
+ end
324
+
325
+ class SampleGraphDisplay < Widget
326
+ attr_accessor :graph
327
+
328
+ def initialize(font, graph)
329
+ super(10, 100, COLOR_CYAN)
330
+ set_dimensions(780, 500)
331
+ set_font(font)
332
+ @graph = graph
333
+ exit_button = add_button("Exit", 370, @height - 30) do
334
+ WidgetResult.new(true)
335
+ end
336
+ exit_button.text_color = COLOR_CYAN
337
+ @graph_display = add_graph_display(5, 60, 770, 400, @graph)
338
+ @graph_display.set_tree_display
339
+ end
315
340
  end
@@ -32,21 +32,29 @@ module Wads
32
32
  end
33
33
 
34
34
  def set(data_set_name, x, y)
35
- data_set = @data[x]
35
+ data_set = @data[data_set_name]
36
36
  if data_set.nil?
37
37
  data_set = {}
38
- @data[x] = data_set
38
+ @data[data_set_name] = data_set
39
39
  end
40
40
  data_set[x] = y
41
41
  end
42
42
 
43
43
  def get(data_set_name, x)
44
- data_set = @data[x]
44
+ data_set = @data[data_set_name]
45
45
  if data_set.nil?
46
46
  return nil
47
47
  end
48
48
  data_set[x]
49
49
  end
50
+
51
+ def keys(data_set_name)
52
+ data_set = @data[data_set_name]
53
+ if data_set.nil?
54
+ return nil
55
+ end
56
+ data_set.keys
57
+ end
50
58
  end
51
59
 
52
60
  class Stats
@@ -250,6 +258,11 @@ module Wads
250
258
  attr_accessor :visited
251
259
  attr_accessor :tags
252
260
 
261
+ def id
262
+ # id is an alias for name
263
+ @name
264
+ end
265
+
253
266
  def initialize(name, value = nil, tags = {})
254
267
  @name = name
255
268
  @value = value
@@ -281,6 +294,35 @@ module Wads
281
294
  edge
282
295
  end
283
296
 
297
+ def remove_output(name)
298
+ output_to_delete = nil
299
+ @outputs.each do |output|
300
+ if output.is_a? Edge
301
+ output_node = output.destination
302
+ if output_node.id == name
303
+ output_to_delete = output
304
+ end
305
+ elsif output.id == name
306
+ output_to_delete = output
307
+ end
308
+ end
309
+ if output_to_delete
310
+ @outputs.delete(output_to_delete)
311
+ end
312
+ end
313
+
314
+ def remove_backlink(name)
315
+ backlink_to_delete = nil
316
+ @backlinks.each do |backlink|
317
+ if backlink.id == name
318
+ backlink_to_delete = backlink
319
+ end
320
+ end
321
+ if backlink_to_delete
322
+ @backlinks.delete(backlink_to_delete)
323
+ end
324
+ end
325
+
284
326
  def add_tag(key, value)
285
327
  @tags[key] = value
286
328
  end
@@ -313,8 +355,8 @@ module Wads
313
355
  node = node_queue.shift
314
356
  yield node
315
357
  node.outputs.each do |c|
316
- if child.is_a? Edge
317
- child = child.destination
358
+ if c.is_a? Edge
359
+ c = c.destination
318
360
  end
319
361
  node_queue << c
320
362
  end
@@ -363,18 +405,49 @@ module Wads
363
405
  @node_map = {}
364
406
  end
365
407
 
408
+ def add(name, value = nil, tags = {})
409
+ add_node(Node.new(name, value, tags))
410
+ end
411
+
412
+ def connect(source, destination, tags = {})
413
+ add_edge(source, destination)
414
+ end
415
+
416
+ def delete(node)
417
+ if node.is_a? String
418
+ node = find_node(node)
419
+ end
420
+ node.backlinks.each do |backlink|
421
+ backlink.remove_output(node.name)
422
+ end
423
+ @node_list.delete(node)
424
+ @node_map.delete(node.name)
425
+ end
426
+
427
+ def disconnect(source, target)
428
+ if source.is_a? String
429
+ source = find_node(source)
430
+ end
431
+ if target.is_a? String
432
+ target = find_node(target)
433
+ end
434
+ source.remove_output(target.name)
435
+ target.remove_backlink(source.name)
436
+ end
437
+
366
438
  def add_node(node)
367
439
  @node_list << node
368
440
  @node_map[node.name] = node
369
441
  end
370
442
 
371
- def add_edge(source, target, tags)
443
+ def add_edge(source, target, tags = {})
372
444
  if source.is_a? String
373
445
  source = find_node(source)
374
446
  end
375
447
  if target.is_a? String
376
448
  target = find_node(target)
377
449
  end
450
+ source.add_output_edge(target, tags)
378
451
  end
379
452
 
380
453
  def find_node(name)
@@ -401,6 +474,16 @@ module Wads
401
474
  list
402
475
  end
403
476
 
477
+ def leaf_nodes
478
+ list = []
479
+ @node_list.each do |node|
480
+ if node.outputs.empty?
481
+ list << node
482
+ end
483
+ end
484
+ list
485
+ end
486
+
404
487
  def is_cycle(node)
405
488
  reset_visited
406
489
  node.visit do |n|
@@ -413,14 +496,21 @@ module Wads
413
496
  false
414
497
  end
415
498
 
416
- def fan_out(node, max_depth, current_depth = 1)
417
- if current_depth > max_depth
418
- return {}
499
+ def traverse_and_collect_nodes(node, max_depth, current_depth = 1)
500
+ if max_depth > 0
501
+ if current_depth > max_depth
502
+ return {}
503
+ end
419
504
  end
420
505
  map = {}
421
- map[node.name] = node
506
+ if node.visited
507
+ return {}
508
+ else
509
+ map[node.name] = node
510
+ node.visited = true
511
+ end
422
512
  node.backlinks.each do |child|
423
- map_from_child = fan_out(child, max_depth, current_depth + 1)
513
+ map_from_child = traverse_and_collect_nodes(child, max_depth, current_depth + 1)
424
514
  map_from_child.each do |key, value|
425
515
  map[key] = value
426
516
  end
@@ -429,7 +519,7 @@ module Wads
429
519
  if child.is_a? Edge
430
520
  child = child.destination
431
521
  end
432
- map_from_child = fan_out(child, max_depth, current_depth + 1)
522
+ map_from_child = traverse_and_collect_nodes(child, max_depth, current_depth + 1)
433
523
  map_from_child.each do |key, value|
434
524
  map[key] = value
435
525
  end
@@ -437,4 +527,183 @@ module Wads
437
527
  map
438
528
  end
439
529
  end
530
+
531
+ class GraphReverseIterator
532
+ attr_accessor :output
533
+ def initialize(graph)
534
+ @output = []
535
+ graph.root_nodes.each do |root|
536
+ partial_list = process_node(root)
537
+ @output.push(*partial_list)
538
+ end
539
+ end
540
+
541
+ def process_node(node)
542
+ list = []
543
+ node.outputs.each do |child_node|
544
+ if child_node.is_a? Edge
545
+ child_node = child_node.destination
546
+ end
547
+ child_list = process_node(child_node)
548
+ list.push(*child_list)
549
+ end
550
+
551
+ list << node
552
+ list
553
+ end
554
+ end
555
+
556
+ class VisibleRange
557
+ attr_accessor :left_x
558
+ attr_accessor :right_x
559
+ attr_accessor :bottom_y
560
+ attr_accessor :top_y
561
+ attr_accessor :x_range
562
+ attr_accessor :y_range
563
+ attr_accessor :is_time_based
564
+
565
+ def initialize(l, r, b, t, is_time_based = false)
566
+ if l < r
567
+ @left_x = l
568
+ @right_x = r
569
+ else
570
+ @left_x = r
571
+ @right_x = l
572
+ end
573
+ if b < t
574
+ @bottom_y = b
575
+ @top_y = t
576
+ else
577
+ @bottom_y = t
578
+ @top_y = b
579
+ end
580
+ @x_range = @right_x - @left_x
581
+ @y_range = @top_y - @bottom_y
582
+ @is_time_based = is_time_based
583
+
584
+ @orig_left_x = @left_x
585
+ @orig_right_x = @right_x
586
+ @orig_bottom_y = @bottom_y
587
+ @orig_top_y = @top_y
588
+ @orig_range_x = @x_range
589
+ @orig_range_y = @y_range
590
+ end
591
+
592
+ def plus(other_range)
593
+ l = @left_x < other_range.left_x ? @left_x : other_range.left_x
594
+ r = @right_x > other_range.right_x ? @right_x : other_range.right_x
595
+ b = @bottom_y < other_range.bottom_y ? @bottom_y : other_range.bottom_y
596
+ t = @top_y > other_range.top_y ? @top_y : other_range.top_y
597
+ VisibleRange.new(l, r, b, t, (@is_time_based or other_range.is_time_based))
598
+ end
599
+
600
+ def x_ten_percent
601
+ @x_range.to_f / 10
602
+ end
603
+
604
+ def y_ten_percent
605
+ @y_range.to_f / 10
606
+ end
607
+
608
+ def scale(zoom_level)
609
+ x_mid_point = @orig_left_x + (@orig_range_x.to_f / 2)
610
+ x_extension = (@orig_range_x.to_f * zoom_level) / 2
611
+ @left_x = x_mid_point - x_extension
612
+ @right_x = x_mid_point + x_extension
613
+
614
+ y_mid_point = @orig_bottom_y + (@orig_range_y.to_f / 2)
615
+ y_extension = (@orig_range_y.to_f * zoom_level) / 2
616
+ @bottom_y = y_mid_point - y_extension
617
+ @top_y = y_mid_point + y_extension
618
+
619
+ @x_range = @right_x - @left_x
620
+ @y_range = @top_y - @bottom_y
621
+ end
622
+
623
+ def scroll_up
624
+ @bottom_y = @bottom_y + y_ten_percent
625
+ @top_y = @top_y + y_ten_percent
626
+ @y_range = @top_y - @bottom_y
627
+ end
628
+
629
+ def scroll_down
630
+ @bottom_y = @bottom_y - y_ten_percent
631
+ @top_y = @top_y - y_ten_percent
632
+ @y_range = @top_y - @bottom_y
633
+ end
634
+
635
+ def scroll_right
636
+ @left_x = @left_x + x_ten_percent
637
+ @right_x = @right_x + x_ten_percent
638
+ @x_range = @right_x - @left_x
639
+ end
640
+
641
+ def scroll_left
642
+ @left_x = @left_x - x_ten_percent
643
+ @right_x = @right_x - x_ten_percent
644
+ @x_range = @right_x - @left_x
645
+ end
646
+
647
+ def grid_line_x_values
648
+ if @cached_grid_line_x_values
649
+ return @cached_grid_line_x_values
650
+ end
651
+ @cached_grid_line_x_values = divide_range_into_values(@x_range, @left_x, @right_x, false)
652
+ @cached_grid_line_x_values
653
+ end
654
+
655
+ def grid_line_y_values
656
+ if @cached_grid_line_y_values
657
+ return @cached_grid_line_y_values
658
+ end
659
+ @cached_grid_line_y_values = divide_range_into_values(@y_range, @bottom_y, @top_y, false)
660
+ @cached_grid_line_y_values
661
+ end
662
+
663
+ def calc_x_values
664
+ if @cached_calc_x_values
665
+ return @cached_calc_x_values
666
+ end
667
+ @cached_calc_x_values = divide_range_into_values(@x_range, @left_x, @right_x)
668
+ #puts "The x_axis value to calculate are: #{@cached_calc_x_values}"
669
+ @cached_calc_x_values
670
+ end
671
+
672
+ def clear_cache
673
+ @cached_grid_line_x_values = nil
674
+ @cached_grid_line_y_values = nil
675
+ @cached_calc_x_values = nil
676
+ end
677
+
678
+ # This method determines what are equidistant points along
679
+ # the x-axis that we can use to draw gridlines and calculate
680
+ # derived values from functions
681
+ def divide_range_into_values(range_size, start_value, end_value, is_derived_values = true)
682
+ values = []
683
+ # How big is x-range? What should the step size be?
684
+ # Generally we want a hundred display points. Let's start there.
685
+ if range_size < 1.1
686
+ step_size = is_derived_values ? 0.01 : 0.1
687
+ elsif range_size < 11
688
+ step_size = is_derived_values ? 0.1 : 1
689
+ elsif range_size < 111
690
+ step_size = is_derived_values ? 1 : 10
691
+ elsif range_size < 1111
692
+ step_size = is_derived_values ? 10 : 100
693
+ elsif range_size < 11111
694
+ step_size = is_derived_values ? 100 : 1000
695
+ elsif range_size < 111111
696
+ step_size = is_derived_values ? 1000 : 10000
697
+ else
698
+ step_size = is_derived_values ? 10000 : 100000
699
+ end
700
+ grid_x = start_value
701
+ while grid_x < end_value
702
+ values << grid_x
703
+ grid_x = grid_x + step_size
704
+ end
705
+ values
706
+ end
707
+ end
708
+
440
709
  end