Fixed wrong time scale in debug graph display when some samples are missed
authorlaurent
Wed, 15 Feb 2012 00:25:05 +0100
changeset 642 f2325ebd67f4
parent 641 e9295622ce9b
child 643 941eda65db7a
Fixed wrong time scale in debug graph display when some samples are missed
GraphicViewer.py
--- a/GraphicViewer.py	Tue Feb 07 19:12:25 2012 +0100
+++ b/GraphicViewer.py	Wed Feb 15 00:25:05 2012 +0100
@@ -24,6 +24,7 @@
 
 import wx
 import wx.lib.plot as plot
+import numpy
 from graphics.GraphicCommons import DebugViewer
 from controls import EditorPanel
 
@@ -156,7 +157,9 @@
         self.RangeValues = None
         
         self.Datas = []
-        self.CurrentValue = 0
+        self.StartValue = 0
+        self.EndValue = 0
+        self.Fixed = False
         self.Ticktime = self.DataProducer.GetTicktime()
         self.RefreshCanvasRange()
         
@@ -173,13 +176,15 @@
     
     def ResetView(self):
         self.Datas = []
-        self.CurrentValue = 0
+        self.StartValue = 0
+        self.EndValue = 0
+        self.Fixed = False
         self.Ticktime = self.DataProducer.GetTicktime()
         self.RefreshCanvasRange()
         self.RefreshView()
     
-    def RefreshNewData(self):
-        self.RefreshView(False)
+    def RefreshNewData(self, *args, **kwargs):
+        self.RefreshView(*args, **kwargs)
         DebugViewer.RefreshNewData(self)
     
     def RefreshCanvasRange(self):
@@ -202,23 +207,18 @@
         
     def RefreshView(self, force=True):
         self.Freeze()
-        if force or self.CurrentValue + self.CurrentRange == len(self.Datas) or self.CurrentValue + len(self.Datas) < self.CurrentRange:
+        if force or not self.Fixed:
             var_name = self.InstancePath.split(".")[-1]
             
-            self.VariableGraphic = plot.PolyLine(self.Datas[self.CurrentValue:self.CurrentValue + self.CurrentRange], 
+            self.VariableGraphic = plot.PolyLine(self.Datas[self.StartValue:self.EndValue + 1], 
                                                  legend=var_name, colour=colours[0])
             self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values"))
             datas_length = len(self.Datas)
             if datas_length > 1:
-                start = self.Datas[self.CurrentValue][0]
-                if self.CurrentValue + self.CurrentRange > datas_length:
-                    end = start + (self.Datas[datas_length - 1][0] - start) * self.CurrentRange / (datas_length - self.CurrentValue - 1)
-                else:
-                    end = self.Datas[self.CurrentValue + self.CurrentRange - 1][0]
+                start = self.Datas[self.StartValue][0]
             else:
                 start = 0.
-                end = 25.
-            self.Canvas.Draw(self.GraphicsObject, xAxis=(start, end))
+            self.Canvas.Draw(self.GraphicsObject, xAxis=(start, start + self.CurrentRange))
         self.RefreshScrollBar()
         self.Thaw()
     
@@ -228,14 +228,31 @@
     def IsViewing(self, tagname):
         return self.InstancePath == tagname
     
+    def GetNearestData(self, tick, adjust):
+        ticks = numpy.array(zip(*self.Datas)[0])
+        new_cursor = numpy.argmin(abs(ticks - tick))
+        if adjust == -1 and ticks[new_cursor] > tick and new_cursor > 0:
+            new_cursor -= 1
+        elif adjust == 1 and ticks[new_cursor] < tick and new_cursor < len(self.Datas):
+            new_cursor += 1
+        return new_cursor
+    
     def NewValue(self, tick, value, forced=False):
         self.Datas.append((float(tick), {True:1., False:0.}.get(value, float(value))))
-        if self.CurrentValue + self.CurrentRange == len(self.Datas) - 1:
-            self.CurrentValue += 1
+        if not self.Fixed:
+            while int(self.Datas[self.StartValue][0]) < tick - self.CurrentRange:
+                self.StartValue += 1
+            self.EndValue += 1
         self.NewDataAvailable()
     
     def RefreshScrollBar(self):
-        self.CanvasPosition.SetScrollbar(self.CurrentValue, self.CurrentRange, len(self.Datas), self.CurrentRange)
+        if len(self.Datas) > 0:
+            pos = int(self.Datas[self.StartValue][0] - self.Datas[0][0])
+            range = int(self.Datas[-1][0] - self.Datas[0][0])
+        else:
+            pos = 0
+            range = 0
+        self.CanvasPosition.SetScrollbar(pos, self.CurrentRange, range, self.CurrentRange)
 
     def OnRangeChanged(self, event):
         old_range = self.CurrentRange
@@ -246,22 +263,33 @@
                 self.CurrentRange = self.RangeValues_dict[self.CanvasRange.GetValue()] / self.Ticktime
         except ValueError, e:
             self.CanvasRange.SetValue(str(self.CurrentRange))
-        self.CurrentValue = max(0, min(self.CurrentValue + old_range - self.CurrentRange, 
-                                       len(self.Datas) - self.CurrentRange))
-        self.RefreshView()
+        if self.Fixed and self.Datas[-1][0] - self.Datas[0][0] < self.CurrentRange:
+            self.Fixed = False
+        if self.Fixed:
+            self.StartValue = min(self.StartValue, self.GetNearestData(self.Datas[-1][0] - self.CurrentRange, -1))
+            self.EndValue = self.GetNearestData(self.StartValue + self.CurrentRange, 1)
+        else:
+            self.StartValue = self.GetNearestData(self.Datas[-1][0] - self.CurrentRange - 1, -1)
+            self.EndValue = len(self.Datas) - 1
+        self.NewDataAvailable(True)
         event.Skip()
     
     def OnPositionChanging(self, event):
-        self.CurrentValue = event.GetPosition()
-        self.RefreshView()
+        self.StartValue = self.GetNearestData(self.Datas[0][0] + event.GetPosition(), -1)
+        self.EndValue = self.GetNearestData(self.Datas[self.StartValue][0] + self.CurrentRange, 1)
+        self.Fixed = True
+        self.NewDataAvailable(True)
         event.Skip()
 
     def OnResetButton(self, event):
-        self.ResetView()
+        self.Fixed = False
+        self.ResteView()
         event.Skip()
 
     def OnCurrentButton(self, event):
-        self.CurrentValue = max(0, len(self.Datas) - self.CurrentRange)
-        self.RefreshView()
-        event.Skip()
-
+        self.StartValue = self.GetNearestData(self.Datas[-1][0] - self.CurrentRange, -1)
+        self.EndValue = self.GetNearestData(self.Datas[self.StartValue][0] + self.CurrentRange, 1)
+        self.Fixed = False
+        self.NewDataAvailable(True)
+        event.Skip()
+