xyp 0.0.1
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 +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: []
|