22 #License along with this library; if not, write to the Free Software |
22 #License along with this library; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 import wx |
25 import wx |
26 import wx.lib.plot as plot |
26 import wx.lib.plot as plot |
|
27 import numpy |
27 from graphics.GraphicCommons import DebugViewer |
28 from graphics.GraphicCommons import DebugViewer |
28 from controls import EditorPanel |
29 from controls import EditorPanel |
29 |
30 |
30 colours = ['blue', 'red', 'green', 'yellow', 'orange', 'purple', 'brown', 'cyan', |
31 colours = ['blue', 'red', 'green', 'yellow', 'orange', 'purple', 'brown', 'cyan', |
31 'pink', 'grey'] |
32 'pink', 'grey'] |
200 self.CanvasRange.SetStringSelection(TIME_RANGE_VALUES[0][0]) |
205 self.CanvasRange.SetStringSelection(TIME_RANGE_VALUES[0][0]) |
201 self.CurrentRange = TIME_RANGE_VALUES[0][1] / self.Ticktime |
206 self.CurrentRange = TIME_RANGE_VALUES[0][1] / self.Ticktime |
202 |
207 |
203 def RefreshView(self, force=True): |
208 def RefreshView(self, force=True): |
204 self.Freeze() |
209 self.Freeze() |
205 if force or self.CurrentValue + self.CurrentRange == len(self.Datas) or self.CurrentValue + len(self.Datas) < self.CurrentRange: |
210 if force or not self.Fixed: |
206 var_name = self.InstancePath.split(".")[-1] |
211 var_name = self.InstancePath.split(".")[-1] |
207 |
212 |
208 self.VariableGraphic = plot.PolyLine(self.Datas[self.CurrentValue:self.CurrentValue + self.CurrentRange], |
213 self.VariableGraphic = plot.PolyLine(self.Datas[self.StartValue:self.EndValue + 1], |
209 legend=var_name, colour=colours[0]) |
214 legend=var_name, colour=colours[0]) |
210 self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values")) |
215 self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values")) |
211 datas_length = len(self.Datas) |
216 datas_length = len(self.Datas) |
212 if datas_length > 1: |
217 if datas_length > 1: |
213 start = self.Datas[self.CurrentValue][0] |
218 start = self.Datas[self.StartValue][0] |
214 if self.CurrentValue + self.CurrentRange > datas_length: |
|
215 end = start + (self.Datas[datas_length - 1][0] - start) * self.CurrentRange / (datas_length - self.CurrentValue - 1) |
|
216 else: |
|
217 end = self.Datas[self.CurrentValue + self.CurrentRange - 1][0] |
|
218 else: |
219 else: |
219 start = 0. |
220 start = 0. |
220 end = 25. |
221 self.Canvas.Draw(self.GraphicsObject, xAxis=(start, start + self.CurrentRange)) |
221 self.Canvas.Draw(self.GraphicsObject, xAxis=(start, end)) |
|
222 self.RefreshScrollBar() |
222 self.RefreshScrollBar() |
223 self.Thaw() |
223 self.Thaw() |
224 |
224 |
225 def GetInstancePath(self): |
225 def GetInstancePath(self): |
226 return self.InstancePath |
226 return self.InstancePath |
227 |
227 |
228 def IsViewing(self, tagname): |
228 def IsViewing(self, tagname): |
229 return self.InstancePath == tagname |
229 return self.InstancePath == tagname |
230 |
230 |
|
231 def GetNearestData(self, tick, adjust): |
|
232 ticks = numpy.array(zip(*self.Datas)[0]) |
|
233 new_cursor = numpy.argmin(abs(ticks - tick)) |
|
234 if adjust == -1 and ticks[new_cursor] > tick and new_cursor > 0: |
|
235 new_cursor -= 1 |
|
236 elif adjust == 1 and ticks[new_cursor] < tick and new_cursor < len(self.Datas): |
|
237 new_cursor += 1 |
|
238 return new_cursor |
|
239 |
231 def NewValue(self, tick, value, forced=False): |
240 def NewValue(self, tick, value, forced=False): |
232 self.Datas.append((float(tick), {True:1., False:0.}.get(value, float(value)))) |
241 self.Datas.append((float(tick), {True:1., False:0.}.get(value, float(value)))) |
233 if self.CurrentValue + self.CurrentRange == len(self.Datas) - 1: |
242 if not self.Fixed: |
234 self.CurrentValue += 1 |
243 while int(self.Datas[self.StartValue][0]) < tick - self.CurrentRange: |
|
244 self.StartValue += 1 |
|
245 self.EndValue += 1 |
235 self.NewDataAvailable() |
246 self.NewDataAvailable() |
236 |
247 |
237 def RefreshScrollBar(self): |
248 def RefreshScrollBar(self): |
238 self.CanvasPosition.SetScrollbar(self.CurrentValue, self.CurrentRange, len(self.Datas), self.CurrentRange) |
249 if len(self.Datas) > 0: |
|
250 pos = int(self.Datas[self.StartValue][0] - self.Datas[0][0]) |
|
251 range = int(self.Datas[-1][0] - self.Datas[0][0]) |
|
252 else: |
|
253 pos = 0 |
|
254 range = 0 |
|
255 self.CanvasPosition.SetScrollbar(pos, self.CurrentRange, range, self.CurrentRange) |
239 |
256 |
240 def OnRangeChanged(self, event): |
257 def OnRangeChanged(self, event): |
241 old_range = self.CurrentRange |
258 old_range = self.CurrentRange |
242 try: |
259 try: |
243 if self.Ticktime == 0: |
260 if self.Ticktime == 0: |
244 self.CurrentRange = self.RangeValues_dict[self.CanvasRange.GetValue()] |
261 self.CurrentRange = self.RangeValues_dict[self.CanvasRange.GetValue()] |
245 else: |
262 else: |
246 self.CurrentRange = self.RangeValues_dict[self.CanvasRange.GetValue()] / self.Ticktime |
263 self.CurrentRange = self.RangeValues_dict[self.CanvasRange.GetValue()] / self.Ticktime |
247 except ValueError, e: |
264 except ValueError, e: |
248 self.CanvasRange.SetValue(str(self.CurrentRange)) |
265 self.CanvasRange.SetValue(str(self.CurrentRange)) |
249 self.CurrentValue = max(0, min(self.CurrentValue + old_range - self.CurrentRange, |
266 if self.Fixed and self.Datas[-1][0] - self.Datas[0][0] < self.CurrentRange: |
250 len(self.Datas) - self.CurrentRange)) |
267 self.Fixed = False |
251 self.RefreshView() |
268 if self.Fixed: |
|
269 self.StartValue = min(self.StartValue, self.GetNearestData(self.Datas[-1][0] - self.CurrentRange, -1)) |
|
270 self.EndValue = self.GetNearestData(self.StartValue + self.CurrentRange, 1) |
|
271 else: |
|
272 self.StartValue = self.GetNearestData(self.Datas[-1][0] - self.CurrentRange - 1, -1) |
|
273 self.EndValue = len(self.Datas) - 1 |
|
274 self.NewDataAvailable(True) |
252 event.Skip() |
275 event.Skip() |
253 |
276 |
254 def OnPositionChanging(self, event): |
277 def OnPositionChanging(self, event): |
255 self.CurrentValue = event.GetPosition() |
278 self.StartValue = self.GetNearestData(self.Datas[0][0] + event.GetPosition(), -1) |
256 self.RefreshView() |
279 self.EndValue = self.GetNearestData(self.Datas[self.StartValue][0] + self.CurrentRange, 1) |
|
280 self.Fixed = True |
|
281 self.NewDataAvailable(True) |
257 event.Skip() |
282 event.Skip() |
258 |
283 |
259 def OnResetButton(self, event): |
284 def OnResetButton(self, event): |
260 self.ResetView() |
285 self.Fixed = False |
|
286 self.ResteView() |
261 event.Skip() |
287 event.Skip() |
262 |
288 |
263 def OnCurrentButton(self, event): |
289 def OnCurrentButton(self, event): |
264 self.CurrentValue = max(0, len(self.Datas) - self.CurrentRange) |
290 self.StartValue = self.GetNearestData(self.Datas[-1][0] - self.CurrentRange, -1) |
265 self.RefreshView() |
291 self.EndValue = self.GetNearestData(self.Datas[self.StartValue][0] + self.CurrentRange, 1) |
266 event.Skip() |
292 self.Fixed = False |
267 |
293 self.NewDataAvailable(True) |
|
294 event.Skip() |
|
295 |