wads 0.1.0 → 0.2.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 +16 -2
- data/README.md +62 -2
- data/data/sample_graph.csv +11 -0
- data/data/starwars-episode-4-interactions.json +336 -0
- data/lib/wads/app.rb +41 -183
- data/lib/wads/data_structures.rb +705 -17
- data/lib/wads/textinput.rb +66 -15
- data/lib/wads/version.rb +1 -1
- data/lib/wads/widgets.rb +2827 -271
- data/lib/wads.rb +1 -1
- data/media/CircleAlpha.png +0 -0
- data/media/CircleAqua.png +0 -0
- data/media/CircleBlue.png +0 -0
- data/media/CircleGray.png +0 -0
- data/media/CircleGreen.png +0 -0
- data/media/CirclePurple.png +0 -0
- data/media/CircleRed.png +0 -0
- data/media/CircleWhite.png +0 -0
- data/media/CircleYellow.png +0 -0
- data/media/SampleGraph.png +0 -0
- data/media/StocksSample.png +0 -0
- data/media/WadsScreenshot.png +0 -0
- data/run-graph +3 -0
- data/run-star-wars +3 -0
- data/run-stocks +3 -0
- data/run-theme-test +3 -0
- data/samples/basic_gosu_with_graph_widget.rb +66 -0
- data/samples/graph.rb +72 -0
- data/samples/star_wars.rb +112 -0
- data/samples/stocks.rb +126 -0
- data/samples/theme_test.rb +256 -0
- metadata +26 -5
- data/run-sample-app +0 -3
- data/sample_app.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1cf7ab7c4229f57f2bb4691819c5a4282a3fd0f7703e5caa6c93e49aeb35053
|
4
|
+
data.tar.gz: a1f0e971db1ea5064e44fef39c31767125f844b8ab3ef87eeaf09e3e92f27ad1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 315790b3c8fe99525c3ad78eaa90eecd17fadd09a2a3e16a13ba82cb61ea5279472c57ada6e88021e9c6649236bb598aad0a46a1954928a1c37dc8dbf8b45b5e
|
7
|
+
data.tar.gz: 89de4f997dcef2e1b9e25062af443d6994d7ee4070d89dab21f06cb492ed3d106f837a9c3bdf85d7ba7e6522d30a039694982d939d49dd41b7da30c2637299ea
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
|
-
## [Unreleased]
|
2
|
-
|
3
1
|
## [0.1.0] - 2021-08-23
|
4
2
|
|
5
3
|
- Initial release
|
4
|
+
|
5
|
+
## [0.1.1] - 2021-08-29
|
6
|
+
|
7
|
+
- Added graph data structure and corresponding display widgets
|
8
|
+
|
9
|
+
## [0.1.2] - 2021-08-30
|
10
|
+
|
11
|
+
- Fixed bugs with data structures. Added convenience methods to manage child widgets
|
12
|
+
|
13
|
+
## [0.1.3] - 2021-09-30
|
14
|
+
|
15
|
+
- Improvements to graph display including user ability to change focus node
|
16
|
+
|
17
|
+
## [0.2.0] - 2021-10-05
|
18
|
+
|
19
|
+
- Breaking change in order to refactor, including standardizing order of widget constructor args
|
data/README.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
A number of Ruby Gosu-based (W)idgets (a)nd (D)ata (S)tructures for your applications.
|
4
4
|
|
5
|
+
The user guide and examples can be found at https://www.rubydoesitagain.com
|
6
|
+
|
7
|
+
Wads (Widgets and Data Structures) is intended to help you quickly build native Ruby applications using the Gosu gem.
|
8
|
+
GUI widgets, such as tables and buttons, are provided to simplify building graphical applications.
|
9
|
+
Widgets in wads can be used independently within your Gosu app, or you can use wads as a holistic GUI framework.
|
10
|
+
Wads includes basic features found in many GUI toolkits including The use of themes and a layout manager.
|
11
|
+
|
12
|
+
One of the motivations for creating wads is to making data analysis, games, and productivity applications using Ruby easier to do.
|
13
|
+
Data structures are included that can be used for statistical analysis or graph-based applications.
|
14
|
+
The samples provided illustrate both use cases (Stocks - stats) and Star Wars character interactions (graphs).
|
15
|
+
|
16
|
+

