From 6970b7890c3314d83db4b68196f1278620e7b5ba Mon Sep 17 00:00:00 2001
From: Mark Watkins <jedimark@users.sourceforge.net>
Date: Mon, 6 Jun 2011 13:37:31 +1000
Subject: [PATCH] Added SkipZeroData graph data type for cleaning up graphs
 that drop to zero during errors (Like Pulse & SPO2)

---
 Projects/CodeBlocks/SleepyHead.depend |  6 +-
 src/SleepyHeadMain.cpp                | 12 ++--
 src/graphs/graph.cpp                  | 86 +++++++++++++++++++++++++--
 src/graphs/graph.h                    | 12 ++++
 4 files changed, 102 insertions(+), 14 deletions(-)

diff --git a/Projects/CodeBlocks/SleepyHead.depend b/Projects/CodeBlocks/SleepyHead.depend
index cf95bd42..a01cc05b 100644
--- a/Projects/CodeBlocks/SleepyHead.depend
+++ b/Projects/CodeBlocks/SleepyHead.depend
@@ -8291,7 +8291,7 @@
 	<map>
 	"tinyxml/tinyxml.h"
 
-1307290670 /home/mark/projects/git/sleepyhead/src/graphs/graph.h
+1307330909 /home/mark/projects/git/sleepyhead/src/graphs/graph.h
 	<sleeplib/machine.h>
 	<list>
 
@@ -8312,7 +8312,7 @@
 	"preferences.h"
 	"tinyxml/tinyxml.h"
 
-1307292874 source:/home/mark/projects/git/sleepyhead/src/SleepyHeadMain.cpp
+1307331240 source:/home/mark/projects/git/sleepyhead/src/SleepyHeadMain.cpp
 	"wx_pch.h"
 	"version.h"
 	<wx/app.h>
@@ -8331,7 +8331,7 @@
 	"sleeplib/profiles.h"
 	"sleeplib/machine_loader.h"
 
-1307290767 source:/home/mark/projects/git/sleepyhead/src/graphs/graph.cpp
+1307331318 source:/home/mark/projects/git/sleepyhead/src/graphs/graph.cpp
 	<wx/settings.h>
 	<wx/dcbuffer.h>
 	<wx/log.h>
diff --git a/src/SleepyHeadMain.cpp b/src/SleepyHeadMain.cpp
index 5a16a247..79d1f167 100644
--- a/src/SleepyHeadMain.cpp
+++ b/src/SleepyHeadMain.cpp
@@ -576,11 +576,7 @@ Daily::Daily(wxWindow *win,Profile *p)
     l->color.push_back(wxGREEN2);
     G_AHI->AddLayer(l);
 
-    AddCPAPData(leakdata=new PressureData(CPAP_Leak,0));
-    //leakdata->ForceMinY(0);
-    //leakdata->ForceMaxY(120);
-
-    AddOXIData(pulse=new PressureData(OXI_Pulse,0,32768));
+    AddOXIData(pulse=new SkipZeroData(OXI_Pulse,0,32768));
     pulse->ForceMinY(40);
     pulse->ForceMaxY(120);
 
@@ -588,7 +584,7 @@ Daily::Daily(wxWindow *win,Profile *p)
     PULSE->AddLayer(new gLineChart(pulse,wxRED,32768,false,false,true));
     PULSE->AddLayer(new gXAxis(wxBLACK));
 
-    AddOXIData(spo2=new PressureData(OXI_SPO2,0,32768));
+    AddOXIData(spo2=new SkipZeroData(OXI_SPO2,0,32768));
     spo2->ForceMinY(60);
     spo2->ForceMaxY(100);
     SPO2=new gGraphWindow(ScrolledWindow,-1,wxT("SpO2"),wxPoint(0,0), wxSize(600,130), wxNO_BORDER);
@@ -597,6 +593,10 @@ Daily::Daily(wxWindow *win,Profile *p)
     SPO2->LinkZoom(PULSE);
     PULSE->LinkZoom(SPO2);
 
+
+    AddCPAPData(leakdata=new PressureData(CPAP_Leak,0));
+    //leakdata->ForceMinY(0);
+    //leakdata->ForceMaxY(120);
     LEAK=new gGraphWindow(ScrolledWindow,-1,wxT("Mask Leaks"),wxPoint(0,0), wxSize(600,130), wxNO_BORDER);
     LEAK->AddLayer(new gLineChart(leakdata,wxPURPLE,4096,false,false,true));
     LEAK->AddLayer(new gXAxis(wxBLACK));
