mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-05 18:50:44 +00:00
Better 90% calculations, and related day cache implementation
This commit is contained in:
parent
51333ff8e9
commit
a8aa7753cb
120
SleepLib/day.cpp
120
SleepLib/day.cpp
@ -128,23 +128,121 @@ EventDataType Day::settings_wavg(ChannelID code)
|
||||
return (s1/s2);
|
||||
|
||||
}
|
||||
EventDataType Day::p90(ChannelID code) // The "average" p90.. this needs fixing.
|
||||
EventDataType Day::percentile(ChannelID code,EventDataType percentile)
|
||||
{
|
||||
double val=0;
|
||||
// Cache this?
|
||||
int cnt=0;
|
||||
// Cache this calculation
|
||||
|
||||
|
||||
//if (percentile>=1) return 0; // probably better to crash and burn.
|
||||
|
||||
QVector<Session *>::iterator s;
|
||||
|
||||
// Don't assume sessions are in order.
|
||||
QVector<EventDataType> ar;
|
||||
for (s=sessions.begin();s!=sessions.end();s++) {
|
||||
Session & sess=*(*s);
|
||||
if (sess.m_90p.contains(code)) {
|
||||
val+=sess.p90(code);
|
||||
cnt++;
|
||||
QHash<ChannelID,QVector<EventList *> >::iterator ei=sess.eventlist.find(code);
|
||||
|
||||
if (ei==sess.eventlist.end())
|
||||
continue;
|
||||
for (int e=0;e<ei.value().size();e++) {
|
||||
EventList *ev=ei.value()[e];
|
||||
//if ()
|
||||
for (unsigned j=0;j<ev->count();j++) {
|
||||
ar.push_back(ev->data(j));
|
||||
}
|
||||
}
|
||||
if (cnt==0) return 0;
|
||||
return EventDataType(val/float(cnt));
|
||||
}
|
||||
int size=ar.size();
|
||||
if (!size)
|
||||
return 0;
|
||||
size--;
|
||||
qSort(ar);
|
||||
int p=EventDataType(size)*percentile;
|
||||
float p2=EventDataType(size)*percentile;
|
||||
float diff=p2-p;
|
||||
EventDataType val=ar[p];
|
||||
if (diff>0) {
|
||||
int s=p+1;
|
||||
if (s>size-1) s=size-1;
|
||||
EventDataType v2=ar[s];
|
||||
EventDataType v3=v2-val;
|
||||
if (v3>0) {
|
||||
val+=v3*diff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
EventDataType Day::p90(ChannelID code) // The "average" p90.. this needs fixing.
|
||||
{
|
||||
int size=sessions.size();
|
||||
|
||||
if (size==0) return 0;
|
||||
else if (size==1) return sessions[0]->p90(code);
|
||||
|
||||
QHash<ChannelID,EventDataType>::iterator i=m_p90.find(code);
|
||||
if (i!=m_p90.end())
|
||||
return i.value();
|
||||
|
||||
|
||||
QVector<Session *>::iterator s;
|
||||
|
||||
// Don't assume sessions are in order.
|
||||
|
||||
unsigned cnt=0,c;
|
||||
EventDataType p,tmp;
|
||||
|
||||
QMap<EventDataType, unsigned> pmap;
|
||||
QMap<EventDataType, float> tmap;
|
||||
QMap<EventDataType, unsigned>::iterator pi;
|
||||
for (s=sessions.begin();s!=sessions.end();s++) {
|
||||
Session & sess=*(*s);
|
||||
c=sess.count(code);
|
||||
if (c>0) {
|
||||
cnt+=c;
|
||||
p=sess.p90(code); //percentile(code,0.9);
|
||||
if (!pmap.contains(p)) {
|
||||
pmap[p]=c;
|
||||
tmap[p]=sess.hours();
|
||||
} else {
|
||||
pmap[p]+=c;
|
||||
tmap[p]+=sess.hours();
|
||||
}
|
||||
}
|
||||
}
|
||||
EventDataType val;
|
||||
size=pmap.size();
|
||||
if (!size) {
|
||||
m_p90[code]=val=0;
|
||||
return val;
|
||||
} else if (size==1) {
|
||||
m_p90[code]=val=pmap.begin().key();
|
||||
return val;
|
||||
}
|
||||
|
||||
OpenEvents();
|
||||
EventDataType realp90=percentile(code,0.9);
|
||||
|
||||
val=realp90;
|
||||
/*double s0=0,s1=0,s2=0,s3=0;
|
||||
|
||||
for (pi=pmap.begin();pi!=pmap.end();pi++) {
|
||||
s2=tmap[pi.key()];
|
||||
s3=pi.value();
|
||||
s0+=pi.key() * s3 * s2;
|
||||
s1+=s3*s2;
|
||||
}
|
||||
if (s1==0)
|
||||
return 0;
|
||||
|
||||
val=s0/s1;
|
||||
qDebug() << first() << code << realp90 << val; */
|
||||
|
||||
m_p90[code]=val;
|
||||
return val;
|
||||
}
|
||||
|
||||
EventDataType Day::avg(ChannelID code)
|
||||
@ -211,7 +309,7 @@ qint64 Day::total_time()
|
||||
}
|
||||
return d_totaltime;
|
||||
}
|
||||
EventDataType Day::percentile(ChannelID code,double percent)
|
||||
/*EventDataType Day::percentile(ChannelID code,double percent)
|
||||
{
|
||||
double val=0;
|
||||
int cnt=0;
|
||||
@ -226,7 +324,7 @@ EventDataType Day::percentile(ChannelID code,double percent)
|
||||
if (cnt==0) return 0;
|
||||
return EventDataType(val/cnt);
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
qint64 Day::first(ChannelID code)
|
||||
{
|
||||
|
@ -36,10 +36,13 @@ public:
|
||||
EventDataType avg(ChannelID code);
|
||||
EventDataType sum(ChannelID code);
|
||||
EventDataType wavg(ChannelID code);
|
||||
EventDataType percentile(ChannelID code,EventDataType percentile);
|
||||
|
||||
bool hasData(ChannelID code, SummaryType type);
|
||||
|
||||
EventDataType percentile(ChannelID mc,double percent);
|
||||
QHash<ChannelID, EventDataType> m_p90; // 90% cache
|
||||
|
||||
//EventDataType percentile(ChannelID mc,double percent);
|
||||
|
||||
// Note, the following convert to doubles without considering the consequences fully.
|
||||
EventDataType settings_avg(ChannelID code);
|
||||
|
@ -165,7 +165,7 @@ const QString Preferences::Get(QString name)
|
||||
} else if (ref.toLower()=="user") {
|
||||
temp+=getUserName();
|
||||
} else if (ref.toLower()=="sep") { // redundant in QT
|
||||
temp+="/";
|
||||
temp+=QDir::separator();
|
||||
} else {
|
||||
temp+=Get(ref);
|
||||
}
|
||||
|
@ -18,6 +18,10 @@ License: GPL
|
||||
#include "machine.h"
|
||||
#include "machine_loader.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include "mainwindow.h"
|
||||
|
||||
extern MainWindow * mainwin;
|
||||
Preferences *p_pref;
|
||||
Preferences *p_layout;
|
||||
Profile * p_profile;
|
||||
@ -46,6 +50,48 @@ Profile::Profile(QString path)
|
||||
|
||||
Profile::~Profile()
|
||||
{
|
||||
QMap<QDate,QList<Day *> >::iterator di;
|
||||
QHash<MachineID,QMap<QDate,QHash<ChannelID, EventDataType> > > cache;
|
||||
|
||||
QHash<MachineID,QMap<QDate,QHash<ChannelID, EventDataType> > >::iterator ci;
|
||||
for (di=daylist.begin();di!=daylist.end();di++) {
|
||||
QDate date=di.key();
|
||||
for (QList<Day *>::iterator d=di.value().begin();d!=di.value().end();d++) {
|
||||
Day *day=*d;
|
||||
MachineID mach=day->machine->id();
|
||||
QHash<ChannelID, EventDataType>::iterator i;
|
||||
|
||||
for (i=day->m_p90.begin();i!=day->m_p90.end();i++) {
|
||||
cache[mach][date][i.key()]=day->m_p90[i.key()];
|
||||
}
|
||||
}
|
||||
}
|
||||
QString filename=Get("{DataFolder}")+QDir::separator()+"cache.day";
|
||||
QFile f(filename);
|
||||
if (f.open(QFile::WriteOnly)) {
|
||||
QDataStream out(&f);
|
||||
out.setVersion(QDataStream::Qt_4_6);
|
||||
out.setByteOrder(QDataStream::LittleEndian);
|
||||
quint16 size=cache.size();
|
||||
out << size;
|
||||
for (ci=cache.begin();ci!=cache.end();ci++) {
|
||||
quint32 mid=ci.key();
|
||||
out << mid;
|
||||
out << ci.value();
|
||||
}
|
||||
/*quint16 size=cache.size();
|
||||
out << size;
|
||||
QMap<QDate,QHash<ChannelID, EventDataType> >::iterator i;
|
||||
for (i=cache.begin();i!=cache.end();i++) {
|
||||
QDate a=i.key();
|
||||
out << a;
|
||||
}
|
||||
for (i=cache.begin();i!=cache.end();i++) {
|
||||
out << cache[i.key()];
|
||||
}*/
|
||||
f.close();
|
||||
}
|
||||
|
||||
for (QHash<MachineID,Machine *>::iterator i=machlist.begin(); i!=machlist.end(); i++) {
|
||||
delete i.value();
|
||||
}
|
||||
@ -72,6 +118,31 @@ void Profile::DataFormatError(Machine *m)
|
||||
}
|
||||
void Profile::LoadMachineData()
|
||||
{
|
||||
QHash<MachineID,QMap<QDate,QHash<ChannelID, EventDataType> > > cache;
|
||||
|
||||
QString filename=Get("{DataFolder}")+QDir::separator()+"cache.day";
|
||||
QFile f(filename);
|
||||
if (f.exists(filename) && (f.open(QFile::ReadOnly))) {
|
||||
QDataStream in(&f);
|
||||
in.setVersion(QDataStream::Qt_4_6);
|
||||
in.setByteOrder(QDataStream::LittleEndian);
|
||||
|
||||
quint16 size;
|
||||
quint32 mid;
|
||||
in >> size;
|
||||
for (int i=0;i<size;i++) {
|
||||
in >> mid;
|
||||
in >> cache[mid];
|
||||
}
|
||||
PROFILE["RebuildCache"]=false;
|
||||
} else {
|
||||
if (mainwin) {
|
||||
mainwin->Notify("Caching session data, this may take a little while.");
|
||||
PROFILE["RebuildCache"]=true;
|
||||
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
for (QHash<MachineID,Machine *>::iterator i=machlist.begin(); i!=machlist.end(); i++) {
|
||||
Machine *m=i.value();
|
||||
|
||||
@ -101,6 +172,18 @@ void Profile::LoadMachineData()
|
||||
m->Load();
|
||||
}
|
||||
}
|
||||
for (QMap<QDate,QList<Day *> >::iterator di=daylist.begin();di!=daylist.end();di++) {
|
||||
for (QList<Day *>::iterator d=di.value().begin();d!=di.value().end();d++) {
|
||||
Day *day=*d;
|
||||
MachineID mid=day->machine->id();
|
||||
if (cache.contains(mid)) {
|
||||
if (cache[mid].contains(di.key())) {
|
||||
day->m_p90=cache[mid][di.key()];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load Day Cache here..
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -882,7 +882,7 @@ EventDataType Session::wavg(ChannelID id)
|
||||
|
||||
for (int i=0;i<size;i++) {
|
||||
if (!evec[i]->count()) continue;
|
||||
lastval=evec[i]->raw(0);
|
||||
/*lastval=evec[i]->raw(0);
|
||||
lasttime=evec[i]->time(0);
|
||||
for (quint32 j=1;j<evec[i]->count();j++) {
|
||||
val=evec[i]->raw(j);
|
||||
@ -894,19 +894,44 @@ EventDataType Session::wavg(ChannelID id)
|
||||
} else vtime[lastval]=td;
|
||||
lasttime=time;
|
||||
lastval=val;
|
||||
}*/
|
||||
|
||||
time=evec[i]->time(0)/1000L;
|
||||
val=evec[i]->raw(0);
|
||||
for (quint32 j=1;j<evec[i]->count();j++) {
|
||||
lastval=val;
|
||||
lasttime=time;
|
||||
val=evec[i]->raw(j);
|
||||
time=evec[i]->time(j)/1000L;
|
||||
td=(time-lasttime);
|
||||
if (vtime.contains(lastval)) {
|
||||
vtime[lastval]+=td;
|
||||
} else vtime[lastval]=td;
|
||||
}
|
||||
if (lasttime>0) {
|
||||
td=last()-time;
|
||||
if (vtime.contains(val)) {
|
||||
vtime[val]+=td;
|
||||
} else vtime[val]=td;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
qint64 s0=0,s1=0,s2=0; // 32bit may all be thats needed here..
|
||||
if (id==CPAP_Snore) {
|
||||
int i=5;
|
||||
}
|
||||
qint64 s0=0,s1=0,s2=0,s3=0; // 32bit may all be thats needed here..
|
||||
for (QHash<EventStoreType,quint32>::iterator i=vtime.begin(); i!=vtime.end(); i++) {
|
||||
s0=i.value();
|
||||
s1+=i.key()*s0;
|
||||
s3=i.key()+1;
|
||||
s1+=s3*s0;
|
||||
s2+=s0;
|
||||
}
|
||||
if (s2==0) {
|
||||
return m_wavg[id]=0;
|
||||
}
|
||||
double j=double(s1)/double(s2);
|
||||
j-=1;
|
||||
EventDataType v=j*gain;
|
||||
if (v>32768*gain) {
|
||||
v=0;
|
||||
|
38
daily.cpp
38
daily.cpp
@ -463,35 +463,43 @@ void Daily::UpdateEventsTree(QTreeWidget *tree,Day *day)
|
||||
|
||||
void Daily::UpdateCalendarDay(QDate date)
|
||||
{
|
||||
QTextCharFormat bold;
|
||||
QTextCharFormat cpapcol;
|
||||
QTextCharFormat normal;
|
||||
QTextCharFormat nodata;
|
||||
QTextCharFormat cpaponly;
|
||||
QTextCharFormat cpapjour;
|
||||
QTextCharFormat oxiday;
|
||||
QTextCharFormat oxicpap;
|
||||
QTextCharFormat jourday;
|
||||
bold.setForeground(QBrush(QColor("dark blue"), Qt::SolidPattern));
|
||||
bold.setFontWeight(QFont::Bold);
|
||||
cpapcol.setForeground(QBrush(Qt::blue, Qt::SolidPattern));
|
||||
cpapcol.setFontWeight(QFont::Bold);
|
||||
|
||||
cpaponly.setForeground(QBrush(Qt::blue, Qt::SolidPattern));
|
||||
cpaponly.setFontWeight(QFont::Normal);
|
||||
cpapjour.setForeground(QBrush(Qt::blue, Qt::SolidPattern));
|
||||
cpapjour.setFontWeight(QFont::Bold);
|
||||
oxiday.setForeground(QBrush(Qt::red, Qt::SolidPattern));
|
||||
oxiday.setFontWeight(QFont::Bold);
|
||||
oxiday.setFontWeight(QFont::Normal);
|
||||
oxicpap.setForeground(QBrush(Qt::red, Qt::SolidPattern));
|
||||
oxicpap.setFontWeight(QFont::Bold);
|
||||
jourday.setForeground(QBrush(QColor("black"), Qt::SolidPattern));
|
||||
jourday.setFontWeight(QFont::Bold);
|
||||
nodata.setForeground(QBrush(QColor("black"), Qt::SolidPattern));
|
||||
nodata.setFontWeight(QFont::Normal);
|
||||
|
||||
bool hascpap=PROFILE.GetDay(date,MT_CPAP)!=NULL;
|
||||
bool hasoxi=PROFILE.GetDay(date,MT_OXIMETER)!=NULL;
|
||||
bool hasjournal=PROFILE.GetDay(date,MT_JOURNAL)!=NULL;
|
||||
if (hascpap) {
|
||||
if (hasoxi) {
|
||||
ui->calendar->setDateTextFormat(date,oxicpap);
|
||||
} else if (hasjournal) {
|
||||
ui->calendar->setDateTextFormat(date,cpapjour);
|
||||
} else {
|
||||
ui->calendar->setDateTextFormat(date,cpaponly);
|
||||
}
|
||||
} else if (hasoxi) {
|
||||
ui->calendar->setDateTextFormat(date,oxiday);
|
||||
} else if (hasjournal) {
|
||||
ui->calendar->setDateTextFormat(date,jourday);
|
||||
} else {
|
||||
ui->calendar->setDateTextFormat(date,cpapcol);
|
||||
}
|
||||
} else if (PROFILE.GetDay(date)) {
|
||||
ui->calendar->setDateTextFormat(date,bold);
|
||||
} else {
|
||||
ui->calendar->setDateTextFormat(date,normal);
|
||||
ui->calendar->setDateTextFormat(date,nodata);
|
||||
}
|
||||
ui->calendar->setHorizontalHeaderFormat(QCalendarWidget::ShortDayNames);
|
||||
|
||||
@ -588,7 +596,7 @@ void Daily::Load(QDate date)
|
||||
GraphView->findGraph("Plethy")->setGroup(1);
|
||||
mainwin->Notify("Oximetry data exists for this day, however it's timestamps are too different, so the Graphs will not be linked.",3000);
|
||||
} else {
|
||||
mainwin->Notify("Oximetry & CPAP graphs are linked for this day",2000);
|
||||
//mainwin->Notify("Oximetry & CPAP graphs are linked for this day",2000);
|
||||
GraphView->findGraph("Pulse")->setGroup(0);
|
||||
GraphView->findGraph("SpO2")->setGroup(0);
|
||||
GraphView->findGraph("Plethy")->setGroup(0);
|
||||
|
3
main.cpp
3
main.cpp
@ -110,7 +110,7 @@ int main(int argc, char *argv[])
|
||||
QDateTime lastchecked, today=QDateTime::currentDateTime();
|
||||
if (!PREF.Exists("Updates_AutoCheck")) {
|
||||
PREF["Updates_AutoCheck"]=true;
|
||||
PREF["Updates_CheckFrequency"]=3;
|
||||
PREF["Updates_CheckFrequency"]=7;
|
||||
}
|
||||
bool check_updates=false;
|
||||
if (PREF["Updates_AutoCheck"].toBool()) {
|
||||
@ -186,6 +186,7 @@ int main(int argc, char *argv[])
|
||||
PREF["Fonts_Application_Bold"].toBool() ? QFont::Bold : QFont::Normal,
|
||||
PREF["Fonts_Application_Italic"].toBool()));
|
||||
|
||||
qDebug() << "Selected" << QApplication::font().family();
|
||||
qInstallMsgHandler(MyOutputHandler);
|
||||
|
||||
MainWindow w;
|
||||
|
@ -502,8 +502,8 @@ void MainWindow::on_oximetryButton_clicked()
|
||||
|
||||
void MainWindow::CheckForUpdates()
|
||||
{
|
||||
mainwin->Notify("Checking for Updates");
|
||||
on_actionCheck_for_Updates_triggered();
|
||||
QTimer::singleShot(100,this,SLOT(on_actionCheck_for_Updates_triggered()));
|
||||
//on_actionCheck_for_Updates_triggered();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionCheck_for_Updates_triggered()
|
||||
@ -516,6 +516,7 @@ void MainWindow::on_actionCheck_for_Updates_triggered()
|
||||
return;
|
||||
}
|
||||
}
|
||||
mainwin->Notify("Checking for Updates");
|
||||
netmanager->get(QNetworkRequest(QUrl("http://sleepyhead.sourceforge.net/current_version.txt")));
|
||||
}
|
||||
void MainWindow::replyFinished(QNetworkReply * reply)
|
||||
@ -523,7 +524,7 @@ void MainWindow::replyFinished(QNetworkReply * reply)
|
||||
if (reply->error()==QNetworkReply::NoError) {
|
||||
// Wrap this crap in XML/JSON so can do other stuff.
|
||||
if (reply->size()>20) {
|
||||
qDebug() << "Doesn't look like a version file... :(";
|
||||
mainwin->Notify("Update check failed.. Version file on the server is broken.");
|
||||
} else {
|
||||
// check in size
|
||||
QByteArray data=reply->readAll();
|
||||
@ -545,7 +546,7 @@ void MainWindow::replyFinished(QNetworkReply * reply)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Network Error:" << reply->errorString();
|
||||
mainwin->Notify("Couldn't check for updates. The network is down.\n\n("+reply->errorString()+")");
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="welcomePage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
@ -75,7 +75,7 @@ p, li { white-space: pre-wrap; }
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This software has been released freely under the <a href="http://www.gnu.org/copyleft/gpl.html"><span style=" text-decoration: underline; color:#0000ff;">GNU Public License</span></a>, and comes with no warranty, and without ANY claims to fitness for any purpose.</p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Accuracy of any data displayed is not and can not be gauranteed. </p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Accuracy of any data displayed is not and can not be guaranteed. </p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The author will not be held liable for <span style=" text-decoration: underline;">anything</span> related to the use or misuse of this software. </p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
|
||||
|
15
overview.cpp
15
overview.cpp
@ -88,10 +88,10 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
|
||||
|
||||
// The following code (to the closing marker) is crap --->
|
||||
AHI=createGraph("AHI","Apnea\nHypopnea\nIndex");
|
||||
UC=createGraph("Usage","Usage\n(time)");
|
||||
UC=createGraph("Usage","Usage\n(hours)");
|
||||
|
||||
int default_height=PROFILE["GraphHeight"].toInt();
|
||||
US=new gGraph(GraphView,"Session Times","Session Times\n(time)",default_height,0);
|
||||
US=new gGraph(GraphView,"Session Times","Session Times\n(hours)",default_height,0);
|
||||
US->AddLayer(new gYAxisTime(),LayerLeft,gYAxis::Margin);
|
||||
gXAxis *x=new gXAxis();
|
||||
x->setUtcFix(true);
|
||||
@ -112,11 +112,11 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
|
||||
SPO2=createGraph("SpO2","Oxygen Saturation\n(%)");
|
||||
WEIGHT=createGraph("Weight","Weight\n(kg)");
|
||||
BMI=createGraph("BMI","Body\nMass\nIndex");
|
||||
ZOMBIE=createGraph("Zombie","How you felt\n(% awesome)");
|
||||
ZOMBIE=createGraph("Zombie","How you felt\n(0-10)");
|
||||
|
||||
ahihr=new SummaryChart("AHI/Hr",GT_LINE);
|
||||
ahihr->addSlice(CPAP_AHI,QColor("blue"),ST_MAX,true);
|
||||
ahihr->addSlice(CPAP_AHI,QColor("orange"),ST_WAVG,true);
|
||||
ahihr->addSlice(CPAP_AHI,QColor("blue"),ST_MAX,false);
|
||||
ahihr->addSlice(CPAP_AHI,QColor("orange"),ST_WAVG,false);
|
||||
AHIHR->AddLayer(ahihr);
|
||||
|
||||
weight=new SummaryChart("Weight",GT_LINE);
|
||||
@ -251,7 +251,10 @@ void Overview::ReloadGraphs()
|
||||
ui->dateStart->setDate(p_profile->FirstDay());
|
||||
ui->dateEnd->setDate(p_profile->LastDay());
|
||||
GraphView->setDay(NULL);
|
||||
|
||||
if (PROFILE.ExistsAndTrue("RebuildCache")) {
|
||||
PROFILE["RebuildCache"]=false;
|
||||
mainwin->Notify("Cache rebuild complete");
|
||||
}
|
||||
}
|
||||
|
||||
void Overview::RedrawGraphs()
|
||||
|
@ -38,7 +38,7 @@
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>5</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="importTab">
|
||||
<attribute name="title">
|
||||
|
Loading…
Reference in New Issue
Block a user