Overview SummaryChart fixes: min/max settings values, uniform legend color markers, use median not average

This commit is contained in:
Mark Watkins 2012-01-03 15:40:35 +10:00
parent ab09192ceb
commit 23a59d80eb
3 changed files with 125 additions and 95 deletions

View File

@ -60,42 +60,39 @@ void SummaryChart::SetDay(Day * nullday)
m_codes.clear();
m_colors.clear();
m_type.clear();
m_zeros.clear();
//m_zeros.clear();
m_typeval.clear();
if (mode>=MODE_ASV) {
addSlice(CPAP_EPAP,QColor("green"),ST_SETMIN,true);
addSlice(CPAP_EPAP,QColor("green"),ST_SETMIN);
addSlice(CPAP_IPAPLo,QColor("light blue"),ST_SETMIN,true);
addSlice(CPAP_IPAP,QColor("cyan"),ST_PERC,true,0.5);
addSlice(CPAP_IPAP,QColor("dark cyan"),ST_PERC,true,0.95);
//addSlice(CPAP_IPAP,QColor("light blue"),ST_PERC,true,0.95);
addSlice(CPAP_IPAPHi,QColor("blue"),ST_SETMAX,true);
addSlice(CPAP_IPAPLo,QColor("light blue"),ST_SETMIN);
addSlice(CPAP_IPAP,QColor("cyan"),ST_PERC,0.5);
addSlice(CPAP_IPAP,QColor("dark cyan"),ST_PERC,0.95);
//addSlice(CPAP_IPAP,QColor("light blue"),ST_PERC,0.95);
addSlice(CPAP_IPAPHi,QColor("blue"),ST_SETMAX);
} else if (mode>=MODE_BIPAP) {
addSlice(CPAP_EPAP,QColor("green"),ST_SETMIN,true);
addSlice(CPAP_EPAP,QColor("light green"),ST_PERC,true,0.95);
addSlice(CPAP_EPAP,QColor("green"),ST_SETMIN);
addSlice(CPAP_EPAP,QColor("light green"),ST_PERC,0.95);
addSlice(CPAP_IPAP,QColor("light cyan"),ST_WAVG,true);
addSlice(CPAP_IPAP,QColor("light blue"),ST_PERC,true,0.95);
addSlice(CPAP_IPAP,QColor("blue"),ST_SETMAX,true);
addSlice(CPAP_IPAP,QColor("light cyan"),ST_WAVG);
addSlice(CPAP_IPAP,QColor("light blue"),ST_PERC,0.95);
addSlice(CPAP_IPAP,QColor("blue"),ST_SETMAX);
} else if (mode>=MODE_APAP) {
addSlice(CPAP_PressureMin,QColor("orange"),ST_SETMIN,true);
addSlice(CPAP_Pressure,QColor("dark green"),ST_WAVG,true);
addSlice(CPAP_Pressure,QColor("grey"),ST_PERC,true,0.95);
addSlice(CPAP_PressureMax,QColor("red"),ST_SETMAX,true);
addSlice(CPAP_PressureMin,QColor("orange"),ST_SETMIN);
addSlice(CPAP_Pressure,QColor("dark green"),ST_WAVG);
addSlice(CPAP_Pressure,QColor("grey"),ST_PERC,0.95);
addSlice(CPAP_PressureMax,QColor("red"),ST_SETMAX);
} else {
addSlice(CPAP_Pressure,QColor("dark green"),ST_SETWAVG,true);
addSlice(CPAP_Pressure,QColor("dark green"),ST_SETWAVG);
}
}
m_goodcodes.resize(m_codes.size());
for (int i=0;i<m_codes.size();i++) {
m_goodcodes[i]=false;
}
m_fday=0;
qint64 tt,zt;
m_empty=true;
@ -385,14 +382,18 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height)
lastdaygood=true;
for (int i=0;i<numcodes;i++) {
totalcounts[i]=0;
if (m_type[i]==ST_MIN) {
// Set min and max to the opposite largest starting value
if ((m_type[i]==ST_MIN) || (m_type[i]==ST_SETMIN)) {
totalvalues[i]=maxy;
} else if (m_type[i]==ST_MAX) {
} else if ((m_type[i]==ST_MAX) || (m_type[i]==ST_SETMAX)) {
totalvalues[i]=miny;
} else {
totalvalues[i]=0;
}
// Turn off legend display.. It will only display if it's turned back on during draw.
goodcodes[i]=false;
if (!m_goodcodes[i]) continue;
// lastvalues[i]=0;
lastX[i]=px;
@ -455,6 +456,11 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height)
GLuint col2=brighten(col).rgba();
outlines->setColor(Qt::black);
if (d.value().size()>0) {
for (int i=0;i<goodcodes.size();i++) {
goodcodes[i]=true;
}
}
for (j=0;j<d.value().size();j++) {
tmp2=times.value()[j]-miny;
py=top+height-(tmp2*ymult);
@ -491,6 +497,7 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height)
//}
bool good;
SummaryType type;
for (QHash<short,EventDataType>::iterator g=d.value().begin();g!=d.value().end();g++) {
short j=g.key();
if (!j) continue;
@ -499,12 +506,14 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height)
if (!good)
continue;
type=m_type[j];
// code was actually used (to signal the display of the legend summary)
goodcodes[j]=good;
tmp=g.value();
QColor col=m_colors[j];
if (m_type[j]==ST_HOURS) {
if (type==ST_HOURS) {
if (tmp<compliance_hours) {
col=QColor("#f04040");
incompliant++;
@ -516,10 +525,12 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height)
}
//if (!tmp) continue;
if (m_type[j]==ST_MAX) {
if (tmp>totalvalues[j]) totalvalues[j]=tmp;
} else if (m_type[j]==ST_MIN) {
if (tmp<totalvalues[j]) totalvalues[j]=tmp;
if ((type==ST_MAX) || (type==ST_SETMAX)) {
if (totalvalues[j]<tmp)
totalvalues[j]=tmp;
} else if ((type==ST_MIN) || (type==ST_SETMIN)) {
if (totalvalues[j]>tmp)
totalvalues[j]=tmp;
} else {
totalvalues[j]+=tmp*hours;
}
@ -585,16 +596,19 @@ jumpnext:
// Draw Ledgend
px=left+width-3;
py=top-5;
int legendx=px;
QString a,b;
int x,y;
bool ishours=false;
int good=0;
for (int j=0;j<m_codes.size();j++) {
if (!goodcodes[j]) continue;
good++;
SummaryType type=m_type[j];
ChannelID code=m_codes[j];
EventDataType tval=m_typeval[j];
switch(m_type[j]) {
switch(type) {
case ST_WAVG: b="Avg"; break;
case ST_AVG: b="Avg"; break;
case ST_90P: b="90%"; break;
@ -618,13 +632,13 @@ jumpnext:
QString val;
float f=0;
if (totalcounts[j]>0) {
if ((m_type[j]==ST_MIN) || (m_type[j]==ST_MAX)) {
if ((type==ST_MIN) || (type==ST_MAX) || (type==ST_SETMIN) || (type==ST_SETMAX)) {
f=totalvalues[j];
} else {
f=totalvalues[j]/totalcounts[j];
}
}
if (m_type[j]==ST_HOURS) {
if (type==ST_HOURS) {
int h=f;
int m=int(f*60) % 60;
val.sprintf("%02i:%02i",h,m);
@ -633,21 +647,38 @@ jumpnext:
val=QString::number(f,'f',2);
}
a+="="+val;
GetTextExtent(a,x,y);
float wt=20*w.printScaleX();
px-=wt+x;
w.renderText(a,px+wt,py+1);
quads->add(px+wt-y/4-y,py-y,px+wt-y/4,py-y,px+wt-y/4,py+1,px+wt-y/4-y,py+1,m_colors[j].rgba());
//GetTextExtent(a,x,y);
//float wt=20*w.printScaleX();
//px-=wt+x;
//w.renderText(a,px+wt,py+1);
//quads->add(px+wt-y/4-y,py-y,px+wt-y/4,py-y,px+wt-y/4,py+1,px+wt-y/4-y,py+1,m_colors[j].rgba());
//QString text=schema::channel[code].label();
int wid,hi;
GetTextExtent(a,wid,hi);
legendx-=wid;
w.renderText(a,legendx,top-4);
int bw=GetXHeight();
legendx-=bw/2;
int tp=top-5-bw/2;
w.quads()->add(legendx-bw,tp+bw/2,legendx,tp+bw/2,legendx,tp-bw/2,legendx-bw,tp-bw/2,m_colors[j].rgba());
legendx-=hi+bw/2;
//lines->add(px,py,px+20,py,m_colors[j]);
//lines->add(px,py+1,px+20,py+1,m_colors[j]);
}
if (m_graphtype==GT_BAR) {
if ((m_graphtype==GT_BAR) && (good>0)) {
if (m_type.size()>1) {
float val=total_val/float(total_hours);
a=m_label+"="+QString::number(val,'f',2)+" ";
GetTextExtent(a,x,y);
px-=20+x;
w.renderText(a,px+24,py+1);
legendx-=20+x;
w.renderText(a,legendx+24,py+1);
}
}
@ -667,8 +698,8 @@ jumpnext:
}
GetTextExtent(a,x,y);
px-=30+x;
//GetTextExtent(a,x,y);
//legendx-=30+x;
//w.renderText(a,px+24,py+5);
w.renderText(a,left,py+1);
}

View File

@ -38,12 +38,12 @@ class SummaryChart:public Layer
virtual bool isEmpty() { return m_empty; }
//! \brief Adds a layer to the summaryChart (When in Bar mode, it becomes culminative, eg, the AHI chart)
void addSlice(ChannelID code, QColor color, SummaryType type, bool ignore_zeros=false, EventDataType tval=0.00f)
void addSlice(ChannelID code, QColor color, SummaryType type, EventDataType tval=0.00f)
{
m_codes.push_back(code);
m_colors.push_back(color);
m_type.push_back(type);
m_zeros.push_back(ignore_zeros);
//m_zeros.push_back(ignore_zeros);
m_typeval.push_back(tval);
}
@ -63,7 +63,7 @@ class SummaryChart:public Layer
QVector<QColor> m_colors;
QVector<ChannelID> m_codes;
QVector<bool> m_goodcodes;
QVector<bool> m_zeros;
//QVector<bool> m_zeros;
QVector<SummaryType> m_type;
QVector<EventDataType> m_typeval;
QHash<int,QHash<short,EventDataType> > m_values;

View File

@ -118,110 +118,109 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
ZOMBIE=createGraph(tr("Zombie"),tr("How you felt\n(0-10)"));
ahihr=new SummaryChart(tr("AHI/Hr"),GT_LINE);
ahihr->addSlice(CPAP_AHI,QColor("blue"),ST_MAX,false);
ahihr->addSlice(CPAP_AHI,QColor("orange"),ST_WAVG,false);
ahihr->addSlice(CPAP_AHI,QColor("blue"),ST_MAX);
ahihr->addSlice(CPAP_AHI,QColor("orange"),ST_WAVG);
AHIHR->AddLayer(ahihr);
weight=new SummaryChart(STR_TR_Weight,GT_LINE);
weight->setMachineType(MT_JOURNAL);
weight->addSlice(Journal_Weight,QColor("black"),ST_SETAVG,true);
weight->addSlice(Journal_Weight,QColor("black"),ST_SETAVG);
WEIGHT->AddLayer(weight);
bmi=new SummaryChart(STR_TR_BMI,GT_LINE);
bmi->setMachineType(MT_JOURNAL);
bmi->addSlice(Journal_BMI,QColor("dark blue"),ST_SETAVG,true);
bmi->addSlice(Journal_BMI,QColor("dark blue"),ST_SETAVG);
BMI->AddLayer(bmi);
zombie=new SummaryChart(tr("Zombie Meter"),GT_LINE);
zombie->setMachineType(MT_JOURNAL);
zombie->addSlice(Journal_ZombieMeter,QColor("dark red"),ST_SETAVG,true);
zombie->addSlice(Journal_ZombieMeter,QColor("dark red"),ST_SETAVG);
ZOMBIE->AddLayer(zombie);
pulse=new SummaryChart(tr("Pulse Rate"),GT_LINE);
pulse->setMachineType(MT_OXIMETER);
pulse->addSlice(OXI_Pulse,QColor("red"),ST_WAVG,true);
pulse->addSlice(OXI_Pulse,QColor("pink"),ST_MIN,true);
pulse->addSlice(OXI_Pulse,QColor("orange"),ST_MAX,true);
pulse->addSlice(OXI_Pulse,QColor("red"),ST_WAVG);
pulse->addSlice(OXI_Pulse,QColor("pink"),ST_MIN);
pulse->addSlice(OXI_Pulse,QColor("orange"),ST_MAX);
PULSE->AddLayer(pulse);
spo2=new SummaryChart(STR_TR_SpO2,GT_LINE);
spo2->setMachineType(MT_OXIMETER);
spo2->addSlice(OXI_SPO2,QColor("cyan"),ST_WAVG,true);
spo2->addSlice(OXI_SPO2,QColor("light blue"),ST_PERC,true,0.95);
spo2->addSlice(OXI_SPO2,QColor("blue"),ST_MIN,true);
spo2->addSlice(OXI_SPO2,QColor("cyan"),ST_WAVG);
spo2->addSlice(OXI_SPO2,QColor("light blue"),ST_PERC,0.95);
spo2->addSlice(OXI_SPO2,QColor("blue"),ST_MIN);
SPO2->AddLayer(spo2);
uc=new SummaryChart(STR_UNIT_Hours,GT_BAR);
uc->addSlice(NoChannel,QColor("green"),ST_HOURS,true);
uc->addSlice(NoChannel,QColor("green"),ST_HOURS);
UC->AddLayer(uc);
us=new SummaryChart(STR_UNIT_Hours,GT_SESSIONS);
us->addSlice(NoChannel,QColor("dark blue"),ST_HOURS,true);
us->addSlice(NoChannel,QColor("blue"),ST_SESSIONS,true);
us->addSlice(NoChannel,QColor("dark blue"),ST_HOURS);
us->addSlice(NoChannel,QColor("blue"),ST_SESSIONS);
US->AddLayer(us);
ses=new SummaryChart(tr("Sessions"),GT_LINE);
ses->addSlice(NoChannel,QColor("blue"),ST_SESSIONS,true);
ses->addSlice(NoChannel,QColor("blue"),ST_SESSIONS);
SES->AddLayer(ses);
if (PROFILE.general->calculateRDI())
bc=new SummaryChart(tr("RDI"),GT_BAR);
else
bc=new SummaryChart(tr("AHI"),GT_BAR);
bc->addSlice(CPAP_Hypopnea,QColor("blue"),ST_CPH,false);
bc->addSlice(CPAP_Apnea,QColor("dark green"),ST_CPH,false);
bc->addSlice(CPAP_Obstructive,QColor("#40c0ff"),ST_CPH,false);
bc->addSlice(CPAP_ClearAirway,QColor("purple"),ST_CPH,false);
bc->addSlice(CPAP_Hypopnea,QColor("blue"),ST_CPH);
bc->addSlice(CPAP_Apnea,QColor("dark green"),ST_CPH);
bc->addSlice(CPAP_Obstructive,QColor("#40c0ff"),ST_CPH);
bc->addSlice(CPAP_ClearAirway,QColor("purple"),ST_CPH);
if (PROFILE.general->calculateRDI()) {
bc->addSlice(CPAP_RERA,QColor("gold"),ST_CPH,false);
bc->addSlice(CPAP_RERA,QColor("gold"),ST_CPH);
}
AHI->AddLayer(bc);
set=new SummaryChart("",GT_LINE);
//set->addSlice(PRS1_SysOneResistSet,QColor("grey"),ST_SETAVG);
set->addSlice(PRS1_HumidSetting,QColor("blue"),ST_SETWAVG,true);
set->addSlice(CPAP_PresReliefSet,QColor("red"),ST_SETWAVG,true);
//set->addSlice(RMS9_EPRSet,QColor("green"),ST_SETWAVG,true);
//set->addSlice(INTP_SmartFlex,QColor("purple"),ST_SETWAVG,true);
set->addSlice(PRS1_HumidSetting,QColor("blue"),ST_SETWAVG);
set->addSlice(CPAP_PresReliefSet,QColor("red"),ST_SETWAVG);
//set->addSlice(RMS9_EPRSet,QColor("green"),ST_SETWAVG);
//set->addSlice(INTP_SmartFlex,QColor("purple"),ST_SETWAVG);
SET->setRecMinY(0);
SET->setRecMaxY(5);
SET->AddLayer(set);
rr=new SummaryChart(tr("breaths/min"),GT_LINE);
rr->addSlice(CPAP_RespRate,QColor("light blue"),ST_MIN,true);
rr->addSlice(CPAP_RespRate,QColor("light green"),ST_PERC,true,0.95);
rr->addSlice(CPAP_RespRate,QColor("blue"),ST_WAVG,true);
rr->addSlice(CPAP_RespRate,QColor("green"),ST_PERC,true,0.999);
// rr->addSlice(CPAP_RespRate,QColor("green"),ST_MAX,true);
rr->addSlice(CPAP_RespRate,QColor("light blue"),ST_MIN);
rr->addSlice(CPAP_RespRate,QColor("blue"),ST_PERC,0.5);
rr->addSlice(CPAP_RespRate,QColor("light green"),ST_PERC,0.95);
rr->addSlice(CPAP_RespRate,QColor("green"),ST_PERC,0.999);
// rr->addSlice(CPAP_RespRate,QColor("green"),ST_MAX);
RR->AddLayer(rr);
tv=new SummaryChart(tr("L/b"),GT_LINE);
tv->addSlice(CPAP_TidalVolume,QColor("light blue"),ST_MIN,true);
tv->addSlice(CPAP_TidalVolume,QColor("light green"),ST_PERC,true,0.95);
tv->addSlice(CPAP_TidalVolume,QColor("blue"),ST_WAVG,true);
tv->addSlice(CPAP_TidalVolume,QColor("green"),ST_PERC,true,0.999);
tv->addSlice(CPAP_TidalVolume,QColor("light blue"),ST_MIN);
tv->addSlice(CPAP_TidalVolume,QColor("blue"),ST_PERC,0.5);
tv->addSlice(CPAP_TidalVolume,QColor("light green"),ST_PERC,0.95);
tv->addSlice(CPAP_TidalVolume,QColor("green"),ST_PERC,0.999);
TV->AddLayer(tv);
mv=new SummaryChart(tr("L/m"),GT_LINE);
mv->addSlice(CPAP_MinuteVent,QColor("light blue"),ST_MIN,true);
mv->addSlice(CPAP_MinuteVent,QColor("light green"),ST_PERC,true,0.95);
mv->addSlice(CPAP_MinuteVent,QColor("blue"),ST_WAVG,true);
mv->addSlice(CPAP_MinuteVent,QColor("green"),ST_PERC,true,0.999);
mv->addSlice(CPAP_MinuteVent,QColor("light blue"),ST_MIN);
mv->addSlice(CPAP_MinuteVent,QColor("blue"),ST_PERC,0.5);
mv->addSlice(CPAP_MinuteVent,QColor("light green"),ST_PERC,0.95);
mv->addSlice(CPAP_MinuteVent,QColor("green"),ST_PERC,0.999);
MV->AddLayer(mv);
tgmv=new SummaryChart(tr("L/m"),GT_LINE);
tgmv->addSlice(CPAP_TgMV,QColor("light blue"),ST_MIN,true);
tgmv->addSlice(CPAP_TgMV,QColor("light green"),ST_PERC,true,0.95);
tgmv->addSlice(CPAP_TgMV,QColor("blue"),ST_WAVG,true);
tgmv->addSlice(CPAP_TgMV,QColor("green"),ST_PERC,true,0.999);
tgmv->addSlice(CPAP_TgMV,QColor("light blue"),ST_MIN);
tgmv->addSlice(CPAP_TgMV,QColor("blue"),ST_PERC,0.5);
tgmv->addSlice(CPAP_TgMV,QColor("light green"),ST_PERC,0.95);
tgmv->addSlice(CPAP_TgMV,QColor("green"),ST_PERC,0.999);
TGMV->AddLayer(tgmv);
ptb=new SummaryChart(tr("%PTB"),GT_LINE);
ptb->addSlice(CPAP_PTB,QColor("yellow"),ST_MIN,true);
ptb->addSlice(CPAP_PTB,QColor("light gray"),ST_PERC,true,0.95);
ptb->addSlice(CPAP_PTB,QColor("orange"),ST_WAVG,true);
ptb->addSlice(CPAP_PTB,QColor("yellow"),ST_MIN);
ptb->addSlice(CPAP_PTB,QColor("blue"),ST_PERC,0.5);
ptb->addSlice(CPAP_PTB,QColor("light gray"),ST_PERC,0.95);
ptb->addSlice(CPAP_PTB,QColor("orange"),ST_WAVG);
PTB->AddLayer(ptb);
pr=new SummaryChart(STR_TR_Pressure,GT_LINE);
@ -249,15 +248,15 @@ Overview::Overview(QWidget *parent,gGraphView * shared) :
PR->AddLayer(pr);
lk=new SummaryChart(tr("Avg Leak"),GT_LINE);
lk->addSlice(CPAP_Leak,QColor("dark grey"),ST_PERC,false,0.95);
lk->addSlice(CPAP_Leak,QColor("light blue"),ST_PERC,false,0.5);
lk->addSlice(CPAP_Leak,QColor("dark blue"),ST_WAVG,false);
lk->addSlice(CPAP_Leak,QColor("grey"),ST_PERC,false,0.999);
lk->addSlice(CPAP_Leak,QColor("light blue"),ST_PERC,0.5);
lk->addSlice(CPAP_Leak,QColor("dark grey"),ST_PERC,0.95);
//lk->addSlice(CPAP_Leak,QColor("dark blue"),ST_WAVG);
lk->addSlice(CPAP_Leak,QColor("grey"),ST_PERC,0.999);
//lk->addSlice(CPAP_Leak,QColor("dark yellow"));
LK->AddLayer(lk);
NPB->AddLayer(npb=new SummaryChart(tr("% PB"),GT_BAR));
npb->addSlice(CPAP_CSR,QColor("light green"),ST_SPH,false);
npb->addSlice(CPAP_CSR,QColor("light green"),ST_SPH);
// <--- The code to the previous marker is crap
GraphView->LoadSettings("Overview"); //no trans