diff --git a/src/graphs/graph.cpp b/src/graphs/graph.cpp
index 4477587e..73041f8c 100644
--- a/src/graphs/graph.cpp
+++ b/src/graphs/graph.cpp
@@ -1601,6 +1601,87 @@ void FlowData::Reload(Day *day)
     m_ready=true;
     //graph->Refresh(false);
 }
+SkipZeroData::SkipZeroData(MachineCode _code,int _field,int _size)
+:gPointData(_size),code(_code),field(_field)
+{
+}
+SkipZeroData::~SkipZeroData()
+{
+}
+void SkipZeroData::Reload(Day *day)
+{
+        vc=0;
+    if (!day) {
+        m_ready=false;
+        return;
+    }
+
+    min_x=day->first().GetMJD();
+    max_x=day->last().GetMJD();
+    assert(min_x<max_x);
+    min_y=max_y=0;
+    int tt=0;
+    bool first=true;
+    EventDataType lastp;
+    for (vector<Session *>::iterator s=day->begin();s!=day->end(); s++) {
+        if ((*s)->events.find(code)==(*s)->events.end()) continue;
+        if (vc>=(int)point.size()) {
+            AddSegment(max_points);
+        }
+
+        int t=0;
+        EventDataType p; //,lastp=-1;
+        for (vector<Event *>::iterator ev=(*s)->events[code].begin(); ev!=(*s)->events[code].end(); ev++) {
+            p=(*(*ev))[field];
+            if (p!=0) {
+                wxRealPoint r((*ev)->time().GetMJD(),p);
+                point[vc][t++]=r;
+                assert(t<max_points);
+                if (first) {
+                    max_y=min_y=r.y;
+                    first=false;
+                } else {
+                    if (r.y<min_y) min_y=r.y;
+                    if (r.y>max_y) max_y=r.y;
+                }
+            } else {
+                if (p!=lastp) { // There really should not be consecutive zeros.. just in case..
+                    np[vc]=t;
+                    tt+=t;
+                    t=0;
+                    vc++;
+                    if (vc>=(int)point.size()) {
+                        AddSegment(max_points);
+                    }
+                }
+            }
+            lastp=p;
+        }
+        np[vc]=t;
+        tt+=t;
+        vc++;
+
+    }
+    if (tt>0) {
+        min_y=floor(min_y);
+        max_y=ceil(max_y+1);
+        if (min_y>1) min_y-=1;
+    }
+
+    //}
+    if (force_min_y!=force_max_y) {
+        min_y=force_min_y;
+        max_y=force_max_y;
+    }
+
+
+    real_min_x=min_x;
+    real_min_y=min_y;
+    real_max_x=max_x;
+    real_max_y=max_y;
+    m_ready=true;
+
+}
 
 PressureData::PressureData(MachineCode _code,int _field,int _size)
 :gPointData(_size),code(_code),field(_field)
@@ -1633,11 +1714,6 @@ void PressureData::Reload(Day *day)
         EventDataType p; //,lastp=-1;
         for (vector<Event *>::iterator ev=(*s)->events[code].begin(); ev!=(*s)->events[code].end(); ev++) {
             p=(*(*ev))[field];
-            /*if (lastp>=0) {
-                wxRealPoint r2((*ev)->time().GetMJD(),lastp);
-                point[vc][t++]=r2;
-                assert(t<max_points);
-            } */
             wxRealPoint r((*ev)->time().GetMJD(),p);
             point[vc][t++]=r;
             assert(t<max_points);
diff --git a/src/graphs/graph.h b/src/graphs/graph.h
index d6ab2dfa..0938a100 100644
--- a/src/graphs/graph.h
+++ b/src/graphs/graph.h
@@ -476,6 +476,18 @@ protected:
     int field;
 };
 
+class SkipZeroData:public gPointData
+{
+public:
+    SkipZeroData(MachineCode _code,int _field=0,int _size=4096);
+    virtual ~SkipZeroData();
+    virtual void Reload(Day *day=NULL);
+protected:
+    MachineCode code;
+    int field;
+};
+
+
 class AHIData:public gPointData
 {
 public: