A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
hud.py
Go to the documentation of this file.
1import math
2
3from gi.repository import GooCanvas, Gtk, Pango
4
5from .base import PIXELS_PER_METER
6
7
8
9class Axes(object):
10
22 def __init__(self, viz):
23 """!
24 Initializer function
25
26 @param self: this object
27 @param viz: visualization object
28 """
29 self.viz = viz
30 self.color = 0x8080C0FF
31 self.hlines = GooCanvas.CanvasPath(
32 parent=viz.canvas.get_root_item(), stroke_color_rgba=self.color
33 )
34 self.hlines.lower(None)
35 self.vlines = GooCanvas.CanvasPath(
36 parent=viz.canvas.get_root_item(), stroke_color_rgba=self.color
37 )
38 self.vlines.lower(None)
39 self.labels = []
40 hadj = self.viz.get_hadjustment()
41 vadj = self.viz.get_vadjustment()
42
43 def update(adj):
44 if self.visible:
45 self.update_view()
46
47 hadj.connect("value-changed", update)
48 vadj.connect("value-changed", update)
49 hadj.connect("changed", update)
50 vadj.connect("changed", update)
51 self.visible = True
52 self.update_view()
53
54 def set_visible(self, visible):
55 """!
56 Set visible function
57
58 @param self: this object
59 @param visible: visible indicator
60 @return none
61 """
62 self.visible = visible
63 if self.visible:
64 self.hlines.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
65 self.vlines.props.visibility = GooCanvas.CanvasItemVisibility.VISIBLE
66 else:
67 self.hlines.props.visibility = GooCanvas.CanvasItemVisibility.HIDDEN
68 self.vlines.props.visibility = GooCanvas.CanvasItemVisibility.HIDDEN
69 for label in self.labels:
70 label.props.visibility = GooCanvas.CanvasItemVisibility.HIDDEN
71
72 def _compute_divisions(self, xi, xf):
73 """!
74 Compute divisions function
75
76 @param self: this object
77 @param xi: xi
78 @param xf: xf
79 @return x0 and div
80 """
81 assert xf > xi
82 dx = xf - xi
83 size = dx
84 ndiv = 5
85 text_width = dx / ndiv / 2
86
87 def rint(x):
88 """!
89 Compute divisions function
90
91 @param x: x
92 @return x rounded up
93 """
94 return math.floor(x + 0.5)
95
96 dx_over_ndiv = dx / ndiv
97 for n in range(5): # iterate 5 times to find optimum division size
98 # div: length of each division
99 # looking for approx. 'ndiv' divisions in a length 'dx'
100 tbe = math.log10(dx_over_ndiv)
101 # div: power of 10 closest to dx/ndiv
102 div = pow(10, rint(tbe))
103 # test if div/2 is closer to dx/ndiv
104 if math.fabs(div / 2 - dx_over_ndiv) < math.fabs(div - dx_over_ndiv):
105 div /= 2
106 elif math.fabs(div * 2 - dx_over_ndiv) < math.fabs(div - dx_over_ndiv):
107 div *= 2 # test if div*2 is closer to dx/ndiv
108 x0 = div * math.ceil(xi / div) - div
109 if n > 1:
110 ndiv = rint(size / text_width)
111 return x0, div
112
113 def update_view(self):
114 """!
115 Update view function
116
117 @param self: this object
118 @return none
119 """
120 if self.viz.zoom is None:
121 return
122
123 unused_labels = self.labels
124 self.labels = []
125 for label in unused_labels:
126 label.set_property("visibility", GooCanvas.CanvasItemVisibility.HIDDEN)
127
128 def get_label():
129 """!
130 Get label function
131
132 @param self: this object
133 @return label
134 """
135 try:
136 label = unused_labels.pop(0)
137 except IndexError:
138 label = GooCanvas.CanvasText(
139 parent=self.viz.canvas.get_root_item(), stroke_color_rgba=self.color
140 )
141 else:
142 label.set_property("visibility", GooCanvas.CanvasItemVisibility.VISIBLE)
143 label.lower(None)
144 self.labels.append(label)
145 return label
146
147 hadj = self.viz.get_hadjustment()
148 vadj = self.viz.get_vadjustment()
149 zoom = self.viz.zoom.get_value()
150 offset = 10 / zoom
151
152 x1, y1 = self.viz.canvas.convert_from_pixels(hadj.get_value(), vadj.get_value())
153 x2, y2 = self.viz.canvas.convert_from_pixels(
154 hadj.get_value() + hadj.get_page_size(), vadj.get_value() + vadj.get_page_size()
155 )
156 line_width = 5.0 / self.viz.zoom.get_value()
157
158 # draw the horizontal axis
159 self.hlines.set_property("line-width", line_width)
160 yc = y2 - line_width / 2
161
162 sim_x1 = x1 / PIXELS_PER_METER
163 sim_x2 = x2 / PIXELS_PER_METER
164 x0, xdiv = self._compute_divisions(sim_x1, sim_x2)
165 path = ["M %r %r L %r %r" % (x1, yc, x2, yc)]
166 x = x0
167 while x < sim_x2:
168 path.append(
169 "M %r %r L %r %r" % (PIXELS_PER_METER * x, yc - offset, PIXELS_PER_METER * x, yc)
170 )
171 label = get_label()
172 label.set_properties(
173 font=("Sans Serif %f" % int(12 / zoom)),
174 text=("%G" % x),
175 fill_color_rgba=self.color,
176 alignment=Pango.Alignment.CENTER,
177 # anchor=Gtk.Widget.ANCHOR_S,
178 x=PIXELS_PER_METER * x,
179 y=(yc - offset),
180 )
181 x += xdiv
182 del x
183
184 self.hlines.set_property("data", " ".join(path))
185
186 # draw the vertical axis
187 self.vlines.set_property("line-width", line_width)
188 xc = x1 + line_width / 2
189
190 sim_y1 = y1 / PIXELS_PER_METER
191 sim_y2 = y2 / PIXELS_PER_METER
192
193 y0, ydiv = self._compute_divisions(sim_y1, sim_y2)
194 path = ["M %r %r L %r %r" % (xc, y1, xc, y2)]
195 y = y0
196 while y < sim_y2:
197 path.append(
198 "M %r %r L %r %r" % (xc, PIXELS_PER_METER * y, xc + offset, PIXELS_PER_METER * y)
199 )
200 label = get_label()
201 label.set_properties(
202 font=("Sans Serif %f" % int(12 / zoom)),
203 text=("%G" % y),
204 fill_color_rgba=self.color,
205 alignment=Pango.Alignment.LEFT,
206 # anchor=Gtk.ANCHOR_W,
207 x=xc + offset,
208 y=PIXELS_PER_METER * y,
209 )
210 y += ydiv
211
212 self.vlines.set_property("data", " ".join(path))
213
214 self.labels.extend(unused_labels)
Axes class.
Definition: hud.py:9
def _compute_divisions(self, xi, xf)
Compute divisions function.
Definition: hud.py:72
hlines
horizontal lines
Definition: hud.py:31
viz
visualizer
Definition: hud.py:29
vlines
vertical lines
Definition: hud.py:35
def __init__(self, viz)
Initializer function.
Definition: hud.py:22
labels
list of labels
Definition: hud.py:39
def update_view(self)
Update view function.
Definition: hud.py:113
def set_visible(self, visible)
Set visible function.
Definition: hud.py:54
visible
visible
Definition: hud.py:51