xyp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/xyp +5 -0
- data/lib/xyp/gui.rb +181 -0
- data/lib/xyp/gui_v0.glade +296 -0
- data/lib/xyp/plot.rb +193 -0
- data/lib/xyp/runner.rb +63 -0
- data/lib/xyp/version.rb +3 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a319b535613b986d1c4fcbed085d797cd1ced8c5a1e28068f392d0152c0f4c45
|
4
|
+
data.tar.gz: d7a61a45426e656e0a29a4c37a337cb9c71e9010f18bce62e0b04ddefc109657
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc13ab445334ea28b66f51aa5fedd2722bbf7b3636a3c6988f231cb8f13840efe1352fb3f2ba53103f357683a35e1255b91af85c52cbcd9339b8f047e587f5a1
|
7
|
+
data.tar.gz: b514223984e368ad8d198f38c741977b57ffa763e2a35751a6a68f30623683a6a9392eb4a445b17c38fe58c4d05f73c3ae85067b9edb3d65d9df1977da6c28ee
|
data/bin/xyp
ADDED
data/lib/xyp/gui.rb
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'gtk3'
|
2
|
+
|
3
|
+
require_relative 'plot'
|
4
|
+
|
5
|
+
GREY = Gdk::RGBA::new(0.2, 0.2, 0.2, 1)
|
6
|
+
RED = Cairo::Color.parse("red")
|
7
|
+
CYAN = Cairo::Color.parse("cyan")
|
8
|
+
YELLOW = Cairo::Color.parse("yellow")
|
9
|
+
GREEN = Cairo::Color.parse("green")
|
10
|
+
ORANGE = Cairo::Color.parse("orange")
|
11
|
+
|
12
|
+
SINUS = (-10*Math::PI..10*Math::PI).step(0.1).inject({}){|hash,x| hash[x]=Math::sin(x) ; hash}
|
13
|
+
|
14
|
+
module XYP
|
15
|
+
|
16
|
+
class GUI
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
glade_file = File.expand_path(__dir__)+"/gui_v0.glade"
|
20
|
+
builder=Gtk::Builder.new
|
21
|
+
builder.add_from_file(glade_file)
|
22
|
+
builder.connect_signals{|handler| method(handler)}
|
23
|
+
@main_window = builder['window1']
|
24
|
+
@main_window.signal_connect("destroy"){Gtk.main_quit}
|
25
|
+
|
26
|
+
@drawing =builder['drawingarea1']
|
27
|
+
|
28
|
+
@drawing.add_events [:leave_notify_mask,
|
29
|
+
:button_press_mask,
|
30
|
+
:pointer_motion_mask,
|
31
|
+
:pointer_motion_hint_mask]
|
32
|
+
create_callbacks
|
33
|
+
dummy_test
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_callbacks
|
37
|
+
@drawing.signal_connect("draw"){redraw}
|
38
|
+
|
39
|
+
@drawing.signal_connect("button-press-event") do |widget, event|
|
40
|
+
@start_drag=Point.new(event.x,event.y)
|
41
|
+
end
|
42
|
+
|
43
|
+
@drawing.signal_connect("motion-notify-event") do |widget, event|
|
44
|
+
do_it=false
|
45
|
+
if @start_drag
|
46
|
+
modify_center event
|
47
|
+
@start_drag=@end_drag
|
48
|
+
redraw
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
@drawing.signal_connect("button-release-event") do |widget, event|
|
53
|
+
modify_center event
|
54
|
+
@start_drag=nil
|
55
|
+
redraw
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def modify_center event
|
60
|
+
@end_drag=Point.new(event.x,event.y)
|
61
|
+
delta_x=((@end_drag.x-@start_drag.x)/@plot.ratio.x)
|
62
|
+
delta_y=((@end_drag.y-@start_drag.y)/@plot.ratio.y)
|
63
|
+
delta=Point.new(delta_x,-delta_y)
|
64
|
+
@view.center=@view.center-delta
|
65
|
+
end
|
66
|
+
|
67
|
+
def run options
|
68
|
+
@main_window.show
|
69
|
+
if filename=options[:data_file]
|
70
|
+
load_data(filename)
|
71
|
+
end
|
72
|
+
Gtk.main
|
73
|
+
end
|
74
|
+
|
75
|
+
# signal handler for main window destory event
|
76
|
+
def quit
|
77
|
+
Gtk.main_quit
|
78
|
+
end
|
79
|
+
|
80
|
+
def on_button_info_clicked
|
81
|
+
about = Gtk::AboutDialog.new
|
82
|
+
about.set_program_name "xyp"
|
83
|
+
about.set_version "0.0.1"
|
84
|
+
about.set_copyright "(c) Jean-Christophe Le Lann"
|
85
|
+
about.set_comments "Ruby GTK3 XY Plotter"
|
86
|
+
about.set_website "http://www.jcll.fr"
|
87
|
+
begin
|
88
|
+
dir = File.expand_path(__dir__)
|
89
|
+
logo = GdkPixbuf::Pixbuf.new :file => "#{dir}/../../doc/screen.png"
|
90
|
+
about.set_logo logo
|
91
|
+
rescue IOError => e
|
92
|
+
puts e
|
93
|
+
puts "cannot load image"
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
about.run
|
97
|
+
about.destroy
|
98
|
+
end
|
99
|
+
|
100
|
+
def on_filechooserbutton1_file_set chooser
|
101
|
+
load_data(chooser.filename)
|
102
|
+
end
|
103
|
+
|
104
|
+
def load_data filename
|
105
|
+
@dataset=IO.readlines(filename).inject({}) do |hash,line|
|
106
|
+
x,y=*line.split.map(&:to_f)
|
107
|
+
hash[x]=y
|
108
|
+
hash
|
109
|
+
end
|
110
|
+
|
111
|
+
@plot=Plot.new(filename)
|
112
|
+
@plot.set_background_rgba GREY
|
113
|
+
@plot.set_data_set @dataset
|
114
|
+
on_button_zoom_fit_clicked
|
115
|
+
end
|
116
|
+
|
117
|
+
def on_button_zoom_fit_clicked
|
118
|
+
if @dataset
|
119
|
+
min_x,max_x=@dataset.keys.minmax
|
120
|
+
min_y,max_y=@dataset.values.minmax
|
121
|
+
|
122
|
+
center_x=min_x+(max_x-min_x).abs/2
|
123
|
+
center_y=min_y+(max_y-min_y).abs/2
|
124
|
+
center=Point.new(center_x,center_y)
|
125
|
+
|
126
|
+
diff_x=max_x-min_x
|
127
|
+
diff_y=max_y-min_y
|
128
|
+
dims=[diff_x,diff_y]
|
129
|
+
|
130
|
+
@view=View.new(center,dims)
|
131
|
+
|
132
|
+
@plot.set_view @view
|
133
|
+
redraw
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def on_button_zoom_x_clicked
|
138
|
+
@view.dims.x/=2
|
139
|
+
redraw
|
140
|
+
end
|
141
|
+
|
142
|
+
def on_button_unzoom_x_clicked
|
143
|
+
@view.dims.x*=2
|
144
|
+
redraw
|
145
|
+
end
|
146
|
+
|
147
|
+
def on_button_zoom_y_clicked
|
148
|
+
@view.dims.y/=2
|
149
|
+
redraw
|
150
|
+
end
|
151
|
+
|
152
|
+
def on_button_unzoom_y_clicked
|
153
|
+
@view.dims.y*=2
|
154
|
+
redraw
|
155
|
+
end
|
156
|
+
|
157
|
+
#===============================================================
|
158
|
+
|
159
|
+
def handle_window_redimensioning
|
160
|
+
width,height=@drawing.window.width,@drawing.window.height
|
161
|
+
@plot.set_window_size [width,height]
|
162
|
+
end
|
163
|
+
|
164
|
+
def redraw
|
165
|
+
handle_window_redimensioning
|
166
|
+
cr = @drawing.window.create_cairo_context
|
167
|
+
@plot.plot(cr)
|
168
|
+
end
|
169
|
+
|
170
|
+
#===============================================================
|
171
|
+
def dummy_test
|
172
|
+
@plot=Plot.new(:test)
|
173
|
+
@plot.set_background_rgba GREY
|
174
|
+
@plot.set_data_set @dataset=SINUS
|
175
|
+
center_1_1=Point.new(1,1)
|
176
|
+
@view=View.new(center_1_1,[60,4])
|
177
|
+
@plot.set_view @view
|
178
|
+
# plot is done during redraw
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,296 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!-- Generated with glade 3.18.3 -->
|
3
|
+
<interface>
|
4
|
+
<requires lib="gtk+" version="3.12"/>
|
5
|
+
<object class="GtkWindow" id="window1">
|
6
|
+
<property name="width_request">800</property>
|
7
|
+
<property name="height_request">600</property>
|
8
|
+
<property name="can_focus">False</property>
|
9
|
+
<child>
|
10
|
+
<object class="GtkPaned" id="paned1">
|
11
|
+
<property name="visible">True</property>
|
12
|
+
<property name="can_focus">True</property>
|
13
|
+
<child>
|
14
|
+
<object class="GtkBox" id="box1">
|
15
|
+
<property name="visible">True</property>
|
16
|
+
<property name="can_focus">False</property>
|
17
|
+
<property name="margin_left">5</property>
|
18
|
+
<property name="margin_right">5</property>
|
19
|
+
<property name="orientation">vertical</property>
|
20
|
+
<child>
|
21
|
+
<object class="GtkButtonBox" id="buttonbox1">
|
22
|
+
<property name="visible">True</property>
|
23
|
+
<property name="can_focus">False</property>
|
24
|
+
<property name="margin_top">20</property>
|
25
|
+
<property name="margin_bottom">20</property>
|
26
|
+
<property name="orientation">vertical</property>
|
27
|
+
<property name="spacing">5</property>
|
28
|
+
<property name="layout_style">start</property>
|
29
|
+
<child>
|
30
|
+
<object class="GtkButton" id="button_info">
|
31
|
+
<property name="label" translatable="yes">info</property>
|
32
|
+
<property name="visible">True</property>
|
33
|
+
<property name="can_focus">True</property>
|
34
|
+
<property name="receives_default">True</property>
|
35
|
+
<signal name="clicked" handler="on_button_info_clicked" swapped="no"/>
|
36
|
+
</object>
|
37
|
+
<packing>
|
38
|
+
<property name="expand">True</property>
|
39
|
+
<property name="fill">True</property>
|
40
|
+
<property name="position">0</property>
|
41
|
+
</packing>
|
42
|
+
</child>
|
43
|
+
<child>
|
44
|
+
<object class="GtkFileChooserButton" id="filechooserbutton1">
|
45
|
+
<property name="visible">True</property>
|
46
|
+
<property name="can_focus">False</property>
|
47
|
+
<signal name="file-set" handler="on_filechooserbutton1_file_set" swapped="no"/>
|
48
|
+
</object>
|
49
|
+
<packing>
|
50
|
+
<property name="expand">True</property>
|
51
|
+
<property name="fill">True</property>
|
52
|
+
<property name="position">1</property>
|
53
|
+
</packing>
|
54
|
+
</child>
|
55
|
+
<child>
|
56
|
+
<object class="GtkButton" id="button_zoom_fit">
|
57
|
+
<property name="label" translatable="yes">zoom fit</property>
|
58
|
+
<property name="visible">True</property>
|
59
|
+
<property name="can_focus">True</property>
|
60
|
+
<property name="receives_default">True</property>
|
61
|
+
<signal name="clicked" handler="on_button_zoom_fit_clicked" swapped="no"/>
|
62
|
+
</object>
|
63
|
+
<packing>
|
64
|
+
<property name="expand">True</property>
|
65
|
+
<property name="fill">True</property>
|
66
|
+
<property name="position">2</property>
|
67
|
+
</packing>
|
68
|
+
</child>
|
69
|
+
<child>
|
70
|
+
<object class="GtkButton" id="button_zoom_x">
|
71
|
+
<property name="label" translatable="yes">zoom_x</property>
|
72
|
+
<property name="visible">True</property>
|
73
|
+
<property name="can_focus">True</property>
|
74
|
+
<property name="receives_default">True</property>
|
75
|
+
<signal name="clicked" handler="on_button_zoom_x_clicked" swapped="no"/>
|
76
|
+
</object>
|
77
|
+
<packing>
|
78
|
+
<property name="expand">True</property>
|
79
|
+
<property name="fill">True</property>
|
80
|
+
<property name="position">3</property>
|
81
|
+
</packing>
|
82
|
+
</child>
|
83
|
+
<child>
|
84
|
+
<object class="GtkButton" id="button_unzoom_x">
|
85
|
+
<property name="label" translatable="yes">unzoom_x</property>
|
86
|
+
<property name="visible">True</property>
|
87
|
+
<property name="can_focus">True</property>
|
88
|
+
<property name="receives_default">True</property>
|
89
|
+
<signal name="clicked" handler="on_button_unzoom_x_clicked" swapped="no"/>
|
90
|
+
</object>
|
91
|
+
<packing>
|
92
|
+
<property name="expand">True</property>
|
93
|
+
<property name="fill">True</property>
|
94
|
+
<property name="position">4</property>
|
95
|
+
</packing>
|
96
|
+
</child>
|
97
|
+
<child>
|
98
|
+
<object class="GtkButton" id="button_zoom_y">
|
99
|
+
<property name="label" translatable="yes">zoom_y</property>
|
100
|
+
<property name="visible">True</property>
|
101
|
+
<property name="can_focus">True</property>
|
102
|
+
<property name="receives_default">True</property>
|
103
|
+
<signal name="clicked" handler="on_button_zoom_y_clicked" swapped="no"/>
|
104
|
+
</object>
|
105
|
+
<packing>
|
106
|
+
<property name="expand">True</property>
|
107
|
+
<property name="fill">True</property>
|
108
|
+
<property name="position">5</property>
|
109
|
+
</packing>
|
110
|
+
</child>
|
111
|
+
<child>
|
112
|
+
<object class="GtkButton" id="button_unzoom_y">
|
113
|
+
<property name="label" translatable="yes">unzoom_y</property>
|
114
|
+
<property name="visible">True</property>
|
115
|
+
<property name="can_focus">True</property>
|
116
|
+
<property name="receives_default">True</property>
|
117
|
+
<signal name="clicked" handler="on_button_unzoom_y_clicked" swapped="no"/>
|
118
|
+
</object>
|
119
|
+
<packing>
|
120
|
+
<property name="expand">True</property>
|
121
|
+
<property name="fill">True</property>
|
122
|
+
<property name="position">6</property>
|
123
|
+
</packing>
|
124
|
+
</child>
|
125
|
+
<child>
|
126
|
+
<object class="GtkButton" id="button_grid_plus">
|
127
|
+
<property name="label" translatable="yes">grid+</property>
|
128
|
+
<property name="visible">True</property>
|
129
|
+
<property name="can_focus">True</property>
|
130
|
+
<property name="receives_default">True</property>
|
131
|
+
</object>
|
132
|
+
<packing>
|
133
|
+
<property name="expand">True</property>
|
134
|
+
<property name="fill">True</property>
|
135
|
+
<property name="position">7</property>
|
136
|
+
</packing>
|
137
|
+
</child>
|
138
|
+
<child>
|
139
|
+
<object class="GtkButton" id="button_grid_minus">
|
140
|
+
<property name="label" translatable="yes">grid-</property>
|
141
|
+
<property name="visible">True</property>
|
142
|
+
<property name="can_focus">True</property>
|
143
|
+
<property name="receives_default">True</property>
|
144
|
+
</object>
|
145
|
+
<packing>
|
146
|
+
<property name="expand">True</property>
|
147
|
+
<property name="fill">True</property>
|
148
|
+
<property name="position">8</property>
|
149
|
+
</packing>
|
150
|
+
</child>
|
151
|
+
</object>
|
152
|
+
<packing>
|
153
|
+
<property name="expand">False</property>
|
154
|
+
<property name="fill">True</property>
|
155
|
+
<property name="position">0</property>
|
156
|
+
</packing>
|
157
|
+
</child>
|
158
|
+
<child>
|
159
|
+
<object class="GtkSeparator" id="separator1">
|
160
|
+
<property name="visible">True</property>
|
161
|
+
<property name="can_focus">False</property>
|
162
|
+
</object>
|
163
|
+
<packing>
|
164
|
+
<property name="expand">False</property>
|
165
|
+
<property name="fill">True</property>
|
166
|
+
<property name="position">1</property>
|
167
|
+
</packing>
|
168
|
+
</child>
|
169
|
+
<child>
|
170
|
+
<object class="GtkGrid" id="grid1">
|
171
|
+
<property name="visible">True</property>
|
172
|
+
<property name="can_focus">False</property>
|
173
|
+
<child>
|
174
|
+
<object class="GtkCheckButton" id="checkbutton1">
|
175
|
+
<property name="label" translatable="yes">with lines</property>
|
176
|
+
<property name="visible">True</property>
|
177
|
+
<property name="can_focus">True</property>
|
178
|
+
<property name="receives_default">False</property>
|
179
|
+
<property name="xalign">0</property>
|
180
|
+
<property name="draw_indicator">True</property>
|
181
|
+
</object>
|
182
|
+
<packing>
|
183
|
+
<property name="left_attach">1</property>
|
184
|
+
<property name="top_attach">0</property>
|
185
|
+
</packing>
|
186
|
+
</child>
|
187
|
+
<child>
|
188
|
+
<placeholder/>
|
189
|
+
</child>
|
190
|
+
</object>
|
191
|
+
<packing>
|
192
|
+
<property name="expand">False</property>
|
193
|
+
<property name="fill">True</property>
|
194
|
+
<property name="position">2</property>
|
195
|
+
</packing>
|
196
|
+
</child>
|
197
|
+
<child>
|
198
|
+
<object class="GtkSeparator" id="separator2">
|
199
|
+
<property name="visible">True</property>
|
200
|
+
<property name="can_focus">False</property>
|
201
|
+
</object>
|
202
|
+
<packing>
|
203
|
+
<property name="expand">False</property>
|
204
|
+
<property name="fill">True</property>
|
205
|
+
<property name="position">3</property>
|
206
|
+
</packing>
|
207
|
+
</child>
|
208
|
+
<child>
|
209
|
+
<object class="GtkBox" id="box2">
|
210
|
+
<property name="visible">True</property>
|
211
|
+
<property name="can_focus">False</property>
|
212
|
+
<property name="orientation">vertical</property>
|
213
|
+
<child>
|
214
|
+
<object class="GtkButton" id="button_func">
|
215
|
+
<property name="label" translatable="yes">draw func</property>
|
216
|
+
<property name="visible">True</property>
|
217
|
+
<property name="can_focus">True</property>
|
218
|
+
<property name="receives_default">True</property>
|
219
|
+
<property name="margin_top">5</property>
|
220
|
+
</object>
|
221
|
+
<packing>
|
222
|
+
<property name="expand">False</property>
|
223
|
+
<property name="fill">True</property>
|
224
|
+
<property name="position">0</property>
|
225
|
+
</packing>
|
226
|
+
</child>
|
227
|
+
<child>
|
228
|
+
<placeholder/>
|
229
|
+
</child>
|
230
|
+
<child>
|
231
|
+
<placeholder/>
|
232
|
+
</child>
|
233
|
+
<child>
|
234
|
+
<placeholder/>
|
235
|
+
</child>
|
236
|
+
<child>
|
237
|
+
<placeholder/>
|
238
|
+
</child>
|
239
|
+
</object>
|
240
|
+
<packing>
|
241
|
+
<property name="expand">False</property>
|
242
|
+
<property name="fill">True</property>
|
243
|
+
<property name="position">4</property>
|
244
|
+
</packing>
|
245
|
+
</child>
|
246
|
+
</object>
|
247
|
+
<packing>
|
248
|
+
<property name="resize">False</property>
|
249
|
+
<property name="shrink">True</property>
|
250
|
+
</packing>
|
251
|
+
</child>
|
252
|
+
<child>
|
253
|
+
<object class="GtkFrame" id="frame1">
|
254
|
+
<property name="visible">True</property>
|
255
|
+
<property name="can_focus">False</property>
|
256
|
+
<property name="margin_left">10</property>
|
257
|
+
<property name="margin_right">10</property>
|
258
|
+
<property name="margin_top">5</property>
|
259
|
+
<property name="margin_bottom">5</property>
|
260
|
+
<property name="label_xalign">0</property>
|
261
|
+
<property name="shadow_type">in</property>
|
262
|
+
<child>
|
263
|
+
<object class="GtkAlignment" id="alignment1">
|
264
|
+
<property name="visible">True</property>
|
265
|
+
<property name="can_focus">False</property>
|
266
|
+
<property name="left_padding">12</property>
|
267
|
+
<child>
|
268
|
+
<object class="GtkDrawingArea" id="drawingarea1">
|
269
|
+
<property name="visible">True</property>
|
270
|
+
<property name="can_focus">False</property>
|
271
|
+
<property name="events">GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
272
|
+
<property name="margin_left">5</property>
|
273
|
+
<property name="margin_right">10</property>
|
274
|
+
<property name="margin_top">5</property>
|
275
|
+
<property name="margin_bottom">5</property>
|
276
|
+
</object>
|
277
|
+
</child>
|
278
|
+
</object>
|
279
|
+
</child>
|
280
|
+
<child type="label">
|
281
|
+
<object class="GtkLabel" id="label3">
|
282
|
+
<property name="visible">True</property>
|
283
|
+
<property name="can_focus">False</property>
|
284
|
+
<property name="label" translatable="yes">frame1</property>
|
285
|
+
</object>
|
286
|
+
</child>
|
287
|
+
</object>
|
288
|
+
<packing>
|
289
|
+
<property name="resize">True</property>
|
290
|
+
<property name="shrink">True</property>
|
291
|
+
</packing>
|
292
|
+
</child>
|
293
|
+
</object>
|
294
|
+
</child>
|
295
|
+
</object>
|
296
|
+
</interface>
|
data/lib/xyp/plot.rb
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
class Array
|
2
|
+
def x
|
3
|
+
self[0]
|
4
|
+
end
|
5
|
+
|
6
|
+
def y
|
7
|
+
self[1]
|
8
|
+
end
|
9
|
+
|
10
|
+
def x=(v)
|
11
|
+
self[0]=v
|
12
|
+
end
|
13
|
+
|
14
|
+
def y=(v)
|
15
|
+
self[1]=v
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module XYP
|
20
|
+
|
21
|
+
Point= Struct.new(:x,:y) do
|
22
|
+
def -(other)
|
23
|
+
Point.new(self.x-other.x,self.y-other.y)
|
24
|
+
end
|
25
|
+
|
26
|
+
def +(other)
|
27
|
+
Point.new(self.x+other.x,self.y+other.y)
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_i
|
31
|
+
Point.new(x.to_i,y.to_i)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_a
|
35
|
+
[x,y]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class View
|
40
|
+
attr_accessor :center,:dims
|
41
|
+
def initialize center,dims
|
42
|
+
@center=center
|
43
|
+
@dims=dims.map(&:to_f)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Plot
|
48
|
+
|
49
|
+
attr_accessor :ratio
|
50
|
+
attr_accessor :name,:data_set
|
51
|
+
attr_accessor :moving
|
52
|
+
|
53
|
+
def initialize name
|
54
|
+
@name=name
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_data_set hash
|
58
|
+
@data_set=hash
|
59
|
+
end
|
60
|
+
|
61
|
+
def set_view view
|
62
|
+
@view=view
|
63
|
+
end
|
64
|
+
|
65
|
+
def set_window_size size
|
66
|
+
@window_size=size
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_background_rgba color
|
70
|
+
@color_rbga=color
|
71
|
+
end
|
72
|
+
|
73
|
+
def plot cairo
|
74
|
+
wx,wy=*@window_size.map(&:to_f)
|
75
|
+
vx,vy=*(@view.dims||[1,1]).map(&:to_f)
|
76
|
+
@ratio=[wx/vx,wy/vy]
|
77
|
+
cairo.set_source_rgba @color_rbga
|
78
|
+
cairo.paint
|
79
|
+
paint_grid(cairo)
|
80
|
+
paint_axis(cairo)
|
81
|
+
paint_data_set_line(cairo)
|
82
|
+
end
|
83
|
+
|
84
|
+
def window_coord p
|
85
|
+
cx=@view.dims.x/2.0-@view.center.x
|
86
|
+
cy=@view.dims.y/2.0-@view.center.y
|
87
|
+
xx=(p.x+cx)*@ratio.x
|
88
|
+
yy=@window_size.y-(p.y+cy)*@ratio.y
|
89
|
+
Point.new xx,yy
|
90
|
+
end
|
91
|
+
|
92
|
+
def draw_line(ctx,start_,end_) # true abstract coord
|
93
|
+
p1=window_coord(start_)
|
94
|
+
ctx.move_to(p1.x,p1.y)
|
95
|
+
p2=window_coord(end_)
|
96
|
+
ctx.line_to(p2.x,p2.y)
|
97
|
+
ctx.stroke
|
98
|
+
end
|
99
|
+
|
100
|
+
def draw_point ctx,center,radius # true abstract coord
|
101
|
+
p=window_coord(center)
|
102
|
+
ctx.arc p.x,p.y,1,0,2*Math::PI
|
103
|
+
ctx.fill
|
104
|
+
end
|
105
|
+
|
106
|
+
def paint_data_set_line ctx
|
107
|
+
ctx.set_source *YELLOW
|
108
|
+
@points||=@data_set.each.collect{|a,b| Point.new(a,b)}
|
109
|
+
@points.each_cons(2) do |start,end_|
|
110
|
+
draw_line(ctx,start,end_)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def paint_grid ctx
|
115
|
+
x_1=(@view.center.x-@view.dims.x/2-2).to_i
|
116
|
+
x_2=(@view.center.x+@view.dims.x/2+2).to_i
|
117
|
+
y_1=(@view.center.y-@view.dims.y/2).to_i
|
118
|
+
y_2=(@view.center.y+@view.dims.y/2).to_i
|
119
|
+
x_range=x_1..x_2
|
120
|
+
y_range=y_1..y_2
|
121
|
+
transparency=400.0/(x_range.size*y_range.size)
|
122
|
+
if transparency>0.08
|
123
|
+
for x in x_range
|
124
|
+
for y in y_range
|
125
|
+
ctx.set_source ORANGE.red,ORANGE.green,ORANGE.blue,transparency
|
126
|
+
center=Point.new(x,y)
|
127
|
+
draw_point(ctx,center,1)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def paint_text_axis ctx,txt,point,axis_sym
|
134
|
+
coord=*window_coord(point).to_a
|
135
|
+
coord.x+=20 if axis_sym==:y
|
136
|
+
coord.y-=20 if axis_sym==:x
|
137
|
+
ctx.move_to *coord
|
138
|
+
ctx.show_text txt
|
139
|
+
end
|
140
|
+
|
141
|
+
def paint_axis ctx
|
142
|
+
ctx.select_font_face "Monospace"
|
143
|
+
ctx.set_font_size 13
|
144
|
+
|
145
|
+
x_1=(@view.center.x-@view.dims.x/2)
|
146
|
+
x_2=(@view.center.x+@view.dims.x/2)
|
147
|
+
x_1-=1
|
148
|
+
x_2+=1
|
149
|
+
y = 0
|
150
|
+
p1=Point.new(x_1,y)
|
151
|
+
p2=Point.new(x_2,y)
|
152
|
+
ctx.set_source *ORANGE
|
153
|
+
draw_line(ctx,p1,p2)
|
154
|
+
|
155
|
+
size_tick=@view.dims.y.to_f/60
|
156
|
+
range=x_1.to_i..x_2.to_i
|
157
|
+
transparency=10.0/range.size
|
158
|
+
if transparency>0.2
|
159
|
+
for x in range
|
160
|
+
p1=Point.new(x,-size_tick/2)
|
161
|
+
p2=Point.new(x,size_tick/2)
|
162
|
+
draw_line(ctx,p1,p2)
|
163
|
+
paint_text_axis(ctx,"#{x}",p1,:x)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
y_1=(@view.center.y-@view.dims.y/2)
|
169
|
+
y_2=(@view.center.y+@view.dims.y/2)
|
170
|
+
x = 0
|
171
|
+
y_1-=3
|
172
|
+
y_2+=3
|
173
|
+
p3=Point.new(x,y_1)
|
174
|
+
p4=Point.new(x,y_2)
|
175
|
+
ctx.set_source *ORANGE
|
176
|
+
draw_line(ctx,p3,p4)
|
177
|
+
|
178
|
+
size_tick=@view.dims.x.to_f/80
|
179
|
+
range=y_1.to_i..y_2.to_i
|
180
|
+
transparency=10.0/range.size
|
181
|
+
|
182
|
+
if transparency>0.2
|
183
|
+
for y in range
|
184
|
+
ctx.set_source ORANGE.red,ORANGE.green,ORANGE.blue,transparency
|
185
|
+
p1=Point.new(-size_tick/2,y)
|
186
|
+
p2=Point.new(size_tick/2,y)
|
187
|
+
draw_line(ctx,p1,p2)
|
188
|
+
paint_text_axis(ctx,"#{y}",p1,:y)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
data/lib/xyp/runner.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "ostruct"
|
3
|
+
|
4
|
+
require_relative "version"
|
5
|
+
require_relative "gui"
|
6
|
+
|
7
|
+
module XYP
|
8
|
+
|
9
|
+
class Runner
|
10
|
+
attr_accessor :options
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@options={}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.run *arguments
|
17
|
+
new.run(arguments)
|
18
|
+
end
|
19
|
+
|
20
|
+
def run arguments
|
21
|
+
options = parse_options(arguments)
|
22
|
+
gui options
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def parse_options(arguments)
|
27
|
+
|
28
|
+
size=arguments.size
|
29
|
+
|
30
|
+
parser = OptionParser.new
|
31
|
+
|
32
|
+
options = {}
|
33
|
+
|
34
|
+
parser.on("-h", "--help", "Show help message") do
|
35
|
+
puts parser
|
36
|
+
exit(true)
|
37
|
+
end
|
38
|
+
|
39
|
+
parser.on("-v", "--version", "Show version number") do
|
40
|
+
puts VERSION
|
41
|
+
exit(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
parser.on("-d", "--data FILE", "data file>") do |file|
|
45
|
+
options[:data_file] = file
|
46
|
+
end
|
47
|
+
|
48
|
+
parser.parse!(arguments)
|
49
|
+
|
50
|
+
if size==0
|
51
|
+
puts parser
|
52
|
+
end
|
53
|
+
|
54
|
+
options
|
55
|
+
end
|
56
|
+
|
57
|
+
def gui options
|
58
|
+
gui = GUI.new #(glade_file)
|
59
|
+
gui.run(options)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
data/lib/xyp/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xyp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jean-Christophe Le Lann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-11-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gtk3
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.4.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.4.1
|
27
|
+
description: xyp is a simple 2D graphics plotter
|
28
|
+
email: lelannje@ensta-bretagne.fr
|
29
|
+
executables:
|
30
|
+
- xyp
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- bin/xyp
|
35
|
+
- lib/xyp/gui.rb
|
36
|
+
- lib/xyp/gui_v0.glade
|
37
|
+
- lib/xyp/plot.rb
|
38
|
+
- lib/xyp/runner.rb
|
39
|
+
- lib/xyp/version.rb
|
40
|
+
homepage: https://github.com/JC-LL/xyp
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
metadata: {}
|
44
|
+
post_install_message: Thanks for installing ! Homepage :https://github.com/JC-LL/xyp
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 2.5.0
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubygems_version: 3.0.6
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Simple 2D graphics plotter
|
63
|
+
test_files: []
|