GraphicViewer.py
changeset 642 f2325ebd67f4
parent 640 c32c169b8f63
child 648 95d165193770
equal deleted inserted replaced
641:e9295622ce9b 642:f2325ebd67f4
    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']
   154         
   155         
   155         self.InstancePath = instancepath
   156         self.InstancePath = instancepath
   156         self.RangeValues = None
   157         self.RangeValues = None
   157         
   158         
   158         self.Datas = []
   159         self.Datas = []
   159         self.CurrentValue = 0
   160         self.StartValue = 0
       
   161         self.EndValue = 0
       
   162         self.Fixed = False
   160         self.Ticktime = self.DataProducer.GetTicktime()
   163         self.Ticktime = self.DataProducer.GetTicktime()
   161         self.RefreshCanvasRange()
   164         self.RefreshCanvasRange()
   162         
   165         
   163         self.AddDataConsumer(self.InstancePath.upper(), self)
   166         self.AddDataConsumer(self.InstancePath.upper(), self)
   164     
   167     
   171             return "..." + self.InstancePath[-12:]
   174             return "..." + self.InstancePath[-12:]
   172         return self.InstancePath
   175         return self.InstancePath
   173     
   176     
   174     def ResetView(self):
   177     def ResetView(self):
   175         self.Datas = []
   178         self.Datas = []
   176         self.CurrentValue = 0
   179         self.StartValue = 0
       
   180         self.EndValue = 0
       
   181         self.Fixed = False
   177         self.Ticktime = self.DataProducer.GetTicktime()
   182         self.Ticktime = self.DataProducer.GetTicktime()
   178         self.RefreshCanvasRange()
   183         self.RefreshCanvasRange()
   179         self.RefreshView()
   184         self.RefreshView()
   180     
   185     
   181     def RefreshNewData(self):
   186     def RefreshNewData(self, *args, **kwargs):
   182         self.RefreshView(False)
   187         self.RefreshView(*args, **kwargs)
   183         DebugViewer.RefreshNewData(self)
   188         DebugViewer.RefreshNewData(self)
   184     
   189     
   185     def RefreshCanvasRange(self):
   190     def RefreshCanvasRange(self):
   186         if self.Ticktime == 0 and self.RangeValues != RANGE_VALUES:
   191         if self.Ticktime == 0 and self.RangeValues != RANGE_VALUES:
   187             self.RangeValues = RANGE_VALUES
   192             self.RangeValues = RANGE_VALUES
   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