|
5
17
|
## Installation
|
6
18
|
|
7
19
|
Add this line to your application’s Gemfile:
|
@@ -9,7 +21,7 @@ Add this line to your application’s Gemfile:
|
|
9
21
|
```
|
10
22
|
gem 'wads'
|
11
23
|
```
|
12
|
-
And
|
24
|
+
And then run bundle install.
|
13
25
|
|
14
26
|
## Sample Application
|
15
27
|
|
@@ -20,8 +32,56 @@ git clone https://github.com/dbroemme/ruby-wads.git
|
|
20
32
|
cd ruby-wads
|
21
33
|
./bin/setup
|
22
34
|
./run
|
23
|
-
./run-sample-app -s
|
35
|
+
./run-sample-app -s
|
24
36
|
```
|
25
37
|
|
26
38
|
This will run the sample NASDAQ stocks analysis that features the use of the
|
27
39
|
Stats class, and a table Gosu widget used to display the results of the analysis.
|
40
|
+
|
41
|
+

|
42
|
+
|
43
|
+
|
44
|
+
You can also see the graph capabilities by running the Star Wars analysis example.
|
45
|
+
This uses a data set that captures all character interactions within Episode 4.
|
46
|
+
|
47
|
+
```
|
48
|
+
./run-sample-app -j
|
49
|
+
```
|
50
|
+
|
51
|
+
There is also a sample Graph display using the following command.
|
52
|
+
```
|
53
|
+
./run-sample-app -g
|
54
|
+
```
|
55
|
+
Note that you can construct graphs in one of two ways. The first approach uses Nodes directly.
|
56
|
+
```
|
57
|
+
root = Node.new("a")
|
58
|
+
b = root.add("b")
|
59
|
+
b.add("d")
|
60
|
+
b.add("e").add("f")
|
61
|
+
root.add("c")
|
62
|
+
Graph.new(root)
|
63
|
+
```
|
64
|
+
The second approach uses an overarching Graph object.
|
65
|
+
```
|
66
|
+
g = Graph.new
|
67
|
+
g.add("a")
|
68
|
+
g.add("b")
|
69
|
+
g.add("c")
|
70
|
+
g.add("d")
|
71
|
+
g.add("e")
|
72
|
+
g.add("f")
|
73
|
+
g.connect("a", "b")
|
74
|
+
g.connect("a", "c")
|
75
|
+
g.connect("b", "d")
|
76
|
+
g.connect("b", "e")
|
77
|
+
g.connect("e", "f")
|
78
|
+
```
|
79
|
+
|
80
|
+
Currently, the Graph object is used by the Graph Widget for display. For the code above, this appears by default as follows:
|
81
|
+
|
82
|
+

|
83
|
+
|
84
|
+
## References
|
85
|
+
|
86
|
+
The Star Wars data set is courtesy of:
|
87
|
+
Gabasova, E. (2016). Star Wars social network. DOI: https://doi.org/10.5281/zenodo.1411479.
|
@@ -0,0 +1,336 @@
|
|
1
|
+
{
|
2
|
+
"nodes": [
|
3
|
+
{
|
4
|
+
"name": "C-3PO",
|
5
|
+
"value": 42,
|
6
|
+
"colour": "#FFD700"
|
7
|
+
},
|
8
|
+
{
|
9
|
+
"name": "LUKE",
|
10
|
+
"value": 88,
|
11
|
+
"colour": "#3881e5"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"name": "DARTH VADER",
|
15
|
+
"value": 25,
|
16
|
+
"colour": "#000000"
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"name": "CAMIE",
|
20
|
+
"value": 3,
|
21
|
+
"colour": "#808080"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"name": "BIGGS",
|
25
|
+
"value": 18,
|
26
|
+
"colour": "#808080"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"name": "LEIA",
|
30
|
+
"value": 25,
|
31
|
+
"colour": "#DCDCDC"
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"name": "BERU",
|
35
|
+
"value": 5,
|
36
|
+
"colour": "#808080"
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"name": "OWEN",
|
40
|
+
"value": 6,
|
41
|
+
"colour": "#808080"
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"name": "OBI-WAN",
|
45
|
+
"value": 22,
|
46
|
+
"colour": "#48D1CC"
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"name": "MOTTI",
|
50
|
+
"value": 3,
|
51
|
+
"colour": "#808080"
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"name": "TARKIN",
|
55
|
+
"value": 12,
|
56
|
+
"colour": "#808080"
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"name": "HAN",
|
60
|
+
"value": 44,
|
61
|
+
"colour": "#ff9400"
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"name": "GREEDO",
|
65
|
+
"value": 2,
|
66
|
+
"colour": "#808080"
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"name": "JABBA",
|
70
|
+
"value": 2,
|
71
|
+
"colour": "#808080"
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"name": "DODONNA",
|
75
|
+
"value": 3,
|
76
|
+
"colour": "#808080"
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"name": "GOLD LEADER",
|
80
|
+
"value": 14,
|
81
|
+
"colour": "#808080"
|
82
|
+
},
|
83
|
+
{
|
84
|
+
"name": "WEDGE",
|
85
|
+
"value": 15,
|
86
|
+
"colour": "#808080"
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"name": "RED LEADER",
|
90
|
+
"value": 33,
|
91
|
+
"colour": "#808080"
|
92
|
+
},
|
93
|
+
{
|
94
|
+
"name": "RED TEN",
|
95
|
+
"value": 8,
|
96
|
+
"colour": "#808080"
|
97
|
+
},
|
98
|
+
{
|
99
|
+
"name": "GOLD FIVE",
|
100
|
+
"value": 8,
|
101
|
+
"colour": "#808080"
|
102
|
+
}
|
103
|
+
],
|
104
|
+
"links": [
|
105
|
+
{
|
106
|
+
"source": 3,
|
107
|
+
"target": 1,
|
108
|
+
"value": 2
|
109
|
+
},
|
110
|
+
{
|
111
|
+
"source": 4,
|
112
|
+
"target": 3,
|
113
|
+
"value": 2
|
114
|
+
},
|
115
|
+
{
|
116
|
+
"source": 4,
|
117
|
+
"target": 1,
|
118
|
+
"value": 4
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"source": 2,
|
122
|
+
"target": 5,
|
123
|
+
"value": 1
|
124
|
+
},
|
125
|
+
{
|
126
|
+
"source": 6,
|
127
|
+
"target": 1,
|
128
|
+
"value": 3
|
129
|
+
},
|
130
|
+
{
|
131
|
+
"source": 6,
|
132
|
+
"target": 7,
|
133
|
+
"value": 3
|
134
|
+
},
|
135
|
+
{
|
136
|
+
"source": 6,
|
137
|
+
"target": 0,
|
138
|
+
"value": 2
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"source": 1,
|
142
|
+
"target": 7,
|
143
|
+
"value": 3
|
144
|
+
},
|
145
|
+
{
|
146
|
+
"source": 0,
|
147
|
+
"target": 1,
|
148
|
+
"value": 18
|
149
|
+
},
|
150
|
+
{
|
151
|
+
"source": 0,
|
152
|
+
"target": 7,
|
153
|
+
"value": 2
|
154
|
+
},
|
155
|
+
{
|
156
|
+
"source": 0,
|
157
|
+
"target": 5,
|
158
|
+
"value": 6
|
159
|
+
},
|
160
|
+
{
|
161
|
+
"source": 5,
|
162
|
+
"target": 1,
|
163
|
+
"value": 17
|
164
|
+
},
|
165
|
+
{
|
166
|
+
"source": 6,
|
167
|
+
"target": 5,
|
168
|
+
"value": 1
|
169
|
+
},
|
170
|
+
{
|
171
|
+
"source": 1,
|
172
|
+
"target": 8,
|
173
|
+
"value": 19
|
174
|
+
},
|
175
|
+
{
|
176
|
+
"source": 0,
|
177
|
+
"target": 8,
|
178
|
+
"value": 6
|
179
|
+
},
|
180
|
+
{
|
181
|
+
"source": 5,
|
182
|
+
"target": 8,
|
183
|
+
"value": 1
|
184
|
+
},
|
185
|
+
{
|
186
|
+
"source": 9,
|
187
|
+
"target": 10,
|
188
|
+
"value": 2
|
189
|
+
},
|
190
|
+
{
|
191
|
+
"source": 2,
|
192
|
+
"target": 9,
|
193
|
+
"value": 1
|
194
|
+
},
|
195
|
+
{
|
196
|
+
"source": 2,
|
197
|
+
"target": 10,
|
198
|
+
"value": 7
|
199
|
+
},
|
200
|
+
{
|
201
|
+
"source": 11,
|
202
|
+
"target": 8,
|
203
|
+
"value": 9
|
204
|
+
},
|
205
|
+
{
|
206
|
+
"source": 11,
|
207
|
+
"target": 1,
|
208
|
+
"value": 26
|
209
|
+
},
|
210
|
+
{
|
211
|
+
"source": 12,
|
212
|
+
"target": 11,
|
213
|
+
"value": 1
|
214
|
+
},
|
215
|
+
{
|
216
|
+
"source": 11,
|
217
|
+
"target": 13,
|
218
|
+
"value": 1
|
219
|
+
},
|
220
|
+
{
|
221
|
+
"source": 0,
|
222
|
+
"target": 11,
|
223
|
+
"value": 6
|
224
|
+
},
|
225
|
+
{
|
226
|
+
"source": 5,
|
227
|
+
"target": 9,
|
228
|
+
"value": 1
|
229
|
+
},
|
230
|
+
{
|
231
|
+
"source": 5,
|
232
|
+
"target": 10,
|
233
|
+
"value": 1
|
234
|
+
},
|
235
|
+
{
|
236
|
+
"source": 11,
|
237
|
+
"target": 5,
|
238
|
+
"value": 13
|
239
|
+
},
|
240
|
+
{
|
241
|
+
"source": 2,
|
242
|
+
"target": 8,
|
243
|
+
"value": 1
|
244
|
+
},
|
245
|
+
{
|
246
|
+
"source": 14,
|
247
|
+
"target": 15,
|
248
|
+
"value": 1
|
249
|
+
},
|
250
|
+
{
|
251
|
+
"source": 14,
|
252
|
+
"target": 16,
|
253
|
+
"value": 1
|
254
|
+
},
|
255
|
+
{
|
256
|
+
"source": 14,
|
257
|
+
"target": 1,
|
258
|
+
"value": 1
|
259
|
+
},
|
260
|
+
{
|
261
|
+
"source": 15,
|
262
|
+
"target": 16,
|
263
|
+
"value": 1
|
264
|
+
},
|
265
|
+
{
|
266
|
+
"source": 15,
|
267
|
+
"target": 1,
|
268
|
+
"value": 1
|
269
|
+
},
|
270
|
+
{
|
271
|
+
"source": 1,
|
272
|
+
"target": 16,
|
273
|
+
"value": 2
|
274
|
+
},
|
275
|
+
{
|
276
|
+
"source": 4,
|
277
|
+
"target": 5,
|
278
|
+
"value": 1
|
279
|
+
},
|
280
|
+
{
|
281
|
+
"source": 5,
|
282
|
+
"target": 17,
|
283
|
+
"value": 1
|
284
|
+
},
|
285
|
+
{
|
286
|
+
"source": 1,
|
287
|
+
"target": 17,
|
288
|
+
"value": 3
|
289
|
+
},
|
290
|
+
{
|
291
|
+
"source": 4,
|
292
|
+
"target": 17,
|
293
|
+
"value": 3
|
294
|
+
},
|
295
|
+
{
|
296
|
+
"source": 4,
|
297
|
+
"target": 0,
|
298
|
+
"value": 1
|
299
|
+
},
|
300
|
+
{
|
301
|
+
"source": 0,
|
302
|
+
"target": 17,
|
303
|
+
"value": 1
|
304
|
+
},
|
305
|
+
{
|
306
|
+
"source": 17,
|
307
|
+
"target": 16,
|
308
|
+
"value": 3
|
309
|
+
},
|
310
|
+
{
|
311
|
+
"source": 15,
|
312
|
+
"target": 17,
|
313
|
+
"value": 1
|
314
|
+
},
|
315
|
+
{
|
316
|
+
"source": 4,
|
317
|
+
"target": 16,
|
318
|
+
"value": 2
|
319
|
+
},
|
320
|
+
{
|
321
|
+
"source": 17,
|
322
|
+
"target": 18,
|
323
|
+
"value": 1
|
324
|
+
},
|
325
|
+
{
|
326
|
+
"source": 4,
|
327
|
+
"target": 15,
|
328
|
+
"value": 1
|
329
|
+
},
|
330
|
+
{
|
331
|
+
"source": 1,
|
332
|
+
"target": 18,
|
333
|
+
"value": 1
|
334
|
+
}
|
335
|
+
]
|
336
|
+
}
|
data/lib/wads/app.rb
CHANGED
@@ -1,199 +1,57 @@
|
|
1
1
|
require 'gosu'
|
2
|
-
require_relative 'data_structures'
|
3
2
|
require_relative 'widgets'
|
4
|
-
require_relative 'version'
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
class
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
4
|
+
module Wads
|
5
|
+
#
|
6
|
+
# The WadsApp class provides a simple starting point to quickly build a native
|
7
|
+
# Ruby application using Gosu as an underlying library. It provides all the necessary
|
8
|
+
# hooks to get started. All you need to do is supply the parent Wads widget using
|
9
|
+
# the set_display(widget) method. See one of the Wads samples for example usage.
|
10
|
+
#
|
11
|
+
class WadsApp < Gosu::Window
|
12
|
+
def initialize(width, height, caption, widget)
|
13
|
+
super(width, height)
|
14
|
+
self.caption = caption
|
15
|
+
@update_count = 0
|
16
|
+
WadsConfig.instance.set_window(self)
|
17
|
+
set_display(widget)
|
18
|
+
WadsConfig.instance.set_log_level("info")
|
19
|
+
end
|
23
20
|
|
24
|
-
|
25
|
-
#
|
26
|
-
|
27
|
-
|
21
|
+
#
|
22
|
+
# This method must be invoked with any Wads::Widget instance. It then handles
|
23
|
+
# delegating all events and drawing all child widgets.
|
24
|
+
#
|
25
|
+
def set_display(widget)
|
26
|
+
@main_widget = widget
|
28
27
|
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
stats = process_stock_data
|
33
|
-
if opts[:gui]
|
34
|
-
@display_widget = SampleStocksDisplay.new(@small_font, stats)
|
35
|
-
show
|
36
|
-
else
|
37
|
-
stats.report(Date::DAYNAMES[1..5])
|
38
|
-
end
|
39
|
-
|
40
|
-
elsif opts[:lottery]
|
41
|
-
process_lottery_data
|
42
|
-
else
|
43
|
-
puts " "
|
44
|
-
puts "Select one of the following sample analysis options"
|
45
|
-
puts "-s Run sample stocks analysis"
|
46
|
-
puts "-l Run sample analysis of lottery numbers"
|
47
|
-
puts " "
|
48
|
-
exit
|
29
|
+
def get_display
|
30
|
+
@main_widget
|
49
31
|
end
|
50
32
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
33
|
+
def update
|
34
|
+
@main_widget.update(@update_count, mouse_x, mouse_y)
|
35
|
+
@update_count = @update_count + 1
|
36
|
+
end
|
56
37
|
|
57
|
-
|
58
|
-
|
59
|
-
@display_widget.draw
|
60
|
-
end
|
61
|
-
|
62
|
-
def draw_banner
|
63
|
-
@banner_image.draw(1,1,1,0.9,0.9)
|
64
|
-
@title_font.draw_text("Wads Sample App", 10, 20, 2, 1, 1, Gosu::Color::WHITE)
|
65
|
-
@version_font.draw_text("Version #{Wads::VERSION}", 13, 54, 2, 1, 1, Gosu::Color::WHITE)
|
66
|
-
end
|
67
|
-
|
68
|
-
def button_down id
|
69
|
-
close if id == Gosu::KbEscape
|
70
|
-
# Delegate button events to the primary display widget
|
71
|
-
result = @display_widget.button_down id, mouse_x, mouse_y
|
72
|
-
if result.close_widget
|
73
|
-
close
|
38
|
+
def draw
|
39
|
+
@main_widget.draw
|
74
40
|
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def process_stock_data
|
78
|
-
# The data file comes from https://finance.yahoo.com
|
79
|
-
# The format of this file is as follows:
|
80
|
-
#
|
81
|
-
# Date,Open,High,Low,Close,Adj Close,Volume
|
82
|
-
# 2000-01-03,4186.189941,4192.189941,3989.709961,4131.149902,4131.149902,1510070000
|
83
|
-
# 2000-01-04,4020.000000,4073.250000,3898.229980,3901.689941,3901.689941,1511840000
|
84
|
-
# ...
|
85
|
-
# 2020-12-30,12906.509766,12924.929688,12857.759766,12870.000000,12870.000000,5292210000
|
86
|
-
# 2020-12-31,12877.089844,12902.070313,12821.230469,12888.280273,12888.280273,4771390000
|
87
|
-
|
88
|
-
stats = Stats.new("NASDAQ")
|
89
|
-
previous_close = nil
|
90
|
-
|
91
|
-
puts "Read the data file #{STOCKS_DATA_FILE}"
|
92
|
-
File.readlines(STOCKS_DATA_FILE).each do |line|
|
93
|
-
line = line.chomp # remove the carriage return
|
94
|
-
|
95
|
-
# Ignore header and any empty lines, process numeric data lines
|
96
|
-
if line.length > 0 and line[0].match(/[0-9]/)
|
97
|
-
values = line.split(",")
|
98
|
-
date = Date.strptime(values[0], "%Y-%m-%d")
|
99
|
-
weekday = Date::DAYNAMES[date.wday]
|
100
|
-
|
101
|
-
open_value = values[1].to_f
|
102
|
-
close_value = values[4].to_f
|
103
41
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
change_percent = change_from_previous_close / previous_close
|
113
|
-
|
114
|
-
stats.add(weekday, change_percent)
|
115
|
-
stats.add("#{weekday} prev close", change_from_previous_close)
|
116
|
-
stats.add("#{weekday} intraday", change_intraday)
|
117
|
-
stats.add("#{weekday} overnight", change_overnight)
|
118
|
-
|
119
|
-
previous_close = close_value
|
42
|
+
def button_down id
|
43
|
+
close if id == Gosu::KbEscape
|
44
|
+
# Delegate button events to the primary display widget
|
45
|
+
result = @main_widget.button_down id, mouse_x, mouse_y
|
46
|
+
if not result.nil? and result.is_a? WidgetResult
|
47
|
+
if result.close_widget
|
48
|
+
close
|
120
49
|
end
|
121
50
|
end
|
122
51
|
end
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
def process_lottery_data
|
128
|
-
puts "The lottery example has not been implemented yet"
|
129
|
-
puts "however the data is available in the data directory,"
|
130
|
-
puts "and the same pattern used in the stocks example can"
|
131
|
-
puts "be applied here."
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
class SampleStocksDisplay < Widget
|
136
|
-
attr_accessor :stats
|
137
|
-
|
138
|
-
def initialize(font, stats)
|
139
|
-
super(10, 100, COLOR_HEADER_BRIGHT_BLUE)
|
140
|
-
set_dimensions(780, 500)
|
141
|
-
set_font(font)
|
142
|
-
add_child(Document.new(sample_content, x + 5, y + 5, @width, @height, @font))
|
143
|
-
@exit_button = Button.new("Exit", 380, bottom_edge - 30, @font)
|
144
|
-
add_child(@exit_button)
|
145
|
-
|
146
|
-
@stats = stats
|
147
|
-
@data_table = SingleSelectTable.new(@x + 5, @y + 100, # top left corner
|
148
|
-
770, 200, # width, height
|
149
|
-
["Day", "Min", "Avg", "StdDev", "Max", "p10", "p90"], # column headers
|
150
|
-
@font, COLOR_WHITE) # font and text color
|
151
|
-
@data_table.selected_color = COLOR_LIGHT_GRAY
|
152
|
-
Date::DAYNAMES[1..5].each do |day|
|
153
|
-
min = format_percent(@stats.min(day))
|
154
|
-
avg = format_percent(@stats.average(day))
|
155
|
-
std = format_percent(@stats.std_dev(day))
|
156
|
-
max = format_percent(@stats.max(day))
|
157
|
-
p10 = format_percent(@stats.percentile(day, 0.1))
|
158
|
-
p90 = format_percent(@stats.percentile(day, 0.90))
|
159
|
-
@data_table.add_row([day, min, avg, std, max, p10, p90], COLOR_HEADER_BRIGHT_BLUE)
|
160
|
-
end
|
161
|
-
add_child(@data_table)
|
162
|
-
@selection_text = nil
|
163
|
-
end
|
164
|
-
|
165
|
-
def format_percent(val)
|
166
|
-
"#{(val * 100).round(3)}%"
|
167
|
-
end
|
168
|
-
|
169
|
-
def sample_content
|
170
|
-
<<~HEREDOC
|
171
|
-
This sample stock analysis uses NASDAQ data from https://finance.yahoo.com looking
|
172
|
-
at closing data through the years 2000 to 2020. The percent gain or loss is broken
|
173
|
-
down per day, as shown in the table below.
|
174
|
-
HEREDOC
|
175
|
-
end
|
176
|
-
|
177
|
-
def render
|
178
|
-
if @selection_text
|
179
|
-
@selection_text.draw
|
52
|
+
|
53
|
+
def button_up id
|
54
|
+
@main_widget.button_up id, mouse_x, mouse_y
|
180
55
|
end
|
181
56
|
end
|
182
|
-
|
183
|
-
def button_down id, mouse_x, mouse_y
|
184
|
-
if id == Gosu::MsLeft
|
185
|
-
if @exit_button.contains_click(mouse_x, mouse_y)
|
186
|
-
return WidgetResult.new(true)
|
187
|
-
elsif @data_table.contains_click(mouse_x, mouse_y)
|
188
|
-
val = @data_table.set_selected_row(mouse_y, 0)
|
189
|
-
if val.nil?
|
190
|
-
# nothing to do
|
191
|
-
else
|
192
|
-
@selection_text = Text.new("You selected #{val}, a great day!",
|
193
|
-
x + 5, y + 400, @font)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
WidgetResult.new(false)
|
198
|
-
end
|
199
|
-
end
|
57
|
+
end
|