Total Time in Apnea overview chart

This commit is contained in:
Mark Watkins 2014-09-19 03:58:00 +10:00
parent 964d6b8862
commit 6fd823104d
5 changed files with 134 additions and 25 deletions

View File

@ -405,7 +405,7 @@ void gSummaryChart::paint(QPainter &painter, gGraph &graph, const QRegion &regio
int days = ceil(double(m_maxx - m_minx) / 86400000.0);
float lasty1 = rect.bottom();
//float lasty1 = rect.bottom();
QMap<QDate, int>::iterator it = dayindex.find(date);
idx_start=0;
@ -1045,6 +1045,77 @@ void gSessionTimesChart::paint(QPainter &painter, gGraph &graph, const QRegion &
afterDraw(painter, graph, rect);
}
////////////////////////////////////////////////////////////////////////////
/// Total Time in Apnea Chart Stuff
////////////////////////////////////////////////////////////////////////////
void gTTIAChart::preCalc()
{
gSummaryChart::preCalc();
}
void gTTIAChart::customCalc(Day *, QList<SummaryChartSlice> & slices)
{
if (slices.size() == 0) return;
const SummaryChartSlice & slice = slices.at(0);
calcitems[0].update(slice.value, slice.value);
}
void gTTIAChart::afterDraw(QPainter &, gGraph &graph, QRect rect)
{
QStringList txtlist;
int num_channels = calcitems.size();
for (int i=0; i < num_channels; ++i) {
SummaryCalcItem & calc = calcitems[i];
ChannelID code = calc.code;
schema::Channel & chan = schema::channel[code];
float mid = 0;
switch (midcalc) {
case 0:
if (calc.median_data.size() > 0) {
mid = median(calc.median_data.begin(), calc.median_data.end());
}
break;
case 1:
if (calc.divisor > 0) {
mid = calc.wavg_sum / calc.divisor;
}
break;
case 2:
if (calc.divisor > 0) {
mid = calc.avg_sum / calc.divisor;
}
break;
}
txtlist.append(QString("%1 %2 / %3 / %4").arg(QObject::tr("TTIA:")).arg(calc.min, 0, 'f', 2).arg(mid, 0, 'f', 2).arg(calc.max, 0, 'f', 2));
}
QString txt = txtlist.join(", ");
graph.renderText(txt, rect.left(), rect.top()-5*graph.printScaleY(), 0);
}
void gTTIAChart::populate(Day *day, int idx)
{
QList<SummaryChartSlice> & slices = cache[idx];
float ttia = day->sum(CPAP_Obstructive) + day->sum(CPAP_ClearAirway) + day->sum(CPAP_Apnea) + day->sum(CPAP_Hypopnea);
int h = ttia / 3600;
int m = int(ttia) / 60 % 60;
int s = int(ttia) % 60;
slices.append(SummaryChartSlice(&calcitems[0], ttia / 60.0, ttia / 60.0, QObject::tr("\nTTIA: %1").arg(QString().sprintf("%02i:%02i:%02i",h,m,s)), QColor(255,147,150)));
}
QString gTTIAChart::tooltipData(Day *, int idx)
{
QList<SummaryChartSlice> & slices = cache[idx];
if (slices.size() == 0) return QString();
const SummaryChartSlice & slice = slices.at(0);
return slice.name;
}
////////////////////////////////////////////////////////////////////////////
/// AHI Chart Stuff
////////////////////////////////////////////////////////////////////////////
void gAHIChart::preCalc()
{
gSummaryChart::preCalc();
@ -1116,10 +1187,14 @@ void gAHIChart::afterDraw(QPainter & /*painter */, gGraph &graph, QRect rect)
}
break;
case 1: // wavg
if (total_hours > 0) {
med = ahi_wavg / total_hours;
}
break;
case 2: // avg
if (calc_cnt > 0) {
med = ahi_avg / calc_cnt;
}
break;
}
@ -1130,7 +1205,6 @@ void gAHIChart::afterDraw(QPainter & /*painter */, gGraph &graph, QRect rect)
for (int i=0; i < num_channels; ++i) {
SummaryCalcItem & calc = calcitems[i];
if (calc.divisor > 0) {
ChannelID code = calc.code;
schema::Channel & chan = schema::channel[code];
float mid = 0;
@ -1141,16 +1215,19 @@ void gAHIChart::afterDraw(QPainter & /*painter */, gGraph &graph, QRect rect)
}
break;
case 1:
if (calc.divisor > 0) {
mid = calc.wavg_sum / calc.divisor;
}
break;
case 2:
if (calc.divisor > 0) {
mid = calc.avg_sum / calc.divisor;
}
break;
}
txtlist.append(QString("%1 %2 / %3 / %4").arg(chan.label()).arg(calc.min, 0, 'f', 2).arg(mid, 0, 'f', 2).arg(calc.max, 0, 'f', 2));
}
}
QString txt = txtlist.join(", ");
graph.renderText(txt, rect.left(), rect.top()-5*graph.printScaleY(), 0);
}

