mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-05 02:30:44 +00:00
Time@Pressure Graph
This commit is contained in:
parent
3a757082b3
commit
e2f1c17840
228
Graphs/gSegmentChart.cpp
Normal file
228
Graphs/gSegmentChart.cpp
Normal file
@ -0,0 +1,228 @@
|
||||
#include <cmath>
|
||||
#include "gSegmentChart.h"
|
||||
|
||||
|
||||
gSegmentChart::gSegmentChart(GraphSegmentType type,QColor gradient_color,QColor outline_color)
|
||||
:gLayer(MC_UNKNOWN),m_graph_type(type),m_gradient_color(gradient_color),m_outline_color(outline_color)
|
||||
{
|
||||
// m_gradient_color=QColor(200,200,200);
|
||||
}
|
||||
gSegmentChart::~gSegmentChart()
|
||||
{
|
||||
}
|
||||
void gSegmentChart::AddSlice(MachineCode code,QColor color,QString name)
|
||||
{
|
||||
m_codes.push_back(code);
|
||||
m_values.push_back(0);
|
||||
m_colors.push_back(color);
|
||||
m_names.push_back(name);
|
||||
m_total=0;
|
||||
}
|
||||
void gSegmentChart::SetDay(Day *d)
|
||||
{
|
||||
gLayer::SetDay(d);
|
||||
m_total=0;
|
||||
if (!m_day) return;
|
||||
for (unsigned c=0;c<m_codes.size();c++) {
|
||||
m_values[c]=0;
|
||||
for (vector<Session *>::iterator s=m_day->begin();s!=m_day->end();s++) {
|
||||
int cnt=(*s)->count(m_codes[c]);
|
||||
m_values[c]+=cnt;
|
||||
m_total+=cnt;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void gSegmentChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
{
|
||||
if (!m_visible) return;
|
||||
if (!m_day) return;
|
||||
if (!m_total) return;
|
||||
int start_px=w.GetLeftMargin();
|
||||
int start_py=w.GetBottomMargin();
|
||||
int width=scrx-(w.GetLeftMargin()+w.GetRightMargin());
|
||||
int height=scry-(w.GetTopMargin()+w.GetBottomMargin());
|
||||
|
||||
float diameter=MIN(width,height);
|
||||
diameter-=8;
|
||||
float radius=diameter/2.0;
|
||||
|
||||
float j=0.0;
|
||||
float sum=0.0;
|
||||
float step=1.0/45.0;
|
||||
float px,py;
|
||||
float q;
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glLineWidth(1.5);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
float mult=float(width)/m_total;
|
||||
|
||||
float xp=w.GetLeftMargin();
|
||||
|
||||
int xoffset=width/2;
|
||||
int yoffset=height/2;
|
||||
|
||||
int data;
|
||||
for (unsigned m=0;m<m_values.size();m++) {
|
||||
data=m_values[m];
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Pie Chart
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
if (m_graph_type==GST_Pie) {
|
||||
j=float(data)/float(m_total); // ratio of this pie slice
|
||||
|
||||
// Draw Filling
|
||||
glPolygonMode(GL_BACK,GL_FILL);
|
||||
glBegin(GL_POLYGON);
|
||||
w.qglColor(m_gradient_color);
|
||||
glVertex2f(start_px+xoffset, start_py+yoffset);
|
||||
w.qglColor(m_colors[m % m_colors.size()]);
|
||||
for (q=sum;q<sum+j;q+=step) {
|
||||
px=start_px+xoffset+sin(q*2*M_PI)*radius;
|
||||
py=start_py+yoffset+cos(q*2*M_PI)*radius;
|
||||
glVertex2f(px,py);
|
||||
}
|
||||
q=sum+j;
|
||||
px=start_px+xoffset+sin(q*2*M_PI)*radius;
|
||||
py=start_py+yoffset+cos(q*2*M_PI)*radius;
|
||||
glVertex2f(px,py);
|
||||
glEnd();
|
||||
|
||||
// Draw Outline
|
||||
w.qglColor(m_outline_color);
|
||||
if (m_total>data) { // Draw the center point first
|
||||
glPolygonMode(GL_BACK,GL_LINE);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2f(start_px+xoffset, start_py+yoffset);
|
||||
} else { // Only one entry, so just draw the circle
|
||||
glBegin(GL_LINE_LOOP);
|
||||
}
|
||||
for (q=sum;q<sum+j;q+=step) {
|
||||
px=start_px+xoffset+sin(q*2*M_PI)*radius;
|
||||
py=start_py+yoffset+cos(q*2*M_PI)*radius;
|
||||
glVertex2f(px,py);
|
||||
}
|
||||
q=sum+j;
|
||||
px=start_px+xoffset+sin(q*2*M_PI)*radius;
|
||||
py=start_py+yoffset+cos(q*2*M_PI)*radius;
|
||||
glVertex2f(px,py);
|
||||
glEnd();
|
||||
sum=q;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// CandleStick Chart
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
} else if (m_graph_type==GST_CandleStick) {
|
||||
float bw=mult*float(data);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
w.qglColor(m_gradient_color);
|
||||
glVertex2f(xp,start_py);
|
||||
glVertex2f(xp+bw,start_py);
|
||||
w.qglColor(m_colors[m % m_colors.size()]);
|
||||
glVertex2f(xp+bw,start_py+height);
|
||||
glVertex2f(xp,start_py+height);
|
||||
glEnd();
|
||||
|
||||
w.qglColor(m_outline_color);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(xp,start_py);
|
||||
glVertex2f(xp+bw,start_py);
|
||||
glVertex2f(xp+bw,start_py+height);
|
||||
glVertex2f(xp,start_py+height);
|
||||
glEnd();
|
||||
|
||||
if (!m_names[m].isEmpty()) {
|
||||
GetTextExtent(m_names[m],px,py);
|
||||
if (px+5<bw) {
|
||||
DrawText(w,m_names[m],(xp+bw/2)-(px/2),scry-((height/2)-(py/2)),0,Qt::black);
|
||||
}
|
||||
}
|
||||
|
||||
xp+=bw;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
|
||||
gTAPGraph::gTAPGraph(MachineCode code,GraphSegmentType gt, QColor gradient_color,QColor outline_color)
|
||||
:gSegmentChart(gt,gradient_color,outline_color),m_code(code)
|
||||
{
|
||||
m_colors.push_back(Qt::red);
|
||||
m_colors.push_back(Qt::green);
|
||||
}
|
||||
gTAPGraph::~gTAPGraph()
|
||||
{
|
||||
}
|
||||
void gTAPGraph::SetDay(Day *d)
|
||||
{
|
||||
gLayer::SetDay(d);
|
||||
m_total=0;
|
||||
if (!m_day) return;
|
||||
vector<qint64> tap;
|
||||
const int max_value=2600;
|
||||
tap.resize(max_value);
|
||||
|
||||
EventStoreType data=0,lastval=0;
|
||||
qint64 time=0,lasttime=0,lastlasttime=0;
|
||||
bool first=true;
|
||||
bool rfirst=true;
|
||||
EventDataType gain=1,offset=0;
|
||||
for (vector<Session *>::iterator s=m_day->begin();s!=m_day->end();s++) {
|
||||
if ((*s)->eventlist.find(m_code)==(*s)->eventlist.end()) continue;
|
||||
for (unsigned q=0;q<(*s)->eventlist[m_code].size();q++) {
|
||||
EventList &el=*(*s)->eventlist[m_code][q];
|
||||
lasttime=el.time(0);
|
||||
first=true;
|
||||
|
||||
for (int i=0;i<el.count();i++) {
|
||||
data=el.raw(i);
|
||||
if (data>max_value) {
|
||||
qWarning() << "max_value is too small in gTAPGraph::SetDay()";
|
||||
break;
|
||||
}
|
||||
time=el.time(i);
|
||||
if (rfirst) {
|
||||
gain=el.gain();
|
||||
offset=el.offset();
|
||||
rfirst=false;
|
||||
}
|
||||
if (first) {
|
||||
first=false;
|
||||
} else {
|
||||
if (lastval!=data) {
|
||||
int v=(time-lasttime)/1000;
|
||||
tap[lastval]+=v;
|
||||
}
|
||||
}
|
||||
lastlasttime=lasttime;
|
||||
lasttime=time;
|
||||
lastval=data;
|
||||
}
|
||||
if (lastval!=data){
|
||||
int v=(time-lastlasttime)/1000L;
|
||||
tap[data]+=v;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_values.clear();
|
||||
m_names.clear();
|
||||
m_total=0;
|
||||
EventDataType val;
|
||||
for (int i=0;i<max_value;i++) {
|
||||
if (tap[i]>0) {
|
||||
val=float(i)*gain+offset;
|
||||
m_values.push_back(tap[i]);
|
||||
m_total+=tap[i];
|
||||
|
||||
m_names.push_back(QString::number(val,'f',2));
|
||||
}
|
||||
}
|
||||
}
|
46
Graphs/gSegmentChart.h
Normal file
46
Graphs/gSegmentChart.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef GSEGMENTCHART_H
|
||||
#define GSEGMENTCHART_H
|
||||
|
||||
#include "graphlayer.h"
|
||||
|
||||
enum GraphSegmentType { GST_Pie, GST_CandleStick };
|
||||
|
||||
class gSegmentChart : public gLayer
|
||||
{
|
||||
public:
|
||||
gSegmentChart(GraphSegmentType gt=GST_Pie, QColor gradient_color=Qt::lightGray,QColor outline_color=Qt::black);
|
||||
virtual ~gSegmentChart();
|
||||
|
||||
virtual void Plot(gGraphWindow & w,float scrx,float scry);
|
||||
virtual void SetDay(Day *d);
|
||||
|
||||
void AddSlice(MachineCode code,QColor col,QString name="");
|
||||
void setGradientColor(QColor & color) { m_gradient_color=color; }
|
||||
void setOutlineColor(QColor & color) { m_outline_color=color; }
|
||||
const GraphSegmentType & graphType() { return m_graph_type; }
|
||||
void setGraphType(GraphSegmentType type) { m_graph_type=type; }
|
||||
|
||||
protected:
|
||||
vector<MachineCode> m_codes;
|
||||
vector<QString> m_names;
|
||||
vector<int> m_values;
|
||||
vector<QColor> m_colors;
|
||||
|
||||
int m_total;
|
||||
GraphSegmentType m_graph_type;
|
||||
QColor m_gradient_color;
|
||||
QColor m_outline_color;
|
||||
};
|
||||
|
||||
class gTAPGraph:public gSegmentChart
|
||||
{
|
||||
public:
|
||||
gTAPGraph(MachineCode code,GraphSegmentType gt=GST_CandleStick, QColor gradient_color=Qt::lightGray,QColor outline_color=Qt::black);
|
||||
virtual ~gTAPGraph();
|
||||
virtual void SetDay(Day *d);
|
||||
protected:
|
||||
MachineCode m_code;
|
||||
};
|
||||
|
||||
|
||||
#endif // GSEGMENTCHART_H
|
@ -1,101 +0,0 @@
|
||||
#include <math.h>
|
||||
#include "gpiechart.h"
|
||||
|
||||
gPieChart::gPieChart(QColor outline_color)
|
||||
:gLayer(MC_UNKNOWN),m_outline_color(outline_color)
|
||||
{
|
||||
m_gradient_color=QColor(200,200,200);
|
||||
}
|
||||
gPieChart::~gPieChart()
|
||||
{
|
||||
}
|
||||
void gPieChart::AddSlice(MachineCode code,QColor color,QString name)
|
||||
{
|
||||
m_counts[code]=code;
|
||||
m_colors[code]=color;
|
||||
m_names[code]=name;
|
||||
m_total=0;
|
||||
}
|
||||
void gPieChart::SetDay(Day *d)
|
||||
{
|
||||
gLayer::SetDay(d);
|
||||
m_total=0;
|
||||
if (!m_day) return;
|
||||
for (map<MachineCode,int>::iterator c=m_counts.begin();c!=m_counts.end();c++) {
|
||||
c->second=0;
|
||||
for (vector<Session *>::iterator s=m_day->begin();s!=m_day->end();s++) {
|
||||
int cnt=(*s)->count(c->first);
|
||||
c->second+=cnt;
|
||||
m_total+=cnt;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void gPieChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
{
|
||||
if (!m_visible) return;
|
||||
if (!m_day) return;
|
||||
if (!m_total) return;
|
||||
int start_px=w.GetLeftMargin();
|
||||
int start_py=w.GetBottomMargin();
|
||||
int width=scrx-(w.GetLeftMargin()+w.GetRightMargin());
|
||||
int height=scry-(w.GetTopMargin()+w.GetBottomMargin());
|
||||
|
||||
float diameter=MIN(width,height);
|
||||
diameter-=8;
|
||||
float radius=diameter/2.0;
|
||||
|
||||
double j=0.0;
|
||||
double sum=0.0;
|
||||
double step=1.0/45.0;
|
||||
float px,py;
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glLineWidth(1.5);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
for (map<MachineCode,int>::iterator m=m_counts.begin();m!=m_counts.end();m++) {
|
||||
if (!m->second) continue;
|
||||
j=float(m->second)/float(m_total); // ratio of this pie slice
|
||||
glPolygonMode(GL_BACK,GL_FILL);
|
||||
glBegin(GL_POLYGON);
|
||||
bool first_col;
|
||||
w.qglColor(m_gradient_color);
|
||||
glVertex2f(start_px+radius+4, start_py+radius+4);
|
||||
w.qglColor(m_colors[m->first]);
|
||||
double q;
|
||||
for (q=sum;q<sum+j;q+=step) {
|
||||
px=start_px+radius+4+sin(q*2*M_PI)*radius;
|
||||
py=start_py+radius+4+cos(q*2*M_PI)*radius;
|
||||
glVertex2f(px,py);
|
||||
}
|
||||
q=sum+j;
|
||||
px=start_px+radius+4+sin(q*2*M_PI)*radius;
|
||||
py=start_py+radius+4+cos(q*2*M_PI)*radius;
|
||||
glVertex2f(px,py);
|
||||
glEnd();
|
||||
|
||||
w.qglColor(m_outline_color);
|
||||
if (m_total>m->second) { // Draw the center point first
|
||||
glPolygonMode(GL_BACK,GL_LINE);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2f(start_px+radius+4, start_py+radius+4);
|
||||
} else { // Only one entry, so just draw the circle
|
||||
//glBegin(GL_POLYGON);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
}
|
||||
for (q=sum;q<sum+j;q+=step) {
|
||||
px=start_px+radius+4+sin(q*2*M_PI)*radius;
|
||||
py=start_py+radius+4+cos(q*2*M_PI)*radius;
|
||||
glVertex2f(px,py);
|
||||
}
|
||||
q=sum+j;
|
||||
px=start_px+radius+4+sin(q*2*M_PI)*radius;
|
||||
py=start_py+radius+4+cos(q*2*M_PI)*radius;
|
||||
glVertex2f(px,py);
|
||||
glEnd();
|
||||
sum=q;
|
||||
}
|
||||
glDisable(GL_BLEND);
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#ifndef GPIECHART_H
|
||||
#define GPIECHART_H
|
||||
|
||||
#include "graphlayer.h"
|
||||
class gPieChart : public gLayer
|
||||
{
|
||||
public:
|
||||
gPieChart(QColor color=Qt::black);
|
||||
virtual ~gPieChart();
|
||||
|
||||
virtual void Plot(gGraphWindow & w,float scrx,float scry);
|
||||
virtual void SetDay(Day *d);
|
||||
|
||||
void AddSlice(MachineCode code,QColor col,QString name="");
|
||||
void setGradientColor(QColor & color) { m_gradient_color=color; }
|
||||
void setOutlineColor(QColor & color) { m_outline_color=color; }
|
||||
|
||||
protected:
|
||||
map <MachineCode,QString> m_names;
|
||||
map <MachineCode,int> m_counts;
|
||||
map <MachineCode,QColor> m_colors;
|
||||
int m_total;
|
||||
QColor m_outline_color;
|
||||
QColor m_gradient_color;
|
||||
|
||||
};
|
||||
|
||||
#endif // GPIECHART_H
|
@ -52,11 +52,11 @@ SOURCES += main.cpp\
|
||||
Graphs/gCandleStick.cpp \
|
||||
Graphs/gBarChart.cpp \
|
||||
SleepLib/loader_plugins/resmed_loader.cpp \
|
||||
Graphs/gpiechart.cpp \
|
||||
SleepLib/loader_plugins/sleep_database.cpp \
|
||||
Graphs/gSessionTime.cpp \
|
||||
qextserialport/qextserialport.cpp \
|
||||
oximetry.cpp
|
||||
oximetry.cpp \
|
||||
Graphs/gSegmentChart.cpp
|
||||
|
||||
unix:SOURCES += qextserialport/posix_qextserialport.cpp
|
||||
unix:!macx:SOURCES += qextserialport/qextserialenumerator_unix.cpp
|
||||
@ -100,13 +100,13 @@ HEADERS += \
|
||||
Graphs/gCandleStick.h \
|
||||
Graphs/gBarChart.h \
|
||||
SleepLib/loader_plugins/resmed_loader.h \
|
||||
Graphs/gpiechart.h \
|
||||
SleepLib/loader_plugins/sleep_database.h \
|
||||
Graphs/gSessionTime.h \
|
||||
qextserialport/qextserialport_global.h \
|
||||
qextserialport/qextserialport.h \
|
||||
qextserialport/qextserialenumerator.h \
|
||||
oximetry.h
|
||||
oximetry.h \
|
||||
Graphs/gSegmentChart.h
|
||||
|
||||
|
||||
FORMS += \
|
||||
|
28
daily.cpp
28
daily.cpp
@ -23,9 +23,8 @@
|
||||
#include "Graphs/gFooBar.h"
|
||||
#include "Graphs/gXAxis.h"
|
||||
#include "Graphs/gYAxis.h"
|
||||
#include "Graphs/gCandleStick.h"
|
||||
#include "Graphs/gBarChart.h"
|
||||
#include "Graphs/gpiechart.h"
|
||||
#include "Graphs/gSegmentChart.h"
|
||||
|
||||
const int min_height=100;
|
||||
const int default_height=150;
|
||||
@ -212,8 +211,12 @@ Daily::Daily(QWidget *parent,QGLWidget * shared) :
|
||||
//TAP_IAP->AddLayer(new gCandleStick(tap_iap));
|
||||
|
||||
|
||||
TAP->SetMargins(0,0,0,0);
|
||||
TAP->AddLayer(AddCPAP(new gTAPGraph(CPAP_Pressure)));
|
||||
TAP->hide();
|
||||
|
||||
G_AHI->SetMargins(0,0,0,0);
|
||||
gPieChart *l=new gPieChart(Qt::black);
|
||||
gSegmentChart *l=new gSegmentChart(GST_Pie);
|
||||
l->AddSlice(CPAP_Hypopnea,QColor(0x40,0x40,0xff,0xff),"H");
|
||||
l->AddSlice(CPAP_Obstructive,QColor(0x40,0xaf,0xbf,0xff),"OA");
|
||||
l->AddSlice(CPAP_ClearAirway,QColor(0xb2,0x54,0xcd,0xff),"CA");
|
||||
@ -221,9 +224,6 @@ Daily::Daily(QWidget *parent,QGLWidget * shared) :
|
||||
l->AddSlice(CPAP_FlowLimit,QColor(0x40,0x40,0x40,0xff),"FL");
|
||||
G_AHI->AddLayer(AddCPAP(l));
|
||||
G_AHI->SetGradientBackground(false);
|
||||
|
||||
//G_AHI->setMaximumSize(2000,30);
|
||||
//TAP->setMaximumSize(2000,30);
|
||||
G_AHI->hide();
|
||||
/*TAP->hide();
|
||||
TAP_IAP->hide();
|
||||
@ -562,7 +562,7 @@ void Daily::Load(QDate date)
|
||||
html+="</tr>\n<tr><td colspan=4 align=center><i>"+tr("Event Breakdown")+"</i></td></tr>\n";
|
||||
if (1) { // AHI Pie Chart
|
||||
G_AHI->setFixedSize(gwwidth,gwheight);
|
||||
QPixmap pixmap=G_AHI->renderPixmap(120,120,false); //gwwidth,gwheight,false);
|
||||
QPixmap pixmap=G_AHI->renderPixmap(gwwidth,120,false); //gwwidth,gwheight,false);
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
@ -659,13 +659,13 @@ void Daily::Load(QDate date)
|
||||
} else if (mode==MODE_APAP) {
|
||||
html+=("<tr><td colspan=4 align=center><i>")+tr("Time@Pressure")+("</i></td></tr>\n");
|
||||
|
||||
//TAP->setFixedSize(gwwidth,gwheight);
|
||||
//QPixmap pixmap=TAP->renderPixmap(gwwidth,gwheight,false);
|
||||
//QByteArray byteArray;
|
||||
//QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
|
||||
//buffer.open(QIODevice::WriteOnly);
|
||||
//pixmap.save(&buffer, "PNG");
|
||||
//html+="<tr><td colspan=4 align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\"></td></tr>\n";
|
||||
TAP->setFixedSize(gwwidth,gwheight);
|
||||
QPixmap pixmap=TAP->renderPixmap(gwwidth,gwheight,false);
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
pixmap.save(&buffer, "PNG");
|
||||
html+="<tr><td colspan=4 align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\"></td></tr>\n";
|
||||
}
|
||||
html+="</table><hr height=2><table cellpadding=0 cellspacing=0 border=0 width=100%>";
|
||||
html+="<tr><td align=center>SessionID</td><td align=center>Date</td><td align=center>Start</td><td align=center>End</td></tr>";
|
||||
|
Loading…
Reference in New Issue
Block a user