";
+ html += QString( "
" + tr("I can haz data?!?") + "
"+
+ "

"
+ "
"+tr("Oscar has no data to report :(")+"
");
+ return html;
+}
+
+// Get RDI or AHI text depending on user preferences
+QString Statistics::getRDIorAHIText() {
+ if (p_profile->general->calculateRDI()) {
+ return STR_TR_RDI;
+ }
+ return STR_TR_AHI;
+}
+
+// Create the HTML that will be the Statistics page.
QString Statistics::GenerateHTML()
{
QList
cpap_machines = p_profile->GetMachines(MT_CPAP);
@@ -956,6 +965,7 @@ QString Statistics::GenerateHTML()
mach.append(cpap_machines);
mach.append(oximeters);
+ // Go through all CPAP and Oximeter machines and see if any data is present
bool havedata = false;
for (int i=0; i < mach.size(); ++i) {
int daysize = mach[i]->day.size();
@@ -965,69 +975,52 @@ QString Statistics::GenerateHTML()
}
}
-
+ // Create HTML header and statement
QString html = htmlHeader(havedata);
- // return "";
-
+ // If we don't have any data, return HTML that says that and we are done
+ if (!havedata) {
+ html += htmlNoData();
+ html += htmlFooter(havedata);
+ return html;
+ }
// Find first and last days with valid CPAP data
QDate lastcpap = p_profile->LastGoodDay(MT_CPAP);
QDate firstcpap = p_profile->FirstGoodDay(MT_CPAP);
-
+ // Get dates for standard report (last week, month, 6 months, year)
QDate cpapweek = lastcpap.addDays(-6);
QDate cpapmonth = lastcpap.addDays(-29);
QDate cpap6month = lastcpap.addMonths(-6);
QDate cpapyear = lastcpap.addMonths(-12);
- if (cpapweek < firstcpap) { cpapweek = firstcpap; }
- if (cpapmonth < firstcpap) { cpapmonth = firstcpap; }
+ // but not before the first available date of course
+ if (cpapweek < firstcpap) { cpapweek = firstcpap; }
+ if (cpapmonth < firstcpap) { cpapmonth = firstcpap; }
if (cpap6month < firstcpap) { cpap6month = firstcpap; }
- if (cpapyear < firstcpap) { cpapyear = firstcpap; }
+ if (cpapyear < firstcpap) { cpapyear = firstcpap; }
- if (!havedata) {
-// html += "";
- html += "";
-// html += QString("
") +
- html += QString( " " + tr("I can haz data?!?") + " "+
- " "
- ""+tr("Oscar has no data to report :(")+" ");
+ QString ahitxt = getRDIorAHIText();
-// " |
";
- html += htmlFooter(havedata);
- return html;
- }
-
-
- // int cpapdays = p_profile->countDays(MT_CPAP, firstcpap, lastcpap);
-
-// CPAPMode cpapmode = (CPAPMode)(int)p_profile->calcSettingsMax(CPAP_Mode, MT_CPAP, firstcpap, lastcpap);
-
- // float percentile = p_profile->general->prefCalcPercentile() / 100.0;
-
- // int mididx=p_profile->general->prefCalcMiddle();
- // SummaryType ST_mid;
- // if (mididx==0) ST_mid=ST_PERC;
- // if (mididx==1) ST_mid=ST_WAVG;
- // if (mididx==2) ST_mid=ST_AVG;
-
- QString ahitxt;
-
- if (p_profile->general->calculateRDI()) {
- ahitxt = STR_TR_RDI;
- } else {
- ahitxt = STR_TR_AHI;
- }
-
- // int decimals = 2;
+ // Prepare top of table
html += "";
html += "
";
+ // Compute number of monthly periods for a monthly rather than standard time distribution
int number_periods = 0;
- if (p_profile->general->statReportMode() == 1) {
- number_periods = p_profile->FirstDay().daysTo(p_profile->LastDay()) / 30;
+ if (p_profile->general->statReportMode() == STAT_MODE_MONTHLY) {
+ QDate beginDate = qMax(firstcpap, lastcpap.addYears(-1));
+ int beginMonth = beginDate.month();
+ int lastMonth = lastcpap.month();
+ if (lastMonth < beginMonth) lastMonth += 12; // handle time extending to next year
+ number_periods = lastMonth - beginMonth + 1;
+ if (number_periods < 1) {
+ qDebug() << "*** Begin" << beginDate << "beginMonth" << beginMonth << "lastMonth" << lastMonth << "periods" << number_periods;
+ number_periods = 1;
+ }
+ // But not more than one year
if (number_periods > 12) {
number_periods = 12;
}
@@ -1037,8 +1030,8 @@ QString Statistics::GenerateHTML()
QList periods;
-
bool skipsection = false;;
+ // Loop through all rows of the Statistics report
for (QList::iterator i = rows.begin(); i != rows.end(); ++i) {
StatisticsRow &row = (*i);
QString name;
@@ -1047,14 +1040,15 @@ QString Statistics::GenerateHTML()
last = p_profile->LastGoodDay(row.type);
first = p_profile->FirstGoodDay(row.type);
+ // Clear the periods (columns)
periods.clear();
- if (p_profile->general->statReportMode() == 0) {
+ if (p_profile->general->statReportMode() == STAT_MODE_STANDARD) {
periods.push_back(Period(last,last,tr("Most Recent")));
periods.push_back(Period(qMax(last.addDays(-6), first), last, tr("Last Week")));
periods.push_back(Period(qMax(last.addDays(-29),first), last, tr("Last 30 Days")));
periods.push_back(Period(qMax(last.addMonths(-6), first), last, tr("Last 6 Months")));
periods.push_back(Period(qMax(last.addMonths(-12), first), last, tr("Last Year")));
- } else {
+ } else { // STAT_MODE_MONTHLY or STAT_MODE_RANGE
QDate l=last,s=last;
periods.push_back(Period(last,last,tr("Last Session")));
@@ -1157,7 +1151,7 @@ QString Statistics::GenerateHTML()
int np = periods.size();
int width;
for (int j=0; j < np; j++) {
- if (p_profile->general->statReportMode() == 1) {
+ if (p_profile->general->statReportMode() == STAT_MODE_MONTHLY) {
width = j < np-1 ? 6 : 100 - (25 + 6*(np-1));
} else {
width = 75/np;
@@ -1498,7 +1492,9 @@ QString StatisticsRow::value(QDate start, QDate end)
value = QString("%1").arg(formatTime(p_profile->calcHours(type, start, end) / days));
} else if (calc == SC_COMPLIANCE) {
float c = p_profile->countCompliantDays(type, start, end);
- float p = (100.0 / days) * c;
+// float p = (100.0 / days) * c;
+ float realDays = qAbs(start.daysTo(end)) + 1;
+ float p = (100.0 / realDays) * c;
value = QString("%1%").arg(p, 0, 'f', 0);
} else if (calc == SC_DAYS) {
value = QString("%1").arg(p_profile->countDays(type, start, end));
diff --git a/oscar/statistics.h b/oscar/statistics.h
index 1a9c86c2..be33e6d1 100644
--- a/oscar/statistics.h
+++ b/oscar/statistics.h
@@ -15,10 +15,14 @@
#include "SleepLib/schema.h"
#include "SleepLib/machine.h"
+//! \brief Type of calculation on one statistics row
enum StatCalcType {
SC_UNDEFINED=0, SC_COLUMNHEADERS, SC_HEADING, SC_SUBHEADING, SC_MEDIAN, SC_AVG, SC_WAVG, SC_90P, SC_MIN, SC_MAX, SC_CPH, SC_SPH, SC_AHI, SC_HOURS, SC_COMPLIANCE, SC_DAYS, SC_ABOVE, SC_BELOW
};
+/*! \struct StatisticsRow
+ \brief Describes a single row on the statistics page
+ */
struct StatisticsRow {
StatisticsRow() { calc=SC_UNDEFINED; }
StatisticsRow(QString src, QString calc, QString type) {
@@ -40,6 +44,7 @@ struct StatisticsRow {
StatCalcType calc;
MachineType type;
+ //! \brief Looks up calculation type for this row
StatCalcType lookupCalc(QString calc)
{
if (calc.compare("avg",Qt::CaseInsensitive)==0) {
@@ -74,6 +79,7 @@ struct StatisticsRow {
return SC_UNDEFINED;
}
+ //! \brief Look up machine type
MachineType lookupType(QString type)
{
if (type.compare("cpap", Qt::CaseInsensitive)==0) {
@@ -94,6 +100,7 @@ struct StatisticsRow {
QString value(QDate start, QDate end);
};
+//! \class Prescription (Machine) setting
class RXItem {
public:
RXItem() {
@@ -156,6 +163,8 @@ class Statistics : public QObject
void saveRXChanges();
void updateRXChanges();
+ QString getUserInfo();
+ QString getRDIorAHIText();
QString GenerateHTML();
QString GenerateMachineList();
QString GenerateRXChanges();
@@ -164,6 +173,7 @@ class Statistics : public QObject
protected:
+ QString htmlNoData();
QString htmlHeader(bool showheader);
QString htmlFooter(bool showinfo=true);