View File

@ -333,6 +333,34 @@ private:
EventDataType compliance_threshold;
};
class gTTIAChart : public gSummaryChart
{
public:
gTTIAChart()
:gSummaryChart("TTIA", MT_CPAP) {
addCalc(NoChannel, ST_CNT, QColor(255,147,150));
}
virtual ~gTTIAChart() {}
virtual void preCalc();
virtual void customCalc(Day *, QList<SummaryChartSlice> &);
virtual void afterDraw(QPainter &, gGraph &, QRect);
virtual void populate(Day *day, int idx);
virtual QString tooltipData(Day * day, int);
virtual Layer * Clone() {
gTTIAChart * sc = new gTTIAChart();
gSummaryChart::CloneInto(sc);
CloneInto(sc);
return sc;
}
void CloneInto(gTTIAChart * /* layer*/) {
}
private:
};
class gAHIChart : public gSummaryChart
{
public:

View File

@ -346,6 +346,10 @@ void Overview::RebuildGraphs(bool reset)
pres = new gPressureChart();
PR->AddLayer(pres);
TTIA = createGraph("TTIA", tr("Total Time in Apnea"), tr("Total Time in Apnea\n(Minutes)"));
ttia = new gTTIAChart();
TTIA->AddLayer(ttia);
// LK = createGraph("Leaks", STR_TR_Leaks, STR_TR_UnintentionalLeaks + "\n(" + STR_UNIT_LPM + ")");
// LK->AddLayer(new gSummaryChart(CPAP_Leak, MT_CPAP));

View File

@ -62,11 +62,11 @@ class Overview : public QWidget
\param QString units The units of measurements to show in the popup */
gGraph *createGraph(QString code, QString name, QString units = "", YTickerType yttype = YT_Number);
gGraph *AHI, *AHIHR, *UC, *FL, *SA, *US, *PR, *LK, *NPB, *SET, *SES, *RR, *MV, *TV, *PTB, *PULSE, *SPO2, *NLL,
*WEIGHT, *ZOMBIE, *BMI, *TGMV, *TOTLK, *STG, *SN;
*WEIGHT, *ZOMBIE, *BMI, *TGMV, *TOTLK, *STG, *SN, *TTIA;
SummaryChart *bc, *sa, *us, *pr, *set, *ses, *ptb, *pulse, *spo2,
*weight, *zombie, *bmi, *ahihr, *tgmv, *totlk;
gSummaryChart * stg, *uc, *ahi, * pres, *lk, *npb, *rr, *mv, *tv, *nll, *sn;
gSummaryChart * stg, *uc, *ahi, * pres, *lk, *npb, *rr, *mv, *tv, *nll, *sn, *ttia;
//! \breif List of SummaryCharts shown on the overview page
QVector<SummaryChart *> OverviewCharts;

View File

@ -51,7 +51,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="importTab">
<attribute name="title">
@ -549,7 +549,7 @@ SleepyHead can keep a copy of this data if you ever need to reinstall.
<string>Bypass the login screen and load the most recent User Profile</string>
</property>
<property name="text">
<string>Skip Login Screen</string>
<string>Skip user selection screen</string>
</property>
</widget>
</item>