Auto-convert the Graphs/ subdirectory with astyle.

Signed-off-by: Mark Watkins <jedimark@users.sourceforge.net>
This commit is contained in:
Sean Stangl 2014-04-16 22:55:38 -07:00 committed by Mark Watkins
parent 012e9fd314
commit b5d5b82b59
23 changed files with 2974 additions and 2350 deletions

View File

@ -15,27 +15,29 @@
#include "gFlagsLine.h" #include "gFlagsLine.h"
#include "gYAxis.h" #include "gYAxis.h"
gFlagsLabelArea::gFlagsLabelArea(gFlagsGroup * group) gFlagsLabelArea::gFlagsLabelArea(gFlagsGroup *group)
:gSpacer(20) : gSpacer(20)
{ {
m_group=group; m_group = group;
} }
bool gFlagsLabelArea::mouseMoveEvent(QMouseEvent * event,gGraph * graph) bool gFlagsLabelArea::mouseMoveEvent(QMouseEvent *event, gGraph *graph)
{ {
if (m_group) if (m_group) {
return m_group->mouseMoveEvent(event,graph); return m_group->mouseMoveEvent(event, graph);
}
return false; return false;
} }
gFlagsGroup::gFlagsGroup() gFlagsGroup::gFlagsGroup()
{ {
addVertexBuffer(quads=new gVertexBuffer(512,GL_QUADS)); addVertexBuffer(quads = new gVertexBuffer(512, GL_QUADS));
addVertexBuffer(lines=new gVertexBuffer(20,GL_LINE_LOOP)); addVertexBuffer(lines = new gVertexBuffer(20, GL_LINE_LOOP));
quads->setAntiAlias(true); quads->setAntiAlias(true);
lines->setAntiAlias(false); lines->setAntiAlias(false);
m_barh=0; m_barh = 0;
m_empty=true; m_empty = true;
} }
gFlagsGroup::~gFlagsGroup() gFlagsGroup::~gFlagsGroup()
{ {
@ -45,6 +47,7 @@ qint64 gFlagsGroup::Minx()
if (m_day) { if (m_day) {
return m_day->first(); return m_day->first();
} }
return 0; return 0;
} }
qint64 gFlagsGroup::Maxx() qint64 gFlagsGroup::Maxx()
@ -52,94 +55,114 @@ qint64 gFlagsGroup::Maxx()
if (m_day) { if (m_day) {
return m_day->last(); return m_day->last();
} }
return 0; return 0;
} }
void gFlagsGroup::SetDay(Day * d) void gFlagsGroup::SetDay(Day *d)
{ {
LayerGroup::SetDay(d); LayerGroup::SetDay(d);
lvisible.clear(); lvisible.clear();
int cnt=0; int cnt = 0;
for (int i=0;i<layers.size();i++) {
gFlagsLine *f=dynamic_cast<gFlagsLine *>(layers[i]); for (int i = 0; i < layers.size(); i++) {
if (!f) continue; gFlagsLine *f = dynamic_cast<gFlagsLine *>(layers[i]);
if (!f) { continue; }
bool e = f->isEmpty();
bool e=f->isEmpty();
if (!e || f->isAlwaysVisible()) { if (!e || f->isAlwaysVisible()) {
lvisible.push_back(f); lvisible.push_back(f);
if (!e)
cnt++; if (!e) {
cnt++;
}
} }
} }
m_empty=(cnt==0);
m_empty = (cnt == 0);
if (m_empty) { if (m_empty) {
if (d) { if (d) {
m_empty=!d->channelExists(CPAP_Pressure); m_empty = !d->channelExists(CPAP_Pressure);
} }
} }
m_barh=0;
m_barh = 0;
} }
void gFlagsGroup::paint(gGraph &g, int left, int top, int width, int height) void gFlagsGroup::paint(gGraph &g, int left, int top, int width, int height)
{ {
if (!m_visible) return; if (!m_visible) { return; }
if (!m_day) return;
int vis=lvisible.size(); if (!m_day) { return; }
m_barh=float(height)/float(vis);
float linetop=top; int vis = lvisible.size();
m_barh = float(height) / float(vis);
float linetop = top;
QColor barcol; QColor barcol;
for (int i=0;i<lvisible.size();i++) {
for (int i = 0; i < lvisible.size(); i++) {
// Alternating box color // Alternating box color
if (i & 1) barcol=COLOR_ALT_BG1; else barcol=COLOR_ALT_BG2; if (i & 1) { barcol = COLOR_ALT_BG1; }
quads->add(left, linetop, left, linetop+m_barh, left+width-1, linetop+m_barh, left+width-1, linetop, barcol.rgba()); else { barcol = COLOR_ALT_BG2; }
quads->add(left, linetop, left, linetop + m_barh, left + width - 1, linetop + m_barh,
left + width - 1, linetop, barcol.rgba());
// Paint the actual flags // Paint the actual flags
lvisible[i]->m_rect=QRect(left,linetop,width,m_barh); lvisible[i]->m_rect = QRect(left, linetop, width, m_barh);
lvisible[i]->paint(g,left,linetop,width,m_barh); lvisible[i]->paint(g, left, linetop, width, m_barh);
linetop+=m_barh; linetop += m_barh;
} }
gVertexBuffer *outlines=g.lines(); gVertexBuffer *outlines = g.lines();
outlines->add(left-1, top, left-1, top+height, COLOR_Outline.rgba()); outlines->add(left - 1, top, left - 1, top + height, COLOR_Outline.rgba());
outlines->add(left-1, top+height, left+width,top+height, COLOR_Outline.rgba()); outlines->add(left - 1, top + height, left + width, top + height, COLOR_Outline.rgba());
outlines->add(left+width,top+height, left+width, top,COLOR_Outline.rgba()); outlines->add(left + width, top + height, left + width, top, COLOR_Outline.rgba());
outlines->add(left+width, top, left-1, top, COLOR_Outline.rgba()); outlines->add(left + width, top, left - 1, top, COLOR_Outline.rgba());
//lines->add(left-1, top, left-1, top+height); //lines->add(left-1, top, left-1, top+height);
//lines->add(left+width, top+height, left+width, top); //lines->add(left+width, top+height, left+width, top);
} }
bool gFlagsGroup::mouseMoveEvent(QMouseEvent * event,gGraph * graph) bool gFlagsGroup::mouseMoveEvent(QMouseEvent *event, gGraph *graph)
{ {
if (!p_profile->appearance->graphTooltips()) if (!p_profile->appearance->graphTooltips()) {
return false; return false;
}
for (int i=0;i<lvisible.size();i++) { for (int i = 0; i < lvisible.size(); i++) {
gFlagsLine *fl=lvisible[i]; gFlagsLine *fl = lvisible[i];
if (fl->m_rect.contains(event->x(),event->y())) {
if (fl->mouseMoveEvent(event,graph)) return true; if (fl->m_rect.contains(event->x(), event->y())) {
if (fl->mouseMoveEvent(event, graph)) { return true; }
} else { } else {
// Inside main graph area? // Inside main graph area?
if ((event->y() > fl->m_rect.y()) && (event->y()) < (fl->m_rect.y()+fl->m_rect.height())) { if ((event->y() > fl->m_rect.y()) && (event->y()) < (fl->m_rect.y() + fl->m_rect.height())) {
if (event->x() < lvisible[i]->m_rect.x()) { if (event->x() < lvisible[i]->m_rect.x()) {
// Display tooltip // Display tooltip
QString ttip=schema::channel[fl->code()].fullname()+"\n"+schema::channel[fl->code()].description(); QString ttip = schema::channel[fl->code()].fullname() + "\n" +
graph->ToolTip(ttip,event->x(),event->y()-15); schema::channel[fl->code()].description();
graph->ToolTip(ttip, event->x(), event->y() - 15);
graph->redraw(); graph->redraw();
} }
} }
} }
} }
return false; return false;
} }
gFlagsLine::gFlagsLine(ChannelID code,QColor flag_color,QString label,bool always_visible,FlagType flt) gFlagsLine::gFlagsLine(ChannelID code, QColor flag_color, QString label, bool always_visible,
:Layer(code),m_label(label),m_always_visible(always_visible),m_flt(flt),m_flag_color(flag_color) FlagType flt)
: Layer(code), m_label(label), m_always_visible(always_visible), m_flt(flt),
m_flag_color(flag_color)
{ {
addVertexBuffer(quads=new gVertexBuffer(2048,GL_QUADS)); addVertexBuffer(quads = new gVertexBuffer(2048, GL_QUADS));
//addGLBuf(lines=new GLBuffer(flag_color,1024,GL_LINES)); //addGLBuf(lines=new GLBuffer(flag_color,1024,GL_LINES));
quads->setAntiAlias(true); quads->setAntiAlias(true);
//lines->setAntiAlias(true); //lines->setAntiAlias(true);
@ -151,80 +174,94 @@ gFlagsLine::~gFlagsLine()
//delete lines; //delete lines;
//delete quads; //delete quads;
} }
void gFlagsLine::paint(gGraph & w,int left, int top, int width, int height) void gFlagsLine::paint(gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) return; if (!m_visible) { return; }
if (!m_day) return;
lines=w.lines(); if (!m_day) { return; }
lines = w.lines();
double minx; double minx;
double maxx; double maxx;
if (w.blockZoom()) { if (w.blockZoom()) {
minx=w.rmin_x; minx = w.rmin_x;
maxx=w.rmax_x; maxx = w.rmax_x;
} else { } else {
minx=w.min_x; minx = w.min_x;
maxx=w.max_x; maxx = w.max_x;
} }
double xx=maxx-minx; double xx = maxx - minx;
if (xx<=0) return;
double xmult=width/xx; if (xx <= 0) { return; }
GetTextExtent(m_label,m_lx,m_ly); double xmult = width / xx;
GetTextExtent(m_label, m_lx, m_ly);
// Draw text label // Draw text label
w.renderText(m_label,left-m_lx-10,top+(height/2)+(m_ly/2)); w.renderText(m_label, left - m_lx - 10, top + (height / 2) + (m_ly / 2));
float x1,x2; float x1, x2;
float bartop=top+2; float bartop = top + 2;
float bottom=top+height-2; float bottom = top + height - 2;
bool verts_exceeded=false; bool verts_exceeded = false;
qint64 X,X2,L; qint64 X, X2, L;
lines->setColor(schema::channel[m_code].defaultColor()); lines->setColor(schema::channel[m_code].defaultColor());
qint64 start; qint64 start;
quint32 * tptr; quint32 *tptr;
EventStoreType *dptr, * eptr; EventStoreType *dptr, * eptr;
int idx; int idx;
QHash<ChannelID,QVector<EventList *> >::iterator cei; QHash<ChannelID, QVector<EventList *> >::iterator cei;
qint64 clockdrift=qint64(PROFILE.cpap->clockDrift()) * 1000L; qint64 clockdrift = qint64(PROFILE.cpap->clockDrift()) * 1000L;
qint64 drift=0; qint64 drift = 0;
for (QList<Session *>::iterator s=m_day->begin();s!=m_day->end(); s++) { for (QList<Session *>::iterator s = m_day->begin(); s != m_day->end(); s++) {
if (!(*s)->enabled()) if (!(*s)->enabled()) {
continue; continue;
drift=((*s)->machine()->GetType()==MT_CPAP) ? clockdrift : 0; }
cei=(*s)->eventlist.find(m_code); drift = ((*s)->machine()->GetType() == MT_CPAP) ? clockdrift : 0;
if (cei==(*s)->eventlist.end())
cei = (*s)->eventlist.find(m_code);
if (cei == (*s)->eventlist.end()) {
continue; continue;
}
QVector<EventList *> & evlist=cei.value(); QVector<EventList *> &evlist = cei.value();
for (int k=0;k<evlist.size();k++) {
EventList & el=*(evlist[k]);
start=el.first() + drift;
tptr=el.rawTime();
dptr=el.rawData();
int np=el.count();
eptr=dptr+np;
for (idx=0;dptr < eptr; dptr++, tptr++, idx++) { for (int k = 0; k < evlist.size(); k++) {
X=start + *tptr; EventList &el = *(evlist[k]);
L=*dptr * 1000; start = el.first() + drift;
if (X >= minx) tptr = el.rawTime();
dptr = el.rawData();
int np = el.count();
eptr = dptr + np;
for (idx = 0; dptr < eptr; dptr++, tptr++, idx++) {
X = start + *tptr;
L = *dptr * 1000;
if (X >= minx) {
break; break;
X2=X-L; }
if (X2 >= minx)
X2 = X - L;
if (X2 >= minx) {
break; break;
}
} }
np-=idx;
if (m_flt==FT_Bar) { np -= idx;
if (m_flt == FT_Bar) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Draw Event Flag Bars // Draw Event Flag Bars
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -232,68 +269,74 @@ void gFlagsLine::paint(gGraph & w,int left, int top, int width, int height)
// Check bounds outside of loop is faster.. // Check bounds outside of loop is faster..
// This will have to be reverted if multithreaded drawing is ever brought back // This will have to be reverted if multithreaded drawing is ever brought back
int rem=lines->Max() - lines->cnt(); int rem = lines->Max() - lines->cnt();
if ((np<<1) > rem) {
if ((np << 1) > rem) {
qDebug() << "gFlagsLine would overfill lines for" << schema::channel[m_code].label(); qDebug() << "gFlagsLine would overfill lines for" << schema::channel[m_code].label();
np=rem >> 1; np = rem >> 1;
verts_exceeded=true; verts_exceeded = true;
} }
for (int i=0;i<np;i++) { for (int i = 0; i < np; i++) {
X=start + *tptr++; X = start + *tptr++;
if (X > maxx) if (X > maxx) {
break; break;
}
x1=(X - minx) * xmult + left; x1 = (X - minx) * xmult + left;
lines->add(x1,bartop,x1,bottom); lines->add(x1, bartop, x1, bottom);
//if (lines->full()) { verts_exceeded=true; break; } //if (lines->full()) { verts_exceeded=true; break; }
} }
} else if (m_flt==FT_Span) { } else if (m_flt == FT_Span) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Draw Event Flag Spans // Draw Event Flag Spans
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
quads->setColor(m_flag_color); quads->setColor(m_flag_color);
int rem=quads->Max() - quads->cnt(); int rem = quads->Max() - quads->cnt();
if ((np<<2) > rem) { if ((np << 2) > rem) {
qDebug() << "gFlagsLine would overfill quads for" << schema::channel[m_code].label(); qDebug() << "gFlagsLine would overfill quads for" << schema::channel[m_code].label();
np=rem >> 2; np = rem >> 2;
verts_exceeded=true; verts_exceeded = true;
} }
for (; dptr < eptr; dptr++) { for (; dptr < eptr; dptr++) {
X=start + * tptr++; X = start + * tptr++;
if (X > maxx) if (X > maxx) {
break; break;
}
L=*dptr * 1000L; L = *dptr * 1000L;
X2=X-L; X2 = X - L;
x1=double(X - minx) * xmult + left; x1 = double(X - minx) * xmult + left;
x2=double(X2 - minx) * xmult + left; x2 = double(X2 - minx) * xmult + left;
quads->add(x2,bartop,x1,bartop, x1,bottom,x2,bottom); quads->add(x2, bartop, x1, bartop, x1, bottom, x2, bottom);
//if (quads->full()) { verts_exceeded=true; break; } //if (quads->full()) { verts_exceeded=true; break; }
} }
} }
if (verts_exceeded) break;
if (verts_exceeded) { break; }
} }
if (verts_exceeded) break;
if (verts_exceeded) { break; }
} }
if (verts_exceeded) { if (verts_exceeded) {
qWarning() << "maxverts exceeded in gFlagsLine::plot()"; qWarning() << "maxverts exceeded in gFlagsLine::plot()";
} }
} }
bool gFlagsLine::mouseMoveEvent(QMouseEvent * event,gGraph * graph) bool gFlagsLine::mouseMoveEvent(QMouseEvent *event, gGraph *graph)
{ {
Q_UNUSED(event) Q_UNUSED(event)
Q_UNUSED(graph) Q_UNUSED(graph)
// qDebug() << code() << event->x() << event->y() << graph->rect(); // qDebug() << code() << event->x() << event->y() << graph->rect();
return false; return false;
} }

View File

@ -20,20 +20,20 @@ class gFlagsGroup;
/*! \class gYSpacer /*! \class gYSpacer
\brief A dummy vertical spacer object \brief A dummy vertical spacer object
*/ */
class gFlagsLabelArea:public gSpacer class gFlagsLabelArea: public gSpacer
{ {
public: public:
gFlagsLabelArea(gFlagsGroup * group); gFlagsLabelArea(gFlagsGroup *group);
virtual void paint(gGraph & w,int left,int top, int width, int height) { virtual void paint(gGraph &w, int left, int top, int width, int height) {
Q_UNUSED(w) Q_UNUSED(w)
Q_UNUSED(left) Q_UNUSED(left)
Q_UNUSED(top) Q_UNUSED(top)
Q_UNUSED(width) Q_UNUSED(width)
Q_UNUSED(height) Q_UNUSED(height)
} }
protected: protected:
gFlagsGroup * m_group; gFlagsGroup *m_group;
virtual bool mouseMoveEvent(QMouseEvent * event,gGraph * graph); virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
}; };
@ -42,63 +42,64 @@ protected:
/*! \class gFlagsLine /*! \class gFlagsLine
\brief One single line of event flags in the Event Flags chart \brief One single line of event flags in the Event Flags chart
*/ */
class gFlagsLine:public Layer class gFlagsLine: public Layer
{ {
friend class gFlagsGroup; friend class gFlagsGroup;
public: public:
/*! \brief Constructs an individual gFlagsLine object /*! \brief Constructs an individual gFlagsLine object
\param code The Channel the data is sourced from \param code The Channel the data is sourced from
\param col The colour to draw this flag \param col The colour to draw this flag
\param label The label to show to the left of the Flags line. \param label The label to show to the left of the Flags line.
\param always_visible Whether to always show this line, even if empty \param always_visible Whether to always show this line, even if empty
\param Type of Flag, either FT_Bar, or FT_Span \param Type of Flag, either FT_Bar, or FT_Span
*/ */
gFlagsLine(ChannelID code,QColor col=Qt::black,QString label="",bool always_visible=false,FlagType flt=FT_Bar); gFlagsLine(ChannelID code, QColor col = Qt::black, QString label = "", bool always_visible = false,
virtual ~gFlagsLine(); FlagType flt = FT_Bar);
virtual ~gFlagsLine();
//! \brief Drawing code to add the flags and span markers to the Vertex buffers. //! \brief Drawing code to add the flags and span markers to the Vertex buffers.
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
//! \brief Returns true if should always show this flag, even if it's empty //! \brief Returns true if should always show this flag, even if it's empty
bool isAlwaysVisible() { return m_always_visible; } bool isAlwaysVisible() { return m_always_visible; }
//! \brief Set this to true to make a flag line always visible //! \brief Set this to true to make a flag line always visible
void setAlwaysVisible(bool b) { m_always_visible=b; } void setAlwaysVisible(bool b) { m_always_visible = b; }
//! \brief Returns the label for this individual Event Flags line //! \brief Returns the label for this individual Event Flags line
QString label() { return m_label; } QString label() { return m_label; }
//! \brief Sets the label for this individual Event Flags line //! \brief Sets the label for this individual Event Flags line
void setLabel(QString s) { m_label=s; } void setLabel(QString s) { m_label = s; }
void setTotalLines(int i) { total_lines=i; } void setTotalLines(int i) { total_lines = i; }
void setLineNum(int i) { line_num=i; } void setLineNum(int i) { line_num = i; }
protected: protected:
virtual bool mouseMoveEvent(QMouseEvent * event,gGraph * graph); virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
QString m_label; QString m_label;
bool m_always_visible; bool m_always_visible;
int total_lines,line_num; int total_lines, line_num;
FlagType m_flt; FlagType m_flt;
QColor m_flag_color; QColor m_flag_color;
gVertexBuffer *quads; gVertexBuffer *quads;
gVertexBuffer *lines; gVertexBuffer *lines;
int m_lx, m_ly; int m_lx, m_ly;
}; };
/*! \class gFlagsGroup /*! \class gFlagsGroup
\brief Contains multiple gFlagsLine entries for the Events Flag graph \brief Contains multiple gFlagsLine entries for the Events Flag graph
*/ */
class gFlagsGroup:public LayerGroup class gFlagsGroup: public LayerGroup
{ {
friend class gFlagsLabelArea; friend class gFlagsLabelArea;
public: public:
gFlagsGroup(); gFlagsGroup();
virtual ~gFlagsGroup(); virtual ~gFlagsGroup();
//! Draw filled rectangles behind Event Flag's, and an outlines around them all, Calls the individual paint for each gFlagLine //! Draw filled rectangles behind Event Flag's, and an outlines around them all, Calls the individual paint for each gFlagLine
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
//! Returns the first time represented by all gFlagLine layers, in milliseconds since epoch //! Returns the first time represented by all gFlagLine layers, in milliseconds since epoch
virtual qint64 Minx(); virtual qint64 Minx();
@ -118,10 +119,10 @@ public:
int barHeight() { return m_barh; } int barHeight() { return m_barh; }
//! Returns a list of Visible gFlagsLine layers to draw //! Returns a list of Visible gFlagsLine layers to draw
QVector<gFlagsLine *> & visibleLayers() { return lvisible; } QVector<gFlagsLine *> &visibleLayers() { return lvisible; }
protected: protected:
virtual bool mouseMoveEvent(QMouseEvent * event,gGraph * graph); virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
gVertexBuffer *quads, *lines; gVertexBuffer *quads, *lines;
QVector<gFlagsLine *> lvisible; QVector<gFlagsLine *> lvisible;

View File

@ -13,11 +13,11 @@
#include "gFooBar.h" #include "gFooBar.h"
#include "gYAxis.h" #include "gYAxis.h"
gShadowArea::gShadowArea(QColor shadow_color,QColor line_color) gShadowArea::gShadowArea(QColor shadow_color, QColor line_color)
:Layer(NoChannel),m_shadow_color(shadow_color),m_line_color(line_color) : Layer(NoChannel), m_shadow_color(shadow_color), m_line_color(line_color)
{ {
addVertexBuffer(quads=new gVertexBuffer(20,GL_QUADS)); addVertexBuffer(quads = new gVertexBuffer(20, GL_QUADS));
addVertexBuffer(lines=new gVertexBuffer(20,GL_LINES)); addVertexBuffer(lines = new gVertexBuffer(20, GL_LINES));
quads->forceAntiAlias(true); quads->forceAntiAlias(true);
lines->setAntiAlias(true); lines->setAntiAlias(true);
lines->setSize(2); lines->setSize(2);
@ -25,108 +25,114 @@ gShadowArea::gShadowArea(QColor shadow_color,QColor line_color)
gShadowArea::~gShadowArea() gShadowArea::~gShadowArea()
{ {
} }
void gShadowArea::paint(gGraph & w,int left, int top, int width, int height) void gShadowArea::paint(gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) return; if (!m_visible) { return; }
double xx=w.max_x-w.min_x;
if (xx==0) double xx = w.max_x - w.min_x;
if (xx == 0) {
return; return;
}
int start_px=left-1; int start_px = left - 1;
int end_px=left+width; int end_px = left + width;
//float h=top; //float h=top;
double rmx=w.rmax_x-w.rmin_x; double rmx = w.rmax_x - w.rmin_x;
double px=((1.0/rmx)*(w.min_x-w.rmin_x))*width; double px = ((1.0 / rmx) * (w.min_x - w.rmin_x)) * width;
double py=((1.0/rmx)*(w.max_x-w.rmin_x))*width; double py = ((1.0 / rmx) * (w.max_x - w.rmin_x)) * width;
quads->add(start_px,top,start_px,top+height,start_px+px, top+height, start_px+px, top,m_shadow_color.rgba()); quads->add(start_px, top, start_px, top + height, start_px + px, top + height, start_px + px, top,
quads->add(start_px+py, top, start_px+py, top+height,end_px, top+height, end_px, top,m_shadow_color.rgba()); m_shadow_color.rgba());
quads->add(start_px + py, top, start_px + py, top + height, end_px, top + height, end_px, top,
m_shadow_color.rgba());
lines->add(start_px+px, top, start_px+py, top,m_line_color.rgba()); lines->add(start_px + px, top, start_px + py, top, m_line_color.rgba());
lines->add(start_px+px, top+height+1, start_px+py, top+height+1,m_line_color.rgba()); lines->add(start_px + px, top + height + 1, start_px + py, top + height + 1, m_line_color.rgba());
} }
gFooBar::gFooBar(int offset,QColor handle_color,QColor line_color) gFooBar::gFooBar(int offset, QColor handle_color, QColor line_color)
:Layer(NoChannel),m_offset(offset),m_handle_color(handle_color),m_line_color(line_color) : Layer(NoChannel), m_offset(offset), m_handle_color(handle_color), m_line_color(line_color)
{ {
} }
gFooBar::~gFooBar() gFooBar::~gFooBar()
{ {
} }
void gFooBar::paint(gGraph & w,int left, int top, int width, int height) void gFooBar::paint(gGraph &w, int left, int top, int width, int height)
{ {
Q_UNUSED(top); Q_UNUSED(top);
Q_UNUSED(left); Q_UNUSED(left);
Q_UNUSED(width); Q_UNUSED(width);
Q_UNUSED(height); Q_UNUSED(height);
if (!m_visible) return;
double xx=w.max_x-w.min_x; if (!m_visible) { return; }
if (xx==0) double xx = w.max_x - w.min_x;
if (xx == 0) {
return; return;
}
//int start_px=left; //int start_px=left;
//int end_px=left+width; //int end_px=left+width;
//float h=top; //float h=top;
/* glLineWidth(1); /* glLineWidth(1);
glBegin(GL_LINES); glBegin(GL_LINES);
w.qglColor(m_line_color); w.qglColor(m_line_color);
glVertex2f(start_px, h); glVertex2f(start_px, h);
glVertex2f(start_px+width, h); glVertex2f(start_px+width, h);
glEnd(); glEnd();
double rmx=w.rmax_x-w.rmin_x; double rmx=w.rmax_x-w.rmin_x;
double px=((1/rmx)*(w.min_x-w.rmin_x))*width; double px=((1/rmx)*(w.min_x-w.rmin_x))*width;
double py=((1/rmx)*(w.max_x-w.rmin_x))*width; double py=((1/rmx)*(w.max_x-w.rmin_x))*width;
int extra=0; int extra=0;
if (fabs(px-py)<2) extra=2; if (fabs(px-py)<2) extra=2;
int hh=25; int hh=25;
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBegin(GL_QUADS); glBegin(GL_QUADS);
w.qglColor(m_handle_color); w.qglColor(m_handle_color);
glVertex2f(start_px+px-extra,top-hh); glVertex2f(start_px+px-extra,top-hh);
glVertex2f(start_px+py+extra,top-hh); glVertex2f(start_px+py+extra,top-hh);
//glColor4ub(255,255,255,128); //glColor4ub(255,255,255,128);
glColor4ub(255,255,255,128); glColor4ub(255,255,255,128);
glVertex2f(start_px+py+extra,top-hh/2.0); glVertex2f(start_px+py+extra,top-hh/2.0);
glVertex2f(start_px+px-extra,top-hh/2.0); glVertex2f(start_px+px-extra,top-hh/2.0);
// glColor4ub(255,255,255,128); // glColor4ub(255,255,255,128);
glColor4ub(255,255,255,128); glColor4ub(255,255,255,128);
glVertex2f(start_px+px-extra,top-hh/2.0); glVertex2f(start_px+px-extra,top-hh/2.0);
glVertex2f(start_px+py+extra,top-hh/2.0); glVertex2f(start_px+py+extra,top-hh/2.0);
w.qglColor(m_handle_color); w.qglColor(m_handle_color);
// glColor4ub(192,192,192,128); // glColor4ub(192,192,192,128);
glVertex2f(start_px+py+extra,h); glVertex2f(start_px+py+extra,h);
glVertex2f(start_px+px-extra,h); glVertex2f(start_px+px-extra,h);
glEnd(); glEnd();
glDisable(GL_BLEND); glDisable(GL_BLEND);
w.qglColor(m_handle_color); w.qglColor(m_handle_color);
glBegin(GL_LINE_LOOP); glBegin(GL_LINE_LOOP);
glVertex2f(start_px+px-extra,top-hh); glVertex2f(start_px+px-extra,top-hh);
glVertex2f(start_px+py+extra,top-hh); glVertex2f(start_px+py+extra,top-hh);
glVertex2f(start_px+py+extra,h); glVertex2f(start_px+py+extra,h);
glVertex2f(start_px+px-extra,h); glVertex2f(start_px+px-extra,h);
glEnd(); glEnd();
glLineWidth(3); glLineWidth(3);
glBegin(GL_LINES); glBegin(GL_LINES);
w.qglColor(m_handle_color); w.qglColor(m_handle_color);
glVertex2f(start_px+px-extra,h); glVertex2f(start_px+px-extra,h);
glVertex2f(start_px+py+extra,h); glVertex2f(start_px+py+extra,h);
glEnd(); glEnd();
glLineWidth(1); */ glLineWidth(1); */
} }

View File

@ -17,34 +17,35 @@
/*! \class gShadowArea /*! \class gShadowArea
\brief Displays a Shadow for all graph areas not highlighted (used in Event Flags) \brief Displays a Shadow for all graph areas not highlighted (used in Event Flags)
*/ */
class gShadowArea:public Layer class gShadowArea: public Layer
{ {
public: public:
gShadowArea(QColor shadow_color=QColor(40,40,40,40),QColor line_color=Qt::blue); gShadowArea(QColor shadow_color = QColor(40, 40, 40, 40), QColor line_color = Qt::blue);
virtual ~gShadowArea(); virtual ~gShadowArea();
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
protected: protected:
QColor m_shadow_color; QColor m_shadow_color;
QColor m_line_color; QColor m_line_color;
gVertexBuffer *quads; gVertexBuffer *quads;
gVertexBuffer *lines; gVertexBuffer *lines;
}; };
/*! \class gFooBar /*! \class gFooBar
\brief Was a kind of scrollbar thingy that used to be used for representing the overall graph areas. \brief Was a kind of scrollbar thingy that used to be used for representing the overall graph areas.
Currently Unused and empty. Currently Unused and empty.
*/ */
class gFooBar:public Layer class gFooBar: public Layer
{ {
public: public:
gFooBar(int offset=10,QColor handle_color=QColor("orange"),QColor line_color=QColor("dark grey")); gFooBar(int offset = 10, QColor handle_color = QColor("orange"),
virtual ~gFooBar(); QColor line_color = QColor("dark grey"));
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual ~gFooBar();
static const int Margin=15; virtual void paint(gGraph &w, int left, int top, int width, int height);
protected: static const int Margin = 15;
int m_offset; protected:
QColor m_handle_color; int m_offset;
QColor m_line_color; QColor m_handle_color;
QColor m_line_color;
}; };
#endif // GFOOBAR_H #endif // GFOOBAR_H

View File

@ -55,7 +55,7 @@ int GetXHeight(QFont *font = defaultfont);
class gGraphView; class gGraphView;
class gGraph; class gGraph;
const int textque_max=512; const int textque_max = 512;
typedef quint32 RGBA; typedef quint32 RGBA;
/*union RGBA { /*union RGBA {
@ -71,9 +71,8 @@ typedef quint32 RGBA;
#ifdef BUILD_WITH_MSVC #ifdef BUILD_WITH_MSVC
__declspec(align(1)) __declspec(align(1))
#endif #endif
struct gVertex struct gVertex {
{ gVertex(GLshort _x, GLshort _y, GLuint _c) { x = _x; y = _y; color = _c; }
gVertex(GLshort _x, GLshort _y, GLuint _c) { x=_x; y=_y; color=_c; }
GLshort x; GLshort x;
GLshort y; GLshort y;
RGBA color; RGBA color;
@ -87,22 +86,22 @@ class gVertexBuffer
{ {
public: public:
gVertexBuffer(int max = 2048, int type = GL_LINES) gVertexBuffer(int max = 2048, int type = GL_LINES)
: m_max(max), m_type(type), m_cnt(0), m_size(1), : m_max(max), m_type(type), m_cnt(0), m_size(1),
m_scissor(false), m_antialias(false), m_forceantialias(false), m_stippled(false), m_scissor(false), m_antialias(false), m_forceantialias(false), m_stippled(false),
buffer(NULL), buffer(NULL),
s_x(0), s_y(0), s_width(0), s_height(0), s_x(0), s_y(0), s_width(0), s_height(0),
m_color(0), m_color(0),
m_stipple(0xffff), m_stipple(0xffff),
m_blendfunc1(GL_SRC_ALPHA), m_blendfunc1(GL_SRC_ALPHA),
m_blendfunc2(GL_ONE_MINUS_SRC_ALPHA) m_blendfunc2(GL_ONE_MINUS_SRC_ALPHA) {
{
// FIXME: Really should not allocate in constructor. // FIXME: Really should not allocate in constructor.
buffer = (gVertex *)calloc(max, sizeof(gVertex)); buffer = (gVertex *)calloc(max, sizeof(gVertex));
} }
~gVertexBuffer() { ~gVertexBuffer() {
if (buffer) if (buffer) {
free(buffer); free(buffer);
}
} }
void add(GLshort x1, GLshort y1, RGBA color); void add(GLshort x1, GLshort y1, RGBA color);
@ -183,14 +182,14 @@ class GLBuffer
{ {
public: public:
GLBuffer(int max = 2048, int type = GL_LINES, bool stippled = false) GLBuffer(int max = 2048, int type = GL_LINES, bool stippled = false)
: m_max(max), m_type(type), m_cnt(0), m_colcnt(0), m_size(1), : m_max(max), m_type(type), m_cnt(0), m_colcnt(0), m_size(1),
s1(0), s2(0), s3(0), s4(0), s1(0), s2(0), s3(0), s4(0),
m_scissor(false), m_scissor(false),
m_antialias(true), m_antialias(true),
m_forceantialias(false), m_forceantialias(false),
m_stippled(stippled), m_stippled(stippled),
m_blendfunc1(GL_SRC_ALPHA), m_blendfunc1(GL_SRC_ALPHA),
m_blendfunc2(GL_ONE_MINUS_SRC_ALPHA) m_blendfunc2(GL_ONE_MINUS_SRC_ALPHA)
{ } { }
virtual ~GLBuffer() {} virtual ~GLBuffer() {}
@ -199,7 +198,7 @@ class GLBuffer
s2 = y1; s2 = y1;
s3 = x2; s3 = x2;
s4 = y2; s4 = y2;
m_scissor=true; m_scissor = true;
} }
int Max() const { return m_max; } int Max() const { return m_max; }
@ -215,7 +214,7 @@ class GLBuffer
void setColor(QColor col) { m_color = col; } void setColor(QColor col) { m_color = col; }
void setBlendFunc(GLuint b1, GLuint b2) { m_blendfunc1 = b1; m_blendfunc2 = b2; } void setBlendFunc(GLuint b1, GLuint b2) { m_blendfunc1 = b1; m_blendfunc2 = b2; }
virtual void draw(){} virtual void draw() {}
protected: protected:
int m_max; int m_max;
@ -290,8 +289,7 @@ class GLFloatBuffer : public GLBuffer
/*! \struct TextQue /*! \struct TextQue
\brief Holds a single item of text for the drawing queue \brief Holds a single item of text for the drawing queue
*/ */
struct TextQue struct TextQue {
{
//! \variable contains the x axis screen position to draw the text //! \variable contains the x axis screen position to draw the text
short x; short x;
//! \variable contains the y axis screen position to draw the text //! \variable contains the y axis screen position to draw the text
@ -315,10 +313,10 @@ class MyScrollBar : public QScrollBar
{ {
public: public:
MyScrollBar(QWidget *parent = NULL) MyScrollBar(QWidget *parent = NULL)
: QScrollBar(parent) : QScrollBar(parent)
{ } { }
void SendWheelEvent(QWheelEvent * e) { void SendWheelEvent(QWheelEvent *e) {
wheelEvent(e); wheelEvent(e);
} }
}; };
@ -335,29 +333,29 @@ class Layer
public: public:
Layer(ChannelID code) Layer(ChannelID code)
: m_refcount(0), : m_refcount(0),
m_day(NULL), m_day(NULL),
m_visible(true), m_visible(true),
m_movable(false), m_movable(false),
m_minx(0), m_maxx(0), m_minx(0), m_maxx(0),
m_miny(0), m_maxy(0), m_miny(0), m_maxy(0),
m_physminy(0), m_physmaxy(0), m_physminy(0), m_physmaxy(0),
m_code(code), m_code(code),
m_width(0), m_height(0), m_width(0), m_height(0),
m_X(0), m_Y(0), m_X(0), m_Y(0),
m_order(0), m_order(0),
m_position(LayerCenter) m_position(LayerCenter)
{ } { }
virtual ~Layer(); virtual ~Layer();
//! \brief This gets called on day selection, allowing this layer to precalculate any drawing data //! \brief This gets called on day selection, allowing this layer to precalculate any drawing data
virtual void SetDay(Day * d); virtual void SetDay(Day *d);
//! \brief Set the ChannelID used in this layer //! \brief Set the ChannelID used in this layer
virtual void SetCode(ChannelID c) { m_code = c; } virtual void SetCode(ChannelID c) { m_code = c; }
//! \brief Return the ChannelID used in this layer //! \brief Return the ChannelID used in this layer
const ChannelID & code() { return m_code; } const ChannelID &code() { return m_code; }
//! \brief returns true if this layer contains no data. //! \brief returns true if this layer contains no data.
virtual bool isEmpty(); virtual bool isEmpty();
@ -417,7 +415,7 @@ class Layer
\param int width \param int width
\param int height \param int height
*/ */
virtual void paint(gGraph & gv,int left,int top,int width, int height) = 0; virtual void paint(gGraph &gv, int left, int top, int width, int height) = 0;
//! \brief Set the layout position and order for this layer. //! \brief Set the layout position and order for this layer.
void setLayout(LayerPosition position, short width, short height, short order); void setLayout(LayerPosition position, short width, short height, short order);
@ -470,27 +468,39 @@ class Layer
//! \brief Mouse wheel moved somewhere over this layer //! \brief Mouse wheel moved somewhere over this layer
virtual bool wheelEvent(QWheelEvent *event, gGraph *graph) { virtual bool wheelEvent(QWheelEvent *event, gGraph *graph) {
Q_UNUSED(event); Q_UNUSED(graph); return false; Q_UNUSED(event);
Q_UNUSED(graph);
return false;
} }
//! \brief Mouse moved somewhere over this layer //! \brief Mouse moved somewhere over this layer
virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph) { virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph) {
Q_UNUSED(event); Q_UNUSED(graph); return false; Q_UNUSED(event);
Q_UNUSED(graph);
return false;
} }
//! \brief Mouse left or right button pressed somewhere on this layer //! \brief Mouse left or right button pressed somewhere on this layer
virtual bool mousePressEvent(QMouseEvent *event, gGraph *graph) { virtual bool mousePressEvent(QMouseEvent *event, gGraph *graph) {
Q_UNUSED(event); Q_UNUSED(graph); return false; Q_UNUSED(event);
Q_UNUSED(graph);
return false;
} }
//! \brief Mouse button released that was originally pressed somewhere on this layer //! \brief Mouse button released that was originally pressed somewhere on this layer
virtual bool mouseReleaseEvent(QMouseEvent *event, gGraph *graph) { virtual bool mouseReleaseEvent(QMouseEvent *event, gGraph *graph) {
Q_UNUSED(event); Q_UNUSED(graph); return false; Q_UNUSED(event);
Q_UNUSED(graph);
return false;
} }
//! \brief Mouse button double clicked somewhere on this layer //! \brief Mouse button double clicked somewhere on this layer
virtual bool mouseDoubleClickEvent(QMouseEvent *event, gGraph *graph) { virtual bool mouseDoubleClickEvent(QMouseEvent *event, gGraph *graph) {
Q_UNUSED(event); Q_UNUSED(graph); return false; Q_UNUSED(event);
Q_UNUSED(graph);
return false;
} }
//! \brief A key was pressed on the keyboard while the graph area was focused. //! \brief A key was pressed on the keyboard while the graph area was focused.
virtual bool keyPressEvent(QKeyEvent *event, gGraph *graph) { virtual bool keyPressEvent(QKeyEvent *event, gGraph *graph) {
Q_UNUSED(event); Q_UNUSED(graph); return false; Q_UNUSED(event);
Q_UNUSED(graph);
return false;
} }
}; };
@ -501,7 +511,7 @@ class LayerGroup : public Layer
{ {
public: public:
LayerGroup() LayerGroup()
: Layer(NoChannel) : Layer(NoChannel)
{ } { }
virtual ~LayerGroup(); virtual ~LayerGroup();
@ -533,27 +543,27 @@ class LayerGroup : public Layer
//! \brief Return the list of Layers this object holds //! \brief Return the list of Layers this object holds
QVector<Layer *> &getLayers() { return layers; } QVector<Layer *> &getLayers() { return layers; }
protected: protected:
//! \brief Contains all Layer objects in this group //! \brief Contains all Layer objects in this group
QVector<Layer *> layers; QVector<Layer *> layers;
//! \brief Mouse wheel moved somewhere over this LayerGroup //! \brief Mouse wheel moved somewhere over this LayerGroup
virtual bool wheelEvent(QWheelEvent * event, gGraph * graph); virtual bool wheelEvent(QWheelEvent *event, gGraph *graph);
//! \brief Mouse moved somewhere over this LayerGroup //! \brief Mouse moved somewhere over this LayerGroup
virtual bool mouseMoveEvent(QMouseEvent * event, gGraph * graph); virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
//! \brief Mouse left or right button pressed somewhere on this LayerGroup //! \brief Mouse left or right button pressed somewhere on this LayerGroup
virtual bool mousePressEvent(QMouseEvent * event, gGraph * graph); virtual bool mousePressEvent(QMouseEvent *event, gGraph *graph);
//! \brief Mouse button released that was originally pressed somewhere on this LayerGroup //! \brief Mouse button released that was originally pressed somewhere on this LayerGroup
virtual bool mouseReleaseEvent(QMouseEvent * event, gGraph * graph); virtual bool mouseReleaseEvent(QMouseEvent *event, gGraph *graph);
//! \brief Mouse button double clicked somewhere on this layerGroup //! \brief Mouse button double clicked somewhere on this layerGroup
virtual bool mouseDoubleClickEvent(QMouseEvent * event, gGraph * graph); virtual bool mouseDoubleClickEvent(QMouseEvent *event, gGraph *graph);
//! \brief A key was pressed on the keyboard while the graph area was focused. //! \brief A key was pressed on the keyboard while the graph area was focused.
virtual bool keyPressEvent(QKeyEvent * event, gGraph * graph); virtual bool keyPressEvent(QKeyEvent *event, gGraph *graph);
}; };
class gGraph; class gGraph;
@ -720,13 +730,13 @@ class gGraph : public QObject
QString title() { return m_title; } QString title() { return m_title; }
//! \brief Sets the Graph's (vertical) title //! \brief Sets the Graph's (vertical) title
void setTitle(const QString title) { m_title=title; } void setTitle(const QString title) { m_title = title; }
//! \brief Returns the measurement Units the Y scale is referring to //! \brief Returns the measurement Units the Y scale is referring to
QString units() { return m_units; } QString units() { return m_units; }
//! \brief Sets the measurement Units the Y scale is referring to //! \brief Sets the measurement Units the Y scale is referring to
void setUnits(const QString units) { m_units=units; } void setUnits(const QString units) { m_units = units; }
//virtual void repaint(); // Repaint individual graph.. //virtual void repaint(); // Repaint individual graph..
@ -821,7 +831,7 @@ class gGraph : public QObject
void setDay(Day *day); void setDay(Day *day);
//! \brief Returns the current day object //! \brief Returns the current day object
Day * day() { return m_day; } Day *day() { return m_day; }
//! \brief The Layer, layout and title drawing code //! \brief The Layer, layout and title drawing code
virtual void paint(int originX, int originY, int width, int height); virtual void paint(int originX, int originY, int width, int height);
@ -837,8 +847,10 @@ class gGraph : public QObject
//! \brief Sets the margins for the four sides of this graph. //! \brief Sets the margins for the four sides of this graph.
void setMargins(short left, short right, short top, short bottom) { void setMargins(short left, short right, short top, short bottom) {
m_marginleft = left; m_marginright = right; m_marginleft = left;
m_margintop = top; m_marginbottom = bottom; m_marginright = right;
m_margintop = top;
m_marginbottom = bottom;
} }
//! \brief Returns this graphs left margin //! \brief Returns this graphs left margin
@ -862,7 +874,7 @@ class gGraph : public QObject
const inline QRect &rect() const { return m_rect; } const inline QRect &rect() const { return m_rect; }
bool isPinned() { return m_pinned; } bool isPinned() { return m_pinned; }
void setPinned(bool b) { m_pinned=b; } void setPinned(bool b) { m_pinned = b; }
// //! \brief Returns the main gGraphView objects gVertexBuffer stippled line list. // //! \brief Returns the main gGraphView objects gVertexBuffer stippled line list.
//GLShortBuffer * stippled(); //GLShortBuffer * stippled();
@ -921,7 +933,7 @@ class gGraph : public QObject
//! \brief Vector containing all this graphs Layers //! \brief Vector containing all this graphs Layers
QVector<Layer *> m_layers; QVector<Layer *> m_layers;
float m_height,m_width; float m_height, m_width;
int m_min_height; int m_min_height;
int m_max_height; int m_max_height;
@ -950,8 +962,7 @@ class gGraph : public QObject
\brief My version of Pixmap cache with texture binding support \brief My version of Pixmap cache with texture binding support
*/ */
struct myPixmapCache struct myPixmapCache {
{
quint64 last_used; quint64 last_used;
QImage image; QImage image;
GLuint textureID; GLuint textureID;
@ -1098,8 +1109,8 @@ class gGraphView : public QGLWidget
void setCubeImage(QImage *); void setCubeImage(QImage *);
inline const float & devicePixelRatio() { return m_dpr; } inline const float &devicePixelRatio() { return m_dpr; }
void setDevicePixelRatio(float dpr) { m_dpr=dpr; } void setDevicePixelRatio(float dpr) { m_dpr = dpr; }
// Cube fun // Cube fun
QVector<QImage *> cubeimg; QVector<QImage *> cubeimg;
@ -1108,15 +1119,15 @@ class gGraphView : public QGLWidget
#ifdef ENABLE_THREADED_DRAWING #ifdef ENABLE_THREADED_DRAWING
QMutex text_mutex; QMutex text_mutex;
QMutex gl_mutex; QMutex gl_mutex;
QSemaphore * masterlock; QSemaphore *masterlock;
bool useThreads() { return m_idealthreads>1; } bool useThreads() { return m_idealthreads > 1; }
QVector<gThread *> m_threads; QVector<gThread *> m_threads;
int m_idealthreads; int m_idealthreads;
QMutex dl_mutex; QMutex dl_mutex;
#endif #endif
//! \brief Sends day object to be distributed to all Graphs Layers objects //! \brief Sends day object to be distributed to all Graphs Layers objects
void setDay(Day * day); void setDay(Day *day);
gVertexBuffer *lines, *backlines, *quads, *frontlines; gVertexBuffer *lines, *backlines, *quads, *frontlines;
@ -1144,7 +1155,7 @@ class gGraphView : public QGLWidget
//! \brief Return whether or not the Pixmap Cache for text rendering is being used. //! \brief Return whether or not the Pixmap Cache for text rendering is being used.
bool usePixmapCache(); bool usePixmapCache();
protected: protected:
//! \brief Set up the OpenGL basics for the QGLWidget underneath //! \brief Set up the OpenGL basics for the QGLWidget underneath
virtual void initializeGL(); virtual void initializeGL();
@ -1202,7 +1213,7 @@ protected:
QVector<gGraph *> m_graphs; QVector<gGraph *> m_graphs;
//! \brief List of all graphs contained, indexed by title //! \brief List of all graphs contained, indexed by title
QHash<QString,gGraph*> m_graphsbytitle; QHash<QString, gGraph *> m_graphsbytitle;
//! \variable Vertical scroll offset (adjusted when scrollbar gets moved) //! \variable Vertical scroll offset (adjusted when scrollbar gets moved)
int m_offsetY; int m_offsetY;
@ -1221,7 +1232,7 @@ protected:
QPoint m_sizer_point; QPoint m_sizer_point;
int m_horiz_travel; int m_horiz_travel;
MyScrollBar * m_scrollbar; MyScrollBar *m_scrollbar;
QTimer *redrawtimer; QTimer *redrawtimer;
bool m_graph_dragging; bool m_graph_dragging;
@ -1231,13 +1242,13 @@ protected:
TextQue m_textque[textque_max]; TextQue m_textque[textque_max];
int m_textque_items; int m_textque_items;
int m_lastxpos,m_lastypos; int m_lastxpos, m_lastypos;
QString m_emptytext; QString m_emptytext;
bool m_showsplitter; bool m_showsplitter;
qint64 m_minx,m_maxx; qint64 m_minx, m_maxx;
float print_scaleX,print_scaleY; float print_scaleX, print_scaleY;
QPixmap previous_day_snapshot; QPixmap previous_day_snapshot;
QPixmap current_day_snapshot; QPixmap current_day_snapshot;
@ -1253,13 +1264,13 @@ protected:
QTime m_animationStarted; QTime m_animationStarted;
// turn this into a struct later.. // turn this into a struct later..
QHash<QString,myPixmapCache *> pixmap_cache; QHash<QString, myPixmapCache *> pixmap_cache;
qint32 pixmap_cache_size; qint32 pixmap_cache_size;
bool use_pixmap_cache; bool use_pixmap_cache;
QTime horizScrollTime, vertScrollTime; QTime horizScrollTime, vertScrollTime;
public slots: public slots:
//! \brief Callback from the ScrollBar, to change scroll position //! \brief Callback from the ScrollBar, to change scroll position
void scrollbarValueChanged(int val); void scrollbarValueChanged(int val);

File diff suppressed because it is too large Load Diff

View File

@ -21,15 +21,15 @@
/*! \class AHIChart /*! \class AHIChart
\brief Another graph calculating the AHI/hour, this one looks at all the sessions for a day. Currently Unused. \brief Another graph calculating the AHI/hour, this one looks at all the sessions for a day. Currently Unused.
*/ */
class AHIChart:public Layer class AHIChart: public Layer
{ {
public: public:
//! \brief Constructs an AHIChart object, with QColor col for the line plots. //! \brief Constructs an AHIChart object, with QColor col for the line plots.
AHIChart(QColor col=QColor("black")); AHIChart(QColor col = QColor("black"));
~AHIChart(); ~AHIChart();
//! \brief Draws the precalculated data to the Vertex buffers //! \brief Draws the precalculated data to the Vertex buffers
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
//! \brief AHI/hr Calculations are done for this day here. //! \brief AHI/hr Calculations are done for this day here.
//! This also uses the sliding window method //! This also uses the sliding window method
@ -42,9 +42,9 @@ public:
virtual EventDataType Maxy() { return m_maxy; } virtual EventDataType Maxy() { return m_maxy; }
//! \brief Returns true if no data was available //! \brief Returns true if no data was available
virtual bool isEmpty() { return m_data.size()==0; } virtual bool isEmpty() { return m_data.size() == 0; }
protected: protected:
//! \brief Contains the plot data (Y-axis) generated for this day //! \brief Contains the plot data (Y-axis) generated for this day
QVector<EventDataType> m_data; QVector<EventDataType> m_data;
@ -54,89 +54,90 @@ protected:
EventDataType m_miny; EventDataType m_miny;
EventDataType m_maxy; EventDataType m_maxy;
QColor m_color; QColor m_color;
gVertexBuffer * lines; gVertexBuffer *lines;
}; };
/*! \class gLineChart /*! \class gLineChart
\brief Draws a 2D linechart from all Session data in a day. EVL_Waveforms typed EventLists are accelerated. \brief Draws a 2D linechart from all Session data in a day. EVL_Waveforms typed EventLists are accelerated.
*/ */
class gLineChart:public Layer class gLineChart: public Layer
{ {
public: public:
/*! \brief Creates a new 2D gLineChart Layer /*! \brief Creates a new 2D gLineChart Layer
\param code The Channel that gets drawn by this layer \param code The Channel that gets drawn by this layer
\param col Color of the Plot \param col Color of the Plot
\param square_plot Whether or not to use square plots (only effective for EVL_Event typed EventList data) \param square_plot Whether or not to use square plots (only effective for EVL_Event typed EventList data)
\param disable_accel Whether or not to disable acceleration for EVL_Waveform typed EventList data \param disable_accel Whether or not to disable acceleration for EVL_Waveform typed EventList data
*/ */
gLineChart(ChannelID code,const QColor col=QColor("black"), bool square_plot=false,bool disable_accel=false); gLineChart(ChannelID code, const QColor col = QColor("black"), bool square_plot = false,
virtual ~gLineChart(); bool disable_accel = false);
virtual ~gLineChart();
//! \brief The drawing code that fills the vertex buffers //! \brief The drawing code that fills the vertex buffers
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
//! \brief Set Use Square plots for non EVL_Waveform data //! \brief Set Use Square plots for non EVL_Waveform data
void SetSquarePlot(bool b) { m_square_plot=b; } void SetSquarePlot(bool b) { m_square_plot = b; }
//! \brief Returns true if using Square plots for non EVL_Waveform data //! \brief Returns true if using Square plots for non EVL_Waveform data
bool GetSquarePlot() { return m_square_plot; } bool GetSquarePlot() { return m_square_plot; }
//! \brief Set this if you want this layer to draw it's empty data message //! \brief Set this if you want this layer to draw it's empty data message
//! They don't show anymore due to the changes in gGraphView. Should modify isEmpty if this still gets to live //! They don't show anymore due to the changes in gGraphView. Should modify isEmpty if this still gets to live
void ReportEmpty(bool b) { m_report_empty=b; } void ReportEmpty(bool b) { m_report_empty = b; }
//! \brief Returns whether or not to show the empty text message //! \brief Returns whether or not to show the empty text message
bool GetReportEmpty() { return m_report_empty; } bool GetReportEmpty() { return m_report_empty; }
//! \brief Sets the ability to Disable waveform plot acceleration (which hides unseen data) //! \brief Sets the ability to Disable waveform plot acceleration (which hides unseen data)
void setDisableAccel(bool b) { m_disable_accel=b; } void setDisableAccel(bool b) { m_disable_accel = b; }
//! \brief Returns true if waveform plot acceleration is disabled //! \brief Returns true if waveform plot acceleration is disabled
bool disableAccel() { return m_disable_accel; } bool disableAccel() { return m_disable_accel; }
//! \brief Sets the Day object containing the Sessions this linechart draws from //! \brief Sets the Day object containing the Sessions this linechart draws from
virtual void SetDay(Day *d); virtual void SetDay(Day *d);
//! \brief Returns Minimum Y-axis value for this layer //! \brief Returns Minimum Y-axis value for this layer
virtual EventDataType Miny(); virtual EventDataType Miny();
//! \brief Returns Maximum Y-axis value for this layer //! \brief Returns Maximum Y-axis value for this layer
virtual EventDataType Maxy(); virtual EventDataType Maxy();
//! \brief Returns true if all subplots contain no data //! \brief Returns true if all subplots contain no data
virtual bool isEmpty(); virtual bool isEmpty();
//! \brief Add Subplot 'code'. Note the first one is added in the constructor. //! \brief Add Subplot 'code'. Note the first one is added in the constructor.
void addPlot(ChannelID code, QColor color, bool square) { m_codes.push_back(code); m_colors.push_back(color); m_enabled[code]=true; m_square.push_back(square); } void addPlot(ChannelID code, QColor color, bool square) { m_codes.push_back(code); m_colors.push_back(color); m_enabled[code] = true; m_square.push_back(square); }
//! \brief Returns true of the subplot 'code' is enabled. //! \brief Returns true of the subplot 'code' is enabled.
bool plotEnabled(ChannelID code) { if ((m_enabled.contains(code)) && m_enabled[code]) return true; else return false; } bool plotEnabled(ChannelID code) { if ((m_enabled.contains(code)) && m_enabled[code]) { return true; } else { return false; } }
//! \brief Enable or Disable the subplot identified by code. //! \brief Enable or Disable the subplot identified by code.
void setPlotEnabled(ChannelID code, bool b) { m_enabled[code]=b; } void setPlotEnabled(ChannelID code, bool b) { m_enabled[code] = b; }
protected: protected:
bool m_report_empty; bool m_report_empty;
bool m_square_plot; bool m_square_plot;
bool m_disable_accel; bool m_disable_accel;
QColor m_line_color; QColor m_line_color;
gVertexBuffer * lines; gVertexBuffer *lines;
//GLShortBuffer * lines; //GLShortBuffer * lines;
//GLShortBuffer * outlines; //GLShortBuffer * outlines;
//! \brief Used by accelerated waveform plots. Must be >= Screen Resolution (or at least graph width) //! \brief Used by accelerated waveform plots. Must be >= Screen Resolution (or at least graph width)
static const int max_drawlist_size=10000; static const int max_drawlist_size = 10000;
//! \brief The list of screen points used for accelerated waveform plots.. //! \brief The list of screen points used for accelerated waveform plots..
QPoint m_drawlist[max_drawlist_size]; QPoint m_drawlist[max_drawlist_size];
int subtract_offset; int subtract_offset;
QVector<ChannelID> m_codes; QVector<ChannelID> m_codes;
QVector<QColor> m_colors; QVector<QColor> m_colors;
QVector<bool> m_square; QVector<bool> m_square;
QHash<ChannelID,bool> m_enabled; QHash<ChannelID, bool> m_enabled;
}; };
#endif // GLINECHART_H #endif // GLINECHART_H

View File

@ -13,13 +13,13 @@
#include "SleepLib/profiles.h" #include "SleepLib/profiles.h"
#include "gLineOverlay.h" #include "gLineOverlay.h"
gLineOverlayBar::gLineOverlayBar(ChannelID code,QColor color,QString label,FlagType flt) gLineOverlayBar::gLineOverlayBar(ChannelID code, QColor color, QString label, FlagType flt)
:Layer(code),m_flag_color(color),m_label(label),m_flt(flt) : Layer(code), m_flag_color(color), m_label(label), m_flt(flt)
{ {
addVertexBuffer(points=new gVertexBuffer(2048,GL_POINTS)); addVertexBuffer(points = new gVertexBuffer(2048, GL_POINTS));
points->setSize(4); points->setSize(4);
points->setColor(m_flag_color); points->setColor(m_flag_color);
addVertexBuffer(quads=new gVertexBuffer(2048,GL_QUADS)); addVertexBuffer(quads = new gVertexBuffer(2048, GL_QUADS));
//addGLBuf(lines=new GLBuffer(color,1024,GL_LINES)); //addGLBuf(lines=new GLBuffer(color,1024,GL_LINES));
points->setAntiAlias(true); points->setAntiAlias(true);
quads->setAntiAlias(true); quads->setAntiAlias(true);
@ -33,186 +33,225 @@ gLineOverlayBar::~gLineOverlayBar()
//delete points; //delete points;
} }
void gLineOverlayBar::paint(gGraph & w, int left, int topp, int width, int height) void gLineOverlayBar::paint(gGraph &w, int left, int topp, int width, int height)
{ {
if (!m_visible) return; if (!m_visible) { return; }
if (!m_day) return;
gVertexBuffer * lines=w.lines(); if (!m_day) { return; }
int start_py=topp;
double xx=w.max_x-w.min_x; gVertexBuffer *lines = w.lines();
double yy=w.max_y-w.min_y; int start_py = topp;
if (xx<=0) return;
float x1,x2; double xx = w.max_x - w.min_x;
double yy = w.max_y - w.min_y;
int x,y; if (xx <= 0) { return; }
float bottom=start_py+height-25*w.printScaleY(), top=start_py+25*w.printScaleY(); float x1, x2;
int x, y;
float bottom = start_py + height - 25 * w.printScaleY(), top = start_py + 25 * w.printScaleY();
double X; double X;
double Y; double Y;
bool verts_exceeded=false; bool verts_exceeded = false;
m_count=0; m_count = 0;
m_sum=0; m_sum = 0;
m_flag_color=schema::channel[m_code].defaultColor(); m_flag_color = schema::channel[m_code].defaultColor();
lines->setColor(m_flag_color); lines->setColor(m_flag_color);
points->setColor(m_flag_color); points->setColor(m_flag_color);
if (m_flt==FT_Span) {
if (m_flt == FT_Span) {
m_flag_color.setAlpha(128); m_flag_color.setAlpha(128);
} }
EventStoreType raw; EventStoreType raw;
quint32 * tptr; quint32 *tptr;
EventStoreType * dptr, *eptr; EventStoreType *dptr, *eptr;
qint64 stime; qint64 stime;
OverlayDisplayType odt=PROFILE.appearance->overlayType(); OverlayDisplayType odt = PROFILE.appearance->overlayType();
QHash<ChannelID,QVector<EventList *> >::iterator cei; QHash<ChannelID, QVector<EventList *> >::iterator cei;
int count; int count;
qint64 clockdrift=qint64(PROFILE.cpap->clockDrift()) * 1000L; qint64 clockdrift = qint64(PROFILE.cpap->clockDrift()) * 1000L;
qint64 drift=0; qint64 drift = 0;
// For each session, process it's eventlist // For each session, process it's eventlist
for (QList<Session *>::iterator s=m_day->begin();s!=m_day->end(); s++) { for (QList<Session *>::iterator s = m_day->begin(); s != m_day->end(); s++) {
if (!(*s)->enabled()) continue; if (!(*s)->enabled()) { continue; }
cei=(*s)->eventlist.find(m_code);
if (cei==(*s)->eventlist.end()) continue; cei = (*s)->eventlist.find(m_code);
QVector<EventList *> & evlist=cei.value();
if (evlist.size()==0) continue; if (cei == (*s)->eventlist.end()) { continue; }
drift=((*s)->machine()->GetType()==MT_CPAP) ? clockdrift : 0;
QVector<EventList *> &evlist = cei.value();
if (evlist.size() == 0) { continue; }
drift = ((*s)->machine()->GetType() == MT_CPAP) ? clockdrift : 0;
// Could loop through here, but nowhere uses more than one yet.. // Could loop through here, but nowhere uses more than one yet..
for (int k=0;k<evlist.size();k++) { for (int k = 0; k < evlist.size(); k++) {
EventList & el=*(evlist[k]); EventList &el = *(evlist[k]);
count=el.count(); count = el.count();
stime=el.first() + drift; stime = el.first() + drift;
dptr=el.rawData(); dptr = el.rawData();
eptr=dptr+count; eptr = dptr + count;
tptr=el.rawTime(); tptr = el.rawTime();
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Skip data previous to minx bounds // Skip data previous to minx bounds
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
for (; dptr < eptr; dptr++) { for (; dptr < eptr; dptr++) {
X=stime + *tptr; X = stime + *tptr;
if (X >= w.min_x)
if (X >= w.min_x) {
break; break;
}
tptr++; tptr++;
} }
if (m_flt==FT_Span) { if (m_flt == FT_Span) {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// FT_Span // FT_Span
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
for (;dptr < eptr; dptr++) { for (; dptr < eptr; dptr++) {
X=stime + *tptr++; X = stime + *tptr++;
raw=*dptr; raw = *dptr;
Y=X-(qint64(raw)*1000.0L); // duration Y = X - (qint64(raw) * 1000.0L); // duration
if (Y > w.max_x)
if (Y > w.max_x) {
break; break;
x1=double(width)/double(xx)*double(X-w.min_x)+left; }
x1 = double(width) / double(xx) * double(X - w.min_x) + left;
m_count++; m_count++;
m_sum+=raw; m_sum += raw;
x2=double(width)/double(xx)*double(Y-w.min_x)+left; x2 = double(width) / double(xx) * double(Y - w.min_x) + left;
if (int(x1)==int(x2)) if (int(x1) == int(x2)) {
x2+=1; x2 += 1;
if (x2<left) }
x2=left;
if (x1>width+left) if (x2 < left) {
x1=width+left; x2 = left;
}
if (x1 > width + left) {
x1 = width + left;
}
quads->add(x2, start_py, x1, start_py, x1, start_py + height, x2, start_py + height,
m_flag_color.rgba());
quads->add(x2,start_py, x1,start_py, x1,start_py+height, x2,start_py+height,m_flag_color.rgba());
if (quads->full()) { if (quads->full()) {
verts_exceeded=true; verts_exceeded = true;
break; break;
} }
} }
} else if (m_flt==FT_Dot) { } else if (m_flt == FT_Dot) {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// FT_Dot // FT_Dot
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
for (; dptr < eptr; dptr++) { for (; dptr < eptr; dptr++) {
X=stime + *tptr++; //el.time(i); X = stime + *tptr++; //el.time(i);
raw=*dptr; //el.data(i); raw = *dptr; //el.data(i);
if (X > w.max_x)
if (X > w.max_x) {
break; break;
x1=double(width)/double(xx)*double(X-w.min_x)+left; }
x1 = double(width) / double(xx) * double(X - w.min_x) + left;
m_count++; m_count++;
m_sum+=raw; m_sum += raw;
if ((odt==ODT_Bars) || (xx<3600000)) {
if ((odt == ODT_Bars) || (xx < 3600000)) {
// show the fat dots in the middle // show the fat dots in the middle
points->add(x1,double(height)/double(yy)*double(-20-w.min_y)+topp); points->add(x1, double(height) / double(yy)*double(-20 - w.min_y) + topp);
if (points->full()) { if (points->full()) {
verts_exceeded=true; verts_exceeded = true;
break; break;
} }
} else { } else {
// thin lines down the bottom // thin lines down the bottom
lines->add(x1,start_py+1,x1,start_py+1+12); lines->add(x1, start_py + 1, x1, start_py + 1 + 12);
if (lines->full()) { if (lines->full()) {
verts_exceeded=true; verts_exceeded = true;
break; break;
} }
} }
} }
} else if (m_flt==FT_Bar) { } else if (m_flt == FT_Bar) {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// FT_Bar // FT_Bar
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
for (; dptr < eptr; dptr++) { for (; dptr < eptr; dptr++) {
X=stime + *tptr++; X = stime + *tptr++;
raw=*dptr; raw = *dptr;
if (X > w.max_x)
break; if (X > w.max_x) {
x1=double(width)/double(xx)*double(X-w.min_x)+left; break;
m_count++; }
m_sum+=raw;
int z=start_py+height; x1 = double(width) / double(xx) * double(X - w.min_x) + left;
if ((odt==ODT_Bars) || (xx<3600000)) { m_count++;
z=top; m_sum += raw;
int z = start_py + height;
if ((odt == ODT_Bars) || (xx < 3600000)) {
z = top;
points->add(x1, top);
lines->add(x1, top, x1, bottom);
points->add(x1,top);
lines->add(x1,top,x1,bottom);
if (points->full()) { if (points->full()) {
verts_exceeded=true; verts_exceeded = true;
break; break;
} }
} else { } else {
lines->add(x1,z,x1,z-12); lines->add(x1, z, x1, z - 12);
} }
if (lines->full()) { if (lines->full()) {
verts_exceeded=true; verts_exceeded = true;
break; break;
} }
if (xx<(1800000)) {
GetTextExtent(m_label,x,y); if (xx < (1800000)) {
w.renderText(m_label,x1-(x/2),top-y+(3*w.printScaleY())); GetTextExtent(m_label, x, y);
w.renderText(m_label, x1 - (x / 2), top - y + (3 * w.printScaleY()));
} }
} }
} }
if (verts_exceeded) if (verts_exceeded) {
break; break;
}
} }
if (verts_exceeded)
if (verts_exceeded) {
break; break;
}
} }
if (verts_exceeded) { if (verts_exceeded) {
qWarning() << "exceeded maxverts in gLineOverlay::Plot()"; qWarning() << "exceeded maxverts in gLineOverlay::Plot()";
} }
} }
gLineOverlaySummary::gLineOverlaySummary(QString text, int x, int y) gLineOverlaySummary::gLineOverlaySummary(QString text, int x, int y)
:Layer(CPAP_Obstructive),m_text(text),m_x(x),m_y(y) // The Layer code is a dummy here. : Layer(CPAP_Obstructive), m_text(text), m_x(x), m_y(y) // The Layer code is a dummy here.
{ {
} }
@ -220,67 +259,84 @@ gLineOverlaySummary::~gLineOverlaySummary()
{ {
} }
void gLineOverlaySummary::paint(gGraph & w,int left, int top, int width, int height) void gLineOverlaySummary::paint(gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) return; if (!m_visible) { return; }
if (!m_day) return;
if (!m_day) { return; }
Q_UNUSED(width); Q_UNUSED(width);
Q_UNUSED(height); Q_UNUSED(height);
float cnt=0; float cnt = 0;
double sum=0; double sum = 0;
bool isSpan=false; bool isSpan = false;
for (int i=0;i<m_overlays.size();i++) {
cnt+=m_overlays[i]->count(); for (int i = 0; i < m_overlays.size(); i++) {
sum+=m_overlays[i]->sum(); cnt += m_overlays[i]->count();
if (m_overlays[i]->flagtype()==FT_Span) isSpan=true; sum += m_overlays[i]->sum();
if (m_overlays[i]->flagtype() == FT_Span) { isSpan = true; }
} }
double val,first,last; double val, first, last;
double time=0; double time = 0;
// Calculate the session time. // Calculate the session time.
for (QList<Session *>::iterator s=m_day->begin();s!=m_day->end(); s++) { for (QList<Session *>::iterator s = m_day->begin(); s != m_day->end(); s++) {
if (!(*s)->enabled()) continue; if (!(*s)->enabled()) { continue; }
first=(*s)->first();
last=(*s)->last();
if (last < w.min_x) continue;
if (first > w.max_x) continue;
if (first < w.min_x) first = (*s)->first();
first=w.min_x; last = (*s)->last();
if (last > w.max_x)
last=w.max_x;
time+=last-first; if (last < w.min_x) { continue; }
if (first > w.max_x) { continue; }
if (first < w.min_x) {
first = w.min_x;
}
if (last > w.max_x) {
last = w.max_x;
}
time += last - first;
} }
val=0; val = 0;
time/=1000; time /= 1000;
int h=time/3600; int h = time / 3600;
int m=int(time/60) % 60; int m = int(time / 60) % 60;
int s=int(time) % 60; int s = int(time) % 60;
time/=3600; time /= 3600;
//if (time<1) time=1; //if (time<1) time=1;
if (time>0) val=cnt/time; if (time > 0) { val = cnt / time; }
QString a=QObject::tr("Events")+"="+QString::number(cnt)+" "+QObject::tr("Duration")+" "+QString().sprintf("%02i:%02i:%02i",h,m,s)+", "+m_text+"="+QString::number(val,'f',2); QString a = QObject::tr("Events") + "=" + QString::number(cnt) + " " + QObject::tr("Duration") +
" " + QString().sprintf("%02i:%02i:%02i", h, m, s) + ", " + m_text + "=" + QString::number(val,
'f', 2);
if (isSpan) { if (isSpan) {
float sph; float sph;
if (!time) sph=0; else {
sph=(100.0/float(time))*(sum/3600.0); if (!time) { sph = 0; }
if (sph>100) sph=100; else {
sph = (100.0 / float(time)) * (sum / 3600.0);
if (sph > 100) { sph = 100; }
} }
a+=" "+QObject::tr("(\%%1 in events)").arg(sph,0,'f',2); // eg: %num of time in a span, like Periodic Breathing
a += " " + QObject::tr("(\%%1 in events)").arg(sph, 0, 'f',
2); // eg: %num of time in a span, like Periodic Breathing
} }
w.renderText(a,left+m_x,top+m_y);
w.renderText(a, left + m_x, top + m_y);
} }

View File

@ -17,61 +17,61 @@
/*! \class gLineOverlayBar /*! \class gLineOverlayBar
\brief Shows a flag line, a dot, or a span over the top of a 2D line chart. \brief Shows a flag line, a dot, or a span over the top of a 2D line chart.
*/ */
class gLineOverlayBar:public Layer class gLineOverlayBar: public Layer
{ {
public: public:
//! \brief Constructs a gLineOverlayBar object of type code, setting the flag/span color, the label to show when zoomed //! \brief Constructs a gLineOverlayBar object of type code, setting the flag/span color, the label to show when zoomed
//! in, and the display method requested, of either FT_Bar, FT_Span, or FT_Dot //! in, and the display method requested, of either FT_Bar, FT_Span, or FT_Dot
gLineOverlayBar(ChannelID code,QColor col,QString _label="",FlagType _flt=FT_Bar); gLineOverlayBar(ChannelID code, QColor col, QString _label = "", FlagType _flt = FT_Bar);
virtual ~gLineOverlayBar(); virtual ~gLineOverlayBar();
//! \brief The drawing code that fills the OpenGL vertex GLBuffers //! \brief The drawing code that fills the OpenGL vertex GLBuffers
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
virtual EventDataType Miny() { return 0; } virtual EventDataType Miny() { return 0; }
virtual EventDataType Maxy() { return 0; } virtual EventDataType Maxy() { return 0; }
//! \brief Returns true if no Channel data available for this code //! \brief Returns true if no Channel data available for this code
virtual bool isEmpty() { return true; } virtual bool isEmpty() { return true; }
//! \brief returns a count of all flags drawn during render. (for gLineOverlaySummary) //! \brief returns a count of all flags drawn during render. (for gLineOverlaySummary)
int count() { return m_count; } int count() { return m_count; }
double sum() { return m_sum; } double sum() { return m_sum; }
FlagType flagtype() { return m_flt; } FlagType flagtype() { return m_flt; }
protected: protected:
QColor m_flag_color; QColor m_flag_color;
QString m_label; QString m_label;
FlagType m_flt; FlagType m_flt;
int m_count; int m_count;
double m_sum; double m_sum;
gVertexBuffer *quads; gVertexBuffer *quads;
gVertexBuffer *points; gVertexBuffer *points;
}; };
/*! \class gLineOverlaySummary /*! \class gLineOverlaySummary
\brief A container class to hold a group of gLineOverlayBar's, and shows the "Section AHI" over the Flow Rate waveform. \brief A container class to hold a group of gLineOverlayBar's, and shows the "Section AHI" over the Flow Rate waveform.
*/ */
class gLineOverlaySummary:public Layer class gLineOverlaySummary: public Layer
{ {
public: public:
gLineOverlaySummary(QString text, int x, int y); gLineOverlaySummary(QString text, int x, int y);
virtual ~gLineOverlaySummary(); virtual ~gLineOverlaySummary();
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
virtual EventDataType Miny() { return 0; } virtual EventDataType Miny() { return 0; }
virtual EventDataType Maxy() { return 0; } virtual EventDataType Maxy() { return 0; }
//! \brief Returns true if no Channel data available for this code //! \brief Returns true if no Channel data available for this code
virtual bool isEmpty() { return true; } virtual bool isEmpty() { return true; }
//! \brief Adds a gLineOverlayBar to this list //! \brief Adds a gLineOverlayBar to this list
gLineOverlayBar *add(gLineOverlayBar *bar) { m_overlays.push_back(bar); return bar; } gLineOverlayBar *add(gLineOverlayBar *bar) { m_overlays.push_back(bar); return bar; }
protected: protected:
QVector<gLineOverlayBar *> m_overlays; QVector<gLineOverlayBar *> m_overlays;
QString m_text; QString m_text;
int m_x,m_y; int m_x, m_y;
}; };
#endif // GLINEOVERLAY_H #endif // GLINEOVERLAY_H

View File

@ -12,12 +12,13 @@
#include <cmath> #include <cmath>
#include "gSegmentChart.h" #include "gSegmentChart.h"
gSegmentChart::gSegmentChart(GraphSegmentType type,QColor gradient_color,QColor outline_color) gSegmentChart::gSegmentChart(GraphSegmentType type, QColor gradient_color, QColor outline_color)
:Layer(NoChannel),m_graph_type(type),m_gradient_color(gradient_color),m_outline_color(outline_color) : Layer(NoChannel), m_graph_type(type), m_gradient_color(gradient_color),
m_outline_color(outline_color)
{ {
m_empty=true; m_empty = true;
addGLBuf(poly=new GLFloatBuffer(4000,GL_POLYGON)); addGLBuf(poly = new GLFloatBuffer(4000, GL_POLYGON));
addGLBuf(lines=new GLFloatBuffer(4000,GL_LINE_LOOP)); addGLBuf(lines = new GLFloatBuffer(4000, GL_LINE_LOOP));
lines->setSize(1); lines->setSize(1);
poly->forceAntiAlias(false); poly->forceAntiAlias(false);
lines->forceAntiAlias(true); lines->forceAntiAlias(true);
@ -26,33 +27,38 @@ gSegmentChart::gSegmentChart(GraphSegmentType type,QColor gradient_color,QColor
gSegmentChart::~gSegmentChart() gSegmentChart::~gSegmentChart()
{ {
} }
void gSegmentChart::AddSlice(ChannelID code,QColor color,QString name) void gSegmentChart::AddSlice(ChannelID code, QColor color, QString name)
{ {
m_codes.push_back(code); m_codes.push_back(code);
m_values.push_back(0); m_values.push_back(0);
m_colors.push_back(color); m_colors.push_back(color);
m_names.push_back(name); m_names.push_back(name);
m_total=0; m_total = 0;
} }
void gSegmentChart::SetDay(Day *d) void gSegmentChart::SetDay(Day *d)
{ {
Layer::SetDay(d); Layer::SetDay(d);
m_total=0; m_total = 0;
if (!m_day) return;
for (int c=0;c<m_codes.size();c++) {
m_values[c]=0;
for (QList<Session *>::iterator s=m_day->begin();s!=m_day->end();++s) {
if (!(*s)->enabled()) continue;
int cnt=(*s)->count(m_codes[c]); if (!m_day) { return; }
m_values[c]+=cnt;
m_total+=cnt; for (int c = 0; c < m_codes.size(); c++) {
m_values[c] = 0;
for (QList<Session *>::iterator s = m_day->begin(); s != m_day->end(); ++s) {
if (!(*s)->enabled()) { continue; }
int cnt = (*s)->count(m_codes[c]);
m_values[c] += cnt;
m_total += cnt;
} }
} }
m_empty=true;
for (int i=0;i<m_codes.size();i++) { m_empty = true;
if (m_day->count(m_codes[i])>0) {
m_empty=false; for (int i = 0; i < m_codes.size(); i++) {
if (m_day->count(m_codes[i]) > 0) {
m_empty = false;
break; break;
} }
} }
@ -63,139 +69,153 @@ bool gSegmentChart::isEmpty()
return m_empty; return m_empty;
} }
void gSegmentChart::paint(gGraph & w,int left, int top, int width, int height) void gSegmentChart::paint(gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) return; if (!m_visible) { return; }
if (!m_day) return;
int start_px=left; if (!m_day) { return; }
int start_py=top;
int start_px = left;
int start_py = top;
width--; width--;
float diameter=MIN(width,height); float diameter = MIN(width, height);
diameter-=8; diameter -= 8;
float radius=diameter/2.0; float radius = diameter / 2.0;
float j=0.0; float j = 0.0;
float sum=0.0; float sum = 0.0;
float step=1.0/720.0; float step = 1.0 / 720.0;
float px,py; float px, py;
float q; float q;
float xmult=float(width)/float(m_total); float xmult = float(width) / float(m_total);
float ymult=float(height)/float(m_total); float ymult = float(height) / float(m_total);
float xp=left; float xp = left;
int xoffset=width/2; int xoffset = width / 2;
int yoffset=height/2; int yoffset = height / 2;
if (m_total==0) {
QColor col=Qt::green;
QString a=":-)";
int x,y;
GetTextExtent(a,x,y,bigfont);
w.renderText(a,start_px+xoffset-x/2, (start_py+yoffset+y/2),0,col,bigfont); if (m_total == 0) {
QColor col = Qt::green;
QString a = ":-)";
int x, y;
GetTextExtent(a, x, y, bigfont);
w.renderText(a, start_px + xoffset - x / 2, (start_py + yoffset + y / 2), 0, col, bigfont);
return; return;
} }
int data; int data;
unsigned size=m_values.size(); unsigned size = m_values.size();
float line_step=float(width)/float(size-1); float line_step = float(width) / float(size - 1);
bool line_first=true; bool line_first = true;
int line_last; int line_last;
gVertexBuffer *quads=w.quads(); gVertexBuffer *quads = w.quads();
gVertexBuffer *lines2=w.lines(); gVertexBuffer *lines2 = w.lines();
for (unsigned m=0;m<size;m++) {
data=m_values[m];
if (data==0) continue; for (unsigned m = 0; m < size; m++) {
///////////////////////////////////////////////////////////////////////////////////// data = m_values[m];
// Pie Chart
///////////////////////////////////////////////////////////////////////////////////// if (data == 0) { continue; }
if (m_graph_type==GST_Pie) {
QColor & col=schema::channel[m_codes[m % m_colors.size()]].defaultColor(); /////////////////////////////////////////////////////////////////////////////////////
j=float(data)/float(m_total); // ratio of this pie slice // Pie Chart
/////////////////////////////////////////////////////////////////////////////////////
if (m_graph_type == GST_Pie) {
QColor &col = schema::channel[m_codes[m % m_colors.size()]].defaultColor();
j = float(data) / float(m_total); // ratio of this pie slice
// Draw Filling // Draw Filling
poly->add(start_px+xoffset, start_py+height-yoffset,m_gradient_color); poly->add(start_px + xoffset, start_py + height - yoffset, m_gradient_color);
for (q=sum;q<sum+j;q+=step) {
px=start_px+xoffset+sin(q*2*M_PI)*radius;
py=start_py+height-(yoffset+cos(q*2*M_PI)*radius);
poly->add(px,py,col);
}
q=sum+j;
px=start_px+xoffset+sin(q*2*M_PI)*radius;
py=start_py+height-(yoffset+cos(q*2*M_PI)*radius);
poly->add(px,py,col);
if (m_total!=data) { for (q = sum; q < sum + j; q += step) {
px = start_px + xoffset + sin(q * 2 * M_PI) * radius;
py = start_py + height - (yoffset + cos(q * 2 * M_PI) * radius);
poly->add(px, py, col);
}
q = sum + j;
px = start_px + xoffset + sin(q * 2 * M_PI) * radius;
py = start_py + height - (yoffset + cos(q * 2 * M_PI) * radius);
poly->add(px, py, col);
if (m_total != data) {
// Draw the center point first // Draw the center point first
lines->add(start_px+xoffset, start_py+height-yoffset,m_outline_color); lines->add(start_px + xoffset, start_py + height - yoffset, m_outline_color);
}
for (q=sum;q<sum+j;q+=step) {
px=start_px+xoffset+sin(q*2*M_PI)*radius;
py=start_py+height-(yoffset+cos(q*2*M_PI)*radius);
lines->add(px,py,m_outline_color);
}
double tpx=start_px+xoffset+sin((sum+(j/2.0))*2*M_PI)*(radius/1.7);
double tpy=start_py+height-(yoffset+cos((sum+(j/2.0))*2*M_PI)*(radius/1.7));
q=sum+j;
px=start_px+xoffset+sin(q*2*M_PI)*radius;
py=start_py+height-(yoffset+cos(q*2*M_PI)*radius);
lines->add(px,py,m_outline_color);
if (j>.09) {
QString a=m_names[m]; //QString::number(floor(100.0/m_total*data),'f',0)+"%";
int x,y;
GetTextExtent(a,x,y);
w.renderText(a,tpx-(x/2.0),(tpy+y/2.0),0,Qt::black,defaultfont,false); // antialiasing looks like crap here..
} }
sum=q; for (q = sum; q < sum + j; q += step) {
px = start_px + xoffset + sin(q * 2 * M_PI) * radius;
py = start_py + height - (yoffset + cos(q * 2 * M_PI) * radius);
lines->add(px, py, m_outline_color);
}
///////////////////////////////////////////////////////////////////////////////////// double tpx = start_px + xoffset + sin((sum + (j / 2.0)) * 2 * M_PI) * (radius / 1.7);
// CandleStick Chart double tpy = start_py + height - (yoffset + cos((sum + (j / 2.0)) * 2 * M_PI) * (radius / 1.7));
///////////////////////////////////////////////////////////////////////////////////// q = sum + j;
} else if (m_graph_type==GST_CandleStick) { px = start_px + xoffset + sin(q * 2 * M_PI) * radius;
QColor & col=m_colors[m % m_colors.size()]; py = start_py + height - (yoffset + cos(q * 2 * M_PI) * radius);
float bw=xmult*float(data); lines->add(px, py, m_outline_color);
quads->add(xp,start_py,xp+bw,start_py,m_gradient_color.rgba()); if (j > .09) {
quads->add(xp+bw,start_py+height,xp,start_py+height,col.rgba()); QString a = m_names[m]; //QString::number(floor(100.0/m_total*data),'f',0)+"%";
int x, y;
GetTextExtent(a, x, y);
w.renderText(a, tpx - (x / 2.0), (tpy + y / 2.0), 0, Qt::black, defaultfont,
false); // antialiasing looks like crap here..
}
lines2->add(xp,start_py,xp+bw,start_py,m_outline_color.rgba()); sum = q;
lines2->add(xp+bw,start_py+height,xp,start_py+height,m_outline_color.rgba());
/////////////////////////////////////////////////////////////////////////////////////
// CandleStick Chart
/////////////////////////////////////////////////////////////////////////////////////
} else if (m_graph_type == GST_CandleStick) {
QColor &col = m_colors[m % m_colors.size()];
float bw = xmult * float(data);
quads->add(xp, start_py, xp + bw, start_py, m_gradient_color.rgba());
quads->add(xp + bw, start_py + height, xp, start_py + height, col.rgba());
lines2->add(xp, start_py, xp + bw, start_py, m_outline_color.rgba());
lines2->add(xp + bw, start_py + height, xp, start_py + height, m_outline_color.rgba());
if (!m_names[m].isEmpty()) { if (!m_names[m].isEmpty()) {
int px,py; int px, py;
GetTextExtent(m_names[m],px,py); GetTextExtent(m_names[m], px, py);
if (px+5<bw) {
w.renderText(m_names[m],(xp+bw/2)-(px/2),top+((height/2)-(py/2)),0,Qt::black); if (px + 5 < bw) {
w.renderText(m_names[m], (xp + bw / 2) - (px / 2), top + ((height / 2) - (py / 2)), 0, Qt::black);
} }
} }
xp+=bw; xp += bw;
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
// Line Chart // Line Chart
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
} else if (m_graph_type==GST_Line) { } else if (m_graph_type == GST_Line) {
QColor col=Qt::black; //m_colors[m % m_colors.size()]; QColor col = Qt::black; //m_colors[m % m_colors.size()];
float h=(top+height)-(float(data)*ymult); float h = (top + height) - (float(data) * ymult);
if (line_first) { if (line_first) {
line_first=false; line_first = false;
} else { } else {
lines->add(xp,line_last,xp+line_step,h,col); lines->add(xp, line_last, xp + line_step, h, col);
xp+=line_step; xp += line_step;
} }
line_last=h;
line_last = h;
} }
} }
} }
gTAPGraph::gTAPGraph(ChannelID code,GraphSegmentType gt, QColor gradient_color,QColor outline_color) gTAPGraph::gTAPGraph(ChannelID code, GraphSegmentType gt, QColor gradient_color,
:gSegmentChart(gt,gradient_color,outline_color),m_code(code) QColor outline_color)
: gSegmentChart(gt, gradient_color, outline_color), m_code(code)
{ {
m_colors.push_back(Qt::red); m_colors.push_back(Qt::red);
m_colors.push_back(Qt::green); m_colors.push_back(Qt::green);
@ -206,68 +226,81 @@ gTAPGraph::~gTAPGraph()
void gTAPGraph::SetDay(Day *d) void gTAPGraph::SetDay(Day *d)
{ {
Layer::SetDay(d); Layer::SetDay(d);
m_total=0; m_total = 0;
if (!m_day) return;
QMap<EventStoreType,qint64> tap;
EventStoreType data=0,lastval=0; if (!m_day) { return; }
qint64 time=0,lasttime=0;
QMap<EventStoreType, qint64> tap;
EventStoreType data = 0, lastval = 0;
qint64 time = 0, lasttime = 0;
//bool first; //bool first;
bool rfirst=true; bool rfirst = true;
//bool changed; //bool changed;
EventDataType gain=1,offset=0; EventDataType gain = 1, offset = 0;
QHash<ChannelID,QVector<EventList *> >::iterator ei; QHash<ChannelID, QVector<EventList *> >::iterator ei;
for (QList<Session *>::iterator s=m_day->begin();s!=m_day->end();++s) {
if (!(*s)->enabled()) continue; for (QList<Session *>::iterator s = m_day->begin(); s != m_day->end(); ++s) {
if (!(*s)->enabled()) { continue; }
if ((ei = (*s)->eventlist.find(m_code)) == (*s)->eventlist.end()) { continue; }
for (int q = 0; q < ei.value().size(); q++) {
EventList &el = *(ei.value()[q]);
lasttime = el.time(0);
lastval = el.raw(0);
if ((ei=(*s)->eventlist.find(m_code))==(*s)->eventlist.end()) continue;
for (int q=0;q<ei.value().size();q++) {
EventList &el=*(ei.value()[q]);
lasttime=el.time(0);
lastval=el.raw(0);
if (rfirst) { if (rfirst) {
gain=el.gain(); gain = el.gain();
offset=el.offset(); offset = el.offset();
rfirst=false; rfirst = false;
} }
//first=true; //first=true;
//changed=false; //changed=false;
for (quint32 i=1;i<el.count();i++) { for (quint32 i = 1; i < el.count(); i++) {
data=el.raw(i); data = el.raw(i);
time=el.time(i); time = el.time(i);
if (lastval!=data) {
qint64 v=(time-lasttime); if (lastval != data) {
if (tap.find(lastval)!=tap.end()) { qint64 v = (time - lasttime);
tap[lastval]+=v;
if (tap.find(lastval) != tap.end()) {
tap[lastval] += v;
} else { } else {
tap[lastval]=v; tap[lastval] = v;
} }
//changed=true; //changed=true;
lasttime=time; lasttime = time;
lastval=data; lastval = data;
} }
} }
if (time!=lasttime) {
qint64 v=(time-lasttime); if (time != lasttime) {
if (tap.find(lastval)!=tap.end()) { qint64 v = (time - lasttime);
tap[data]+=v;
if (tap.find(lastval) != tap.end()) {
tap[data] += v;
} else { } else {
tap[data]=v; tap[data] = v;
} }
} }
} }
} }
m_values.clear(); m_values.clear();
m_names.clear(); m_names.clear();
m_total=0; m_total = 0;
EventDataType val; EventDataType val;
for (QMap<EventStoreType,qint64>::iterator i=tap.begin();i!=tap.end();i++) { for (QMap<EventStoreType, qint64>::iterator i = tap.begin(); i != tap.end(); i++) {
val=float(i.key())*gain+offset; val = float(i.key()) * gain + offset;
m_values.push_back(i.value()/1000L); m_values.push_back(i.value() / 1000L);
m_total+=i.value()/1000L; m_total += i.value() / 1000L;
m_names.push_back(QString::number(val,'f',2)); m_names.push_back(QString::number(val, 'f', 2));
} }
m_empty=m_values.size()==0;
m_empty = m_values.size() == 0;
} }

View File

@ -21,12 +21,13 @@ enum GraphSegmentType { GST_Pie, GST_CandleStick, GST_Line };
*/ */
class gSegmentChart : public Layer class gSegmentChart : public Layer
{ {
public: public:
gSegmentChart(GraphSegmentType gt=GST_Pie, QColor gradient_color=Qt::white,QColor outline_color=Qt::black); gSegmentChart(GraphSegmentType gt = GST_Pie, QColor gradient_color = Qt::white,
QColor outline_color = Qt::black);
virtual ~gSegmentChart(); virtual ~gSegmentChart();
//! \brief The drawing code that fills the Vertex buffers //! \brief The drawing code that fills the Vertex buffers
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
//! \brief Pre-fills a buffer with the data needed to draw //! \brief Pre-fills a buffer with the data needed to draw
virtual void SetDay(Day *d); virtual void SetDay(Day *d);
@ -35,17 +36,17 @@ public:
virtual bool isEmpty(); virtual bool isEmpty();
//! \brief Adds a channel slice, and sets the color and label //! \brief Adds a channel slice, and sets the color and label
void AddSlice(ChannelID code,QColor col,QString name=""); void AddSlice(ChannelID code, QColor col, QString name = "");
//! \brief Sets the fade-out color to make the graphs look more attractive //! \brief Sets the fade-out color to make the graphs look more attractive
void setGradientColor(QColor & color) { m_gradient_color=color; } void setGradientColor(QColor &color) { m_gradient_color = color; }
//! \brief Sets the outline color for the edges drawn around the Pie slices //! \brief Sets the outline color for the edges drawn around the Pie slices
void setOutlineColor(QColor & color) { m_outline_color=color; } void setOutlineColor(QColor &color) { m_outline_color = color; }
const GraphSegmentType & graphType() { return m_graph_type; } const GraphSegmentType &graphType() { return m_graph_type; }
void setGraphType(GraphSegmentType type) { m_graph_type=type; } void setGraphType(GraphSegmentType type) { m_graph_type = type; }
protected: protected:
QVector<ChannelID> m_codes; QVector<ChannelID> m_codes;
QVector<QString> m_names; QVector<QString> m_names;
QVector<int> m_values; QVector<int> m_values;
@ -58,20 +59,21 @@ protected:
bool m_empty; bool m_empty;
// gah.. can't convert these // gah.. can't convert these
GLFloatBuffer *poly,*lines; GLFloatBuffer *poly, *lines;
}; };
/*! \class gTAPGraph /*! \class gTAPGraph
\brief Time at Pressure chart, derived from gSegmentChart \brief Time at Pressure chart, derived from gSegmentChart
\notes Currently unused \notes Currently unused
*/ */
class gTAPGraph:public gSegmentChart class gTAPGraph: public gSegmentChart
{ {
public: public:
gTAPGraph(ChannelID code,GraphSegmentType gt=GST_CandleStick, QColor gradient_color=Qt::lightGray,QColor outline_color=Qt::black); gTAPGraph(ChannelID code, GraphSegmentType gt = GST_CandleStick,
QColor gradient_color = Qt::lightGray, QColor outline_color = Qt::black);
virtual ~gTAPGraph(); virtual ~gTAPGraph();
virtual void SetDay(Day *d); virtual void SetDay(Day *d);
protected: protected:
ChannelID m_code; ChannelID m_code;
}; };

View File

@ -13,36 +13,37 @@
#include "gYAxis.h" #include "gYAxis.h"
#include "gStatsLine.h" #include "gStatsLine.h"
gStatsLine::gStatsLine(ChannelID code,QString label,QColor textcolor) gStatsLine::gStatsLine(ChannelID code, QString label, QColor textcolor)
:Layer(code),m_label(label),m_textcolor(textcolor) : Layer(code), m_label(label), m_textcolor(textcolor)
{ {
} }
void gStatsLine::paint(gGraph & w, int left, int top, int width, int height) void gStatsLine::paint(gGraph &w, int left, int top, int width, int height)
{ {
if (!m_visible) return; if (!m_visible) { return; }
//if (m_empty) return; //if (m_empty) return;
Q_UNUSED(height); Q_UNUSED(height);
int z=(width+gYAxis::Margin)/5; int z = (width + gYAxis::Margin) / 5;
int p=left-gYAxis::Margin; int p = left - gYAxis::Margin;
top+=4; top += 4;
w.renderText(m_label,p,top); w.renderText(m_label, p, top);
//w.renderText(m_text,p,top,0,m_textcolor); //w.renderText(m_text,p,top,0,m_textcolor);
p+=z; p += z;
w.renderText(st_min,p,top); w.renderText(st_min, p, top);
p+=z; p += z;
w.renderText(st_avg,p,top); w.renderText(st_avg, p, top);
p+=z; p += z;
w.renderText(st_p90,p,top); w.renderText(st_p90, p, top);
p+=z; p += z;
w.renderText(st_max,p,top); w.renderText(st_max, p, top);
} }
@ -50,15 +51,17 @@ void gStatsLine::paint(gGraph & w, int left, int top, int width, int height)
void gStatsLine::SetDay(Day *d) void gStatsLine::SetDay(Day *d)
{ {
Layer::SetDay(d); Layer::SetDay(d);
if (!m_day) return;
m_min=d->Min(m_code);
m_max=d->Max(m_code);
m_avg=d->wavg(m_code);
m_p90=d->p90(m_code);
st_min="Min="+QString::number(m_min,'f',2); if (!m_day) { return; }
st_max="Max="+QString::number(m_max,'f',2);
st_avg="Avg="+QString::number(m_avg,'f',2); m_min = d->Min(m_code);
st_p90="90%="+QString::number(m_p90,'f',2); m_max = d->Max(m_code);
m_avg = d->wavg(m_code);
m_p90 = d->p90(m_code);
st_min = "Min=" + QString::number(m_min, 'f', 2);
st_max = "Max=" + QString::number(m_max, 'f', 2);
st_avg = "Avg=" + QString::number(m_avg, 'f', 2);
st_p90 = "90%=" + QString::number(m_p90, 'f', 2);
} }

View File

@ -20,17 +20,17 @@
*/ */
class gStatsLine : public Layer class gStatsLine : public Layer
{ {
public: public:
gStatsLine(ChannelID code,QString label="",QColor textcolor=Qt::black); gStatsLine(ChannelID code, QString label = "", QColor textcolor = Qt::black);
virtual void paint(gGraph & w, int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
void SetDay(Day *d); void SetDay(Day *d);
protected: protected:
QString m_label; QString m_label;
QColor m_textcolor; QColor m_textcolor;
EventDataType m_min,m_max,m_avg,m_p90; EventDataType m_min, m_max, m_avg, m_p90;
QString st_min,st_max,st_avg,st_p90; QString st_min, st_max, st_avg, st_p90;
float m_tx,m_ty; float m_tx, m_ty;
}; };
#endif // GSTATSLINE_H #endif // GSTATSLINE_H

File diff suppressed because it is too large Load Diff

View File

@ -26,92 +26,91 @@ enum GraphType { GT_BAR, GT_LINE, GT_POINTS, GT_SESSIONS };
/*! \class SummaryChart /*! \class SummaryChart
\brief The main overall chart type layer used in Overview page \brief The main overall chart type layer used in Overview page
*/ */
class SummaryChart:public Layer class SummaryChart: public Layer
{ {
public: public:
//! \brief Constructs a SummaryChart with QString label, of GraphType type //! \brief Constructs a SummaryChart with QString label, of GraphType type
SummaryChart(QString label, GraphType type=GT_BAR); SummaryChart(QString label, GraphType type = GT_BAR);
virtual ~SummaryChart(); virtual ~SummaryChart();
//! \brief Drawing code that fills the Vertex buffers //! \brief Drawing code that fills the Vertex buffers
virtual void paint(gGraph & w,int left, int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
//! \brief Precalculation code prior to drawing. Day object is not needed here, it's just here for Layer compatability. //! \brief Precalculation code prior to drawing. Day object is not needed here, it's just here for Layer compatability.
virtual void SetDay(Day * day=NULL); virtual void SetDay(Day *day = NULL);
//! \brief Returns true if no data was found for this day during SetDay //! \brief Returns true if no data was found for this day during SetDay
virtual bool isEmpty() { return m_empty; } virtual bool isEmpty() { return m_empty; }
//! \brief Adds a layer to the summaryChart (When in Bar mode, it becomes culminative, eg, the AHI chart) //! \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, EventDataType tval=0.00f) void addSlice(ChannelID code, QColor color, SummaryType type, EventDataType tval = 0.00f) {
{ m_codes.push_back(code);
m_codes.push_back(code); m_colors.push_back(color);
m_colors.push_back(color); m_type.push_back(type);
m_type.push_back(type); //m_zeros.push_back(ignore_zeros);
//m_zeros.push_back(ignore_zeros); m_typeval.push_back(tval);
m_typeval.push_back(tval); }
}
//! \brief Deselect highlighting (the gold bar) //! \brief Deselect highlighting (the gold bar)
virtual void deselect() { virtual void deselect() {
hl_day=-1; hl_day = -1;
} }
//! \brief Returns true if currently selected.. //! \brief Returns true if currently selected..
virtual bool isSelected() { return hl_day>=0; } virtual bool isSelected() { return hl_day >= 0; }
//! \brief Sets the MachineType this SummaryChart is interested in //! \brief Sets the MachineType this SummaryChart is interested in
void setMachineType(MachineType type) { m_machinetype=type; } void setMachineType(MachineType type) { m_machinetype = type; }
//! \brief Returns the MachineType this SummaryChart is interested in //! \brief Returns the MachineType this SummaryChart is interested in
MachineType machineType() { return m_machinetype; } MachineType machineType() { return m_machinetype; }
protected: protected:
Qt::Orientation m_orientation; Qt::Orientation m_orientation;
QVector<QColor> m_colors; QVector<QColor> m_colors;
QVector<ChannelID> m_codes; QVector<ChannelID> m_codes;
QVector<bool> m_goodcodes; QVector<bool> m_goodcodes;
//QVector<bool> m_zeros; //QVector<bool> m_zeros;
QVector<SummaryType> m_type; QVector<SummaryType> m_type;
QVector<EventDataType> m_typeval; QVector<EventDataType> m_typeval;
QHash<int,QHash<short,EventDataType> > m_values; QHash<int, QHash<short, EventDataType> > m_values;
QHash<int,QHash<short,EventDataType> > m_times; QHash<int, QHash<short, EventDataType> > m_times;
QHash<int,EventDataType> m_hours; QHash<int, EventDataType> m_hours;
QHash<int,Day *> m_days; QHash<int, Day *> m_days;
gVertexBuffer *quads; gVertexBuffer *quads;
gVertexBuffer *lines; gVertexBuffer *lines;
gVertexBuffer *outlines; gVertexBuffer *outlines;
gVertexBuffer *points; gVertexBuffer *points;
bool m_empty; bool m_empty;
int m_fday; int m_fday;
QString m_label; QString m_label;
float barw; // bar width from last draw float barw; // bar width from last draw
qint64 l_offset; // last offset qint64 l_offset; // last offset
float offset; // in pixels; float offset; // in pixels;
int l_left,l_top,l_width,l_height; int l_left, l_top, l_width, l_height;
int rtop; int rtop;
qint64 l_minx,l_maxx; qint64 l_minx, l_maxx;
int hl_day; int hl_day;
gGraph * graph; gGraph *graph;
GraphType m_graphtype; GraphType m_graphtype;
MachineType m_machinetype; MachineType m_machinetype;
int tz_offset; int tz_offset;
float tz_hours; float tz_hours;
//! \brief Key was pressed that effects this layer //! \brief Key was pressed that effects this layer
virtual bool keyPressEvent(QKeyEvent * event,gGraph * graph); virtual bool keyPressEvent(QKeyEvent *event, gGraph *graph);
//! \brief Mouse moved over this layers area (shows the hover-over tooltips here) //! \brief Mouse moved over this layers area (shows the hover-over tooltips here)
virtual bool mouseMoveEvent(QMouseEvent * event,gGraph * graph); virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
//! \brief Mouse Button was pressed over this area //! \brief Mouse Button was pressed over this area
virtual bool mousePressEvent(QMouseEvent * event,gGraph * graph); virtual bool mousePressEvent(QMouseEvent *event, gGraph *graph);
//! \brief Mouse Button was released over this area. (jumps to daily view here) //! \brief Mouse Button was released over this area. (jumps to daily view here)
virtual bool mouseReleaseEvent(QMouseEvent * event,gGraph * graph); virtual bool mouseReleaseEvent(QMouseEvent *event, gGraph *graph);
}; };

View File

@ -14,48 +14,48 @@
#include "gXAxis.h" #include "gXAxis.h"
const quint64 divisors[]={ const quint64 divisors[] = {
15552000000ULL, 7776000000ULL, 5184000000ULL, 2419200000ULL, 1814400000ULL, 1209600000L, 604800000L, 259200000L, 15552000000ULL, 7776000000ULL, 5184000000ULL, 2419200000ULL, 1814400000ULL, 1209600000L, 604800000L, 259200000L,
172800000L, 86400000,2880000,14400000,7200000,3600000,2700000, 172800000L, 86400000, 2880000, 14400000, 7200000, 3600000, 2700000,
1800000,1200000,900000,600000,300000,120000,60000,45000,30000, 1800000, 1200000, 900000, 600000, 300000, 120000, 60000, 45000, 30000,
20000,15000,10000,5000,2000,1000,100,50,10 20000, 15000, 10000, 5000, 2000, 1000, 100, 50, 10
}; };
const int divcnt=sizeof(divisors)/sizeof(quint64); const int divcnt = sizeof(divisors) / sizeof(quint64);
gXAxis::gXAxis(QColor col,bool fadeout) gXAxis::gXAxis(QColor col, bool fadeout)
:Layer(NoChannel) : Layer(NoChannel)
{ {
m_line_color=col; m_line_color = col;
m_text_color=col; m_text_color = col;
m_major_color=Qt::darkGray; m_major_color = Qt::darkGray;
m_minor_color=Qt::lightGray; m_minor_color = Qt::lightGray;
m_show_major_lines=false; m_show_major_lines = false;
m_show_minor_lines=false; m_show_minor_lines = false;
m_show_minor_ticks=true; m_show_minor_ticks = true;
m_show_major_ticks=true; m_show_major_ticks = true;
m_utcfix=false; m_utcfix = false;
m_fadeout=fadeout; m_fadeout = fadeout;
m_textureID=0; m_textureID = 0;
// QDateTime d=QDateTime::currentDateTime(); // QDateTime d=QDateTime::currentDateTime();
// QTime t1=d.time(); // QTime t1=d.time();
// QTime t2=d.toUTC().time(); // QTime t2=d.toUTC().time();
// tz_offset=t2.secsTo(t1); // tz_offset=t2.secsTo(t1);
// tz_hours=tz_offset/3600.0; // tz_hours=tz_offset/3600.0;
// tz_offset*=1000L; // tz_offset*=1000L;
tz_offset=timezoneOffset(); tz_offset = timezoneOffset();
tz_hours=tz_offset/3600000.0; tz_hours = tz_offset / 3600000.0;
} }
gXAxis::~gXAxis() gXAxis::~gXAxis()
{ {
} }
void gXAxis::paint(gGraph & w,int left,int top, int width, int height) void gXAxis::paint(gGraph &w, int left, int top, int width, int height)
{ {
Q_UNUSED(height) Q_UNUSED(height)
QString months[]={ QString months[] = {
QObject::tr("Jan"), QObject::tr("Feb"), QObject::tr("Mar"), QObject::tr("Apr"), QObject::tr("May"), QObject::tr("Jun"), QObject::tr("Jan"), QObject::tr("Feb"), QObject::tr("Mar"), QObject::tr("Apr"), QObject::tr("May"), QObject::tr("Jun"),
QObject::tr("Jul"), QObject::tr("Aug"), QObject::tr("Sep"), QObject::tr("Oct"), QObject::tr("Nov"),QObject::tr("Dec") QObject::tr("Jul"), QObject::tr("Aug"), QObject::tr("Sep"), QObject::tr("Oct"), QObject::tr("Nov"), QObject::tr("Dec")
}; };
//static QString dow[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; //static QString dow[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
@ -65,110 +65,124 @@ void gXAxis::paint(gGraph & w,int left,int top, int width, int height)
// pixmap caching screws font size when printing // pixmap caching screws font size when printing
bool usepixmap=w.graphView()->usePixmapCache(); // Whether or not to use pixmap caching bool usepixmap = w.graphView()->usePixmapCache(); // Whether or not to use pixmap caching
if (!usepixmap || (usepixmap && w.invalidate_xAxisImage)) { if (!usepixmap || (usepixmap && w.invalidate_xAxisImage)) {
if (usepixmap) { if (usepixmap) {
// Unbind any previous texture // Unbind any previous texture
if (m_textureID) w.graphView()->deleteTexture(m_textureID); if (m_textureID) { w.graphView()->deleteTexture(m_textureID); }
m_image=QImage(width+22,height+4,QImage::Format_ARGB32_Premultiplied); m_image = QImage(width + 22, height + 4, QImage::Format_ARGB32_Premultiplied);
m_image.fill(Qt::transparent); m_image.fill(Qt::transparent);
painter.begin(&m_image); painter.begin(&m_image);
painter.setPen(Qt::black); painter.setPen(Qt::black);
painter.setFont(*defaultfont); painter.setFont(*defaultfont);
} }
double px,py;
int start_px=left; double px, py;
int start_px = left;
//int start_py=top; //int start_py=top;
//int width=scrx-(w.GetLeftMargin()+w.GetRightMargin()); //int width=scrx-(w.GetLeftMargin()+w.GetRightMargin());
// float height=scry-(w.GetTopMargin()+w.GetBottomMargin()); // float height=scry-(w.GetTopMargin()+w.GetBottomMargin());
if (width<40) if (width < 40) {
return; return;
}
qint64 minx; qint64 minx;
qint64 maxx; qint64 maxx;
if (w.blockZoom()) { if (w.blockZoom()) {
minx=w.rmin_x; minx = w.rmin_x;
maxx=w.rmax_x; maxx = w.rmax_x;
} else { } else {
minx=w.min_x; minx = w.min_x;
maxx=w.max_x; maxx = w.max_x;
} }
qint64 xx=maxx-minx;
if (xx<=0) return; qint64 xx = maxx - minx;
if (xx <= 0) { return; }
//Most of this could be precalculated when min/max is set.. //Most of this could be precalculated when min/max is set..
QString fd,tmpstr; QString fd, tmpstr;
int divmax,dividx; int divmax, dividx;
int fitmode; int fitmode;
if (xx>=86400000L) { // Day
fd="Mjj 00"; if (xx >= 86400000L) { // Day
dividx=0; fd = "Mjj 00";
divmax=10; dividx = 0;
fitmode=0; divmax = 10;
} else if (xx>600000) { // Minutes fitmode = 0;
fd=" j0:00"; } else if (xx > 600000) { // Minutes
dividx=10; fd = " j0:00";
divmax=27; dividx = 10;
fitmode=1; divmax = 27;
} else if (xx>5000) { // Seconds fitmode = 1;
fd=" j0:00:00"; } else if (xx > 5000) { // Seconds
dividx=16; fd = " j0:00:00";
divmax=27; dividx = 16;
fitmode=2; divmax = 27;
fitmode = 2;
} else { // Microseconds } else { // Microseconds
fd="j0:00:00:000"; fd = "j0:00:00:000";
dividx=28; dividx = 28;
divmax=divcnt; divmax = divcnt;
fitmode=3; fitmode = 3;
} }
//if (divmax>divcnt) divmax=divcnt; //if (divmax>divcnt) divmax=divcnt;
int x,y; int x, y;
GetTextExtent(fd,x,y); GetTextExtent(fd, x, y);
if (x<=0) { if (x <= 0) {
qWarning() << "gXAxis::Plot() x<=0 font size bug"; qWarning() << "gXAxis::Plot() x<=0 font size bug";
return; return;
} }
int max_ticks=width/(x+15); // Max number of ticks that will fit int max_ticks = width / (x + 15); // Max number of ticks that will fit
int fit_ticks=0; int fit_ticks = 0;
int div=-1; int div = -1;
qint64 closest=0,tmp,tmpft; qint64 closest = 0, tmp, tmpft;
for (int i=dividx;i<divmax;i++){
tmpft=xx/divisors[i]; for (int i = dividx; i < divmax; i++) {
tmp=max_ticks-tmpft; tmpft = xx / divisors[i];
if (tmp<0) continue; tmp = max_ticks - tmpft;
if (tmpft>closest) { // Find the closest scale to the number
closest=tmpft; // that will fit if (tmp < 0) { continue; }
div=i;
fit_ticks=tmpft; if (tmpft > closest) { // Find the closest scale to the number
closest = tmpft; // that will fit
div = i;
fit_ticks = tmpft;
} }
} }
if (fit_ticks==0) {
if (fit_ticks == 0) {
qDebug() << "gXAxis::Plot() Couldn't fit ticks.. Too short?" << minx << maxx << xx; qDebug() << "gXAxis::Plot() Couldn't fit ticks.. Too short?" << minx << maxx << xx;
return; return;
} }
if ((div<0) || (div>divcnt)) {
if ((div < 0) || (div > divcnt)) {
qDebug() << "gXAxis::Plot() div out of bounds"; qDebug() << "gXAxis::Plot() div out of bounds";
return; return;
} }
qint64 step=divisors[div];
qint64 step = divisors[div];
//Align left minimum to divisor by losing precision //Align left minimum to divisor by losing precision
qint64 aligned_start=minx/step; qint64 aligned_start = minx / step;
aligned_start*=step; aligned_start *= step;
while (aligned_start<minx) { while (aligned_start < minx) {
aligned_start+=step; aligned_start += step;
} }
gVertexBuffer *lines=w.backlines(); gVertexBuffer *lines = w.backlines();
lines->setColor(Qt::black); lines->setColor(Qt::black);
@ -177,85 +191,104 @@ void gXAxis::paint(gGraph & w,int left,int top, int width, int height)
//utcoff=0; //utcoff=0;
int num_minor_ticks; int num_minor_ticks;
if (step>=86400000) { if (step >= 86400000) {
qint64 i=step/86400000L; // number of days qint64 i = step / 86400000L; // number of days
if (i>14) i/=2;
if (i<0) i=1;
num_minor_ticks=i;
} else num_minor_ticks=10;
float xmult=double(width)/double(xx); if (i > 14) { i /= 2; }
float step_pixels=double(step/float(num_minor_ticks))*xmult;
py=left+float(aligned_start-minx)*xmult; if (i < 0) { i = 1; }
num_minor_ticks = i;
} else { num_minor_ticks = 10; }
float xmult = double(width) / double(xx);
float step_pixels = double(step / float(num_minor_ticks)) * xmult;
py = left + float(aligned_start - minx) * xmult;
//py+=usepixmap ? 20 : left; //py+=usepixmap ? 20 : left;
int mintop=top+4.0*(float(y)/10.0); int mintop = top + 4.0 * (float(y) / 10.0);
int majtop=top+6.0*(float(y)/10.0); int majtop = top + 6.0 * (float(y) / 10.0);
int texttop=majtop+y; // 18*w.printScaleY(); int texttop = majtop + y; // 18*w.printScaleY();
// Fill in the minor tick marks up to the first major alignment tick // Fill in the minor tick marks up to the first major alignment tick
for (int i=0;i<num_minor_ticks;i++) { for (int i = 0; i < num_minor_ticks; i++) {
py-=step_pixels; py -= step_pixels;
if (py<start_px) continue;
if (usepixmap) if (py < start_px) { continue; }
painter.drawLine(py-left+20,0,py-left+20,mintop-top);
else if (usepixmap) {
lines->add(py,top,py,mintop); painter.drawLine(py - left + 20, 0, py - left + 20, mintop - top);
} else {
lines->add(py, top, py, mintop);
}
} }
int ms,m,h,s,d; int ms, m, h, s, d;
qint64 j; qint64 j;
for (qint64 i=aligned_start;i<maxx;i+=step) {
px=(i-minx)*xmult; for (qint64 i = aligned_start; i < maxx; i += step) {
px+=left; px = (i - minx) * xmult;
px += left;
if (usepixmap) { if (usepixmap) {
painter.drawLine(px-left+20,0,px-left+20,majtop-top); painter.drawLine(px - left + 20, 0, px - left + 20, majtop - top);
} else lines->add(px,top,px,majtop); } else { lines->add(px, top, px, majtop); }
j=i;
if (!m_utcfix) j+=tz_offset; j = i;
ms=j % 1000;
m=(j/60000L) % 60L; if (!m_utcfix) { j += tz_offset; }
h=(j/3600000L) % 24L;
s=(j/1000L) % 60L; ms = j % 1000;
m = (j / 60000L) % 60L;
h = (j / 3600000L) % 24L;
s = (j / 1000L) % 60L;
//int d=(j/86400000) % 7; //int d=(j/86400000) % 7;
if (fitmode==0) { if (fitmode == 0) {
d=(j/1000); d = (j / 1000);
QDateTime dt=QDateTime::fromTime_t(d).toUTC(); QDateTime dt = QDateTime::fromTime_t(d).toUTC();
QDate date=dt.date(); QDate date = dt.date();
// SLOW SLOW SLOW!!! On Mac especially, this function is pathetically slow. // SLOW SLOW SLOW!!! On Mac especially, this function is pathetically slow.
//dt.toString("MMM dd"); //dt.toString("MMM dd");
// Doing it this way instead because it's MUUUUUUCH faster // Doing it this way instead because it's MUUUUUUCH faster
tmpstr=QString("%1 %2").arg(months[date.month()-1]).arg(date.day()); tmpstr = QString("%1 %2").arg(months[date.month() - 1]).arg(date.day());
//} else if (fitmode==0) { //} else if (fitmode==0) {
// tmpstr=QString("%1 %2:%3").arg(dow[d]).arg(h,2,10,QChar('0')).arg(m,2,10,QChar('0')); // tmpstr=QString("%1 %2:%3").arg(dow[d]).arg(h,2,10,QChar('0')).arg(m,2,10,QChar('0'));
} else if (fitmode==1) { // minute } else if (fitmode == 1) { // minute
tmpstr=QString("%1:%2").arg(h,2,10,QChar('0')).arg(m,2,10,QChar('0')); tmpstr = QString("%1:%2").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0'));
} else if (fitmode==2) { // second } else if (fitmode == 2) { // second
tmpstr=QString("%1:%2:%3").arg(h,2,10,QChar('0')).arg(m,2,10,QChar('0')).arg(s,2,10,QChar('0')); tmpstr = QString("%1:%2:%3").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10,
} else if (fitmode==3) { // milli QChar('0'));
tmpstr=QString("%1:%2:%3:%4").arg(h,2,10,QChar('0')).arg(m,2,10,QChar('0')).arg(s,2,10,QChar('0')).arg(ms,3,10,QChar('0')); } else if (fitmode == 3) { // milli
tmpstr = QString("%1:%2:%3:%4").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10,
QChar('0')).arg(ms, 3, 10, QChar('0'));
} }
int tx=px-x/2.0; int tx = px - x / 2.0;
if (m_utcfix) if (m_utcfix) {
tx+=step_pixels/2.0; tx += step_pixels / 2.0;
if ((tx+x)<(left+width)) {
if (!usepixmap) w.renderText(tmpstr,tx,texttop,0,Qt::black,defaultfont);
else painter.drawText(tx-left+20,texttop-top,tmpstr);
} }
py=px;
for (int j=1;j<num_minor_ticks;j++) { if ((tx + x) < (left + width)) {
py+=step_pixels; if (!usepixmap) { w.renderText(tmpstr, tx, texttop, 0, Qt::black, defaultfont); }
if (py>=left+width) break; else { painter.drawText(tx - left + 20, texttop - top, tmpstr); }
}
py = px;
for (int j = 1; j < num_minor_ticks; j++) {
py += step_pixels;
if (py >= left + width) { break; }
if (usepixmap) { if (usepixmap) {
painter.drawLine(py-left+20,0,py-left+20,mintop-top); painter.drawLine(py - left + 20, 0, py - left + 20, mintop - top);
} else lines->add(py,top,py,mintop); } else { lines->add(py, top, py, mintop); }
} }
if (lines->full()) { if (lines->full()) {
@ -266,18 +299,20 @@ void gXAxis::paint(gGraph & w,int left,int top, int width, int height)
if (usepixmap) { if (usepixmap) {
painter.end(); painter.end();
m_image=QGLWidget::convertToGLFormat(m_image); m_image = QGLWidget::convertToGLFormat(m_image);
m_textureID=w.graphView()->bindTexture(m_image,GL_TEXTURE_2D,GL_RGBA,QGLContext::NoBindOption); m_textureID = w.graphView()->bindTexture(m_image, GL_TEXTURE_2D, GL_RGBA,
QGLContext::NoBindOption);
} }
w.invalidate_xAxisImage=false;
w.invalidate_xAxisImage = false;
} }
if (usepixmap && !m_image.isNull()) { if (usepixmap && !m_image.isNull()) {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
w.graphView()->drawTexture(QPoint(left-20,(top+height)-m_image.height()+4),m_textureID); w.graphView()->drawTexture(QPoint(left - 20, (top + height) - m_image.height() + 4), m_textureID);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }

View File

@ -15,41 +15,41 @@
/*! \class gXAxis /*! \class gXAxis
\brief Draws the XTicker timescales underneath graphs */ \brief Draws the XTicker timescales underneath graphs */
class gXAxis:public Layer class gXAxis: public Layer
{ {
public: public:
gXAxis(QColor col=Qt::black,bool fadeout=true); gXAxis(QColor col = Qt::black, bool fadeout = true);
virtual ~gXAxis(); virtual ~gXAxis();
virtual void paint(gGraph & w,int left,int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
static const int Margin=20; // How much room does this take up. (Bottom margin) static const int Margin = 20; // How much room does this take up. (Bottom margin)
void SetShowMinorLines(bool b) { m_show_minor_lines=b; } void SetShowMinorLines(bool b) { m_show_minor_lines = b; }
void SetShowMajorLines(bool b) { m_show_major_lines=b; } void SetShowMajorLines(bool b) { m_show_major_lines = b; }
bool ShowMinorLines() { return m_show_minor_lines; } bool ShowMinorLines() { return m_show_minor_lines; }
bool ShowMajorLines() { return m_show_major_lines; } bool ShowMajorLines() { return m_show_major_lines; }
void SetShowMinorTicks(bool b) { m_show_minor_ticks=b; } void SetShowMinorTicks(bool b) { m_show_minor_ticks = b; }
void SetShowMajorTicks(bool b) { m_show_major_ticks=b; } void SetShowMajorTicks(bool b) { m_show_major_ticks = b; }
bool ShowMinorTicks() { return m_show_minor_ticks; } bool ShowMinorTicks() { return m_show_minor_ticks; }
bool ShowMajorTicks() { return m_show_major_ticks; } bool ShowMajorTicks() { return m_show_major_ticks; }
void setUtcFix(bool b) { m_utcfix=b; } void setUtcFix(bool b) { m_utcfix = b; }
protected: protected:
// virtual const wxString & Format(double v) { static wxString t; wxDateTime d; d.Set(v); t=d.Format(wxT("%H:%M")); return t; }; // virtual const wxString & Format(double v) { static wxString t; wxDateTime d; d.Set(v); t=d.Format(wxT("%H:%M")); return t; };
bool m_show_major_lines; bool m_show_major_lines;
bool m_show_minor_lines; bool m_show_minor_lines;
bool m_show_minor_ticks; bool m_show_minor_ticks;
bool m_show_major_ticks; bool m_show_major_ticks;
bool m_utcfix; bool m_utcfix;
QColor m_line_color; QColor m_line_color;
QColor m_text_color; QColor m_text_color;
QColor m_major_color; QColor m_major_color;
QColor m_minor_color; QColor m_minor_color;
bool m_fadeout; bool m_fadeout;
qint64 tz_offset; qint64 tz_offset;
float tz_hours; float tz_hours;
QImage m_image; QImage m_image;
GLuint m_textureID; GLuint m_textureID;
}; };
#endif // GXAXIS_H #endif // GXAXIS_H

View File

@ -15,114 +15,130 @@
#include "SleepLib/profiles.h" #include "SleepLib/profiles.h"
gXGrid::gXGrid(QColor col) gXGrid::gXGrid(QColor col)
:Layer(NoChannel) : Layer(NoChannel)
{ {
Q_UNUSED(col) Q_UNUSED(col)
m_major_color=QColor(180,180,180,64); m_major_color = QColor(180, 180, 180, 64);
//m_major_color=QColor(180,180,180,92); //m_major_color=QColor(180,180,180,92);
m_minor_color=QColor(230,230,230,64); m_minor_color = QColor(230, 230, 230, 64);
m_show_major_lines=true; m_show_major_lines = true;
m_show_minor_lines=true; m_show_minor_lines = true;
} }
gXGrid::~gXGrid() gXGrid::~gXGrid()
{ {
} }
void gXGrid::paint(gGraph & w,int left,int top, int width, int height) void gXGrid::paint(gGraph &w, int left, int top, int width, int height)
{ {
int x,y; int x, y;
gVertexBuffer * stippled, * lines; gVertexBuffer *stippled, * lines;
EventDataType miny,maxy; EventDataType miny, maxy;
if (w.zoomY()==0 && PROFILE.appearance->allowYAxisScaling()) { if (w.zoomY() == 0 && PROFILE.appearance->allowYAxisScaling()) {
miny=w.physMinY(); miny = w.physMinY();
maxy=w.physMaxY(); maxy = w.physMaxY();
} else { } else {
miny=w.min_y; miny = w.min_y;
maxy=w.max_y; maxy = w.max_y;
if (miny<0) { // even it up if it's starts negative if (miny < 0) { // even it up if it's starts negative
miny=-MAX(fabs(miny),fabs(maxy)); miny = -MAX(fabs(miny), fabs(maxy));
} }
} }
w.roundY(miny,maxy); w.roundY(miny, maxy);
//EventDataType dy=maxy-miny; //EventDataType dy=maxy-miny;
if (height<0) return; if (height < 0) { return; }
static QString fd="0"; static QString fd = "0";
GetTextExtent(fd,x,y); GetTextExtent(fd, x, y);
double max_yticks=round(height / (y+14.0)); // plus spacing between lines double max_yticks = round(height / (y + 14.0)); // plus spacing between lines
//double yt=1/max_yticks; //double yt=1/max_yticks;
double mxy=MAX(fabs(maxy),fabs(miny)); double mxy = MAX(fabs(maxy), fabs(miny));
double mny=miny; double mny = miny;
if (miny<0) {
mny=-mxy; if (miny < 0) {
mny = -mxy;
} }
double rxy=mxy-mny;
double rxy = mxy - mny;
int myt; int myt;
bool fnd=false; bool fnd = false;
for (myt=max_yticks;myt>=1;myt--) {
float v=rxy/float(myt); for (myt = max_yticks; myt >= 1; myt--) {
if (float(v)==int(v)) { float v = rxy / float(myt);
fnd=true;
if (float(v) == int(v)) {
fnd = true;
break; break;
} }
} }
if (fnd) max_yticks=myt;
if (fnd) { max_yticks = myt; }
else { else {
max_yticks=2; max_yticks = 2;
} }
double yt=1/max_yticks;
double ymult=height/rxy; double yt = 1 / max_yticks;
double min_ytick=rxy*yt; double ymult = height / rxy;
float ty,h; double min_ytick = rxy * yt;
if (min_ytick<=0) { float ty, h;
if (min_ytick <= 0) {
qDebug() << "min_ytick error in gXGrid::paint() in" << w.title(); qDebug() << "min_ytick error in gXGrid::paint() in" << w.title();
return; return;
} }
if (min_ytick>=1000000) {
min_ytick=100; if (min_ytick >= 1000000) {
min_ytick = 100;
} }
stippled=w.backlines(); stippled = w.backlines();
lines=w.backlines(); lines = w.backlines();
for (double i=miny; i<=maxy+min_ytick-0.00001; i+=min_ytick) {
ty=(i - miny) * ymult; for (double i = miny; i <= maxy + min_ytick - 0.00001; i += min_ytick) {
h=top+height-ty; ty = (i - miny) * ymult;
h = top + height - ty;
if (m_show_major_lines && (i > miny)) { if (m_show_major_lines && (i > miny)) {
stippled->add(left,h,left+width,h,m_major_color.rgba()); stippled->add(left, h, left + width, h, m_major_color.rgba());
} }
double z=(min_ytick/4)*ymult;
double g=h; double z = (min_ytick / 4) * ymult;
for (int i=0;i<3;i++) { double g = h;
g+=z;
if (g>top+height) break; for (int i = 0; i < 3; i++) {
g += z;
if (g > top + height) { break; }
//if (vertcnt>=maxverts) { //if (vertcnt>=maxverts) {
// qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick; // qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick;
// break; // break;
// } // }
if (m_show_minor_lines) {// && (i > miny)) { if (m_show_minor_lines) {// && (i > miny)) {
stippled->add(left,g,left+width,g,m_minor_color.rgba()); stippled->add(left, g, left + width, g, m_minor_color.rgba());
} }
if (stippled->full()) { if (stippled->full()) {
break; break;
} }
} }
if (lines->full() || stippled->full()) { if (lines->full() || stippled->full()) {
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick; qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<
miny << "MaxY =" << maxy << "min_ytick=" << min_ytick;
break; break;
} }
} }
@ -131,197 +147,205 @@ void gXGrid::paint(gGraph & w,int left,int top, int width, int height)
gYAxis::gYAxis(QColor col) gYAxis::gYAxis(QColor col)
:Layer(NoChannel) : Layer(NoChannel)
{ {
m_line_color=col; m_line_color = col;
m_text_color=col; m_text_color = col;
m_textureID=0; m_textureID = 0;
m_yaxis_scale=1; m_yaxis_scale = 1;
} }
gYAxis::~gYAxis() gYAxis::~gYAxis()
{ {
} }
void gYAxis::paint(gGraph & w,int left,int top, int width, int height) void gYAxis::paint(gGraph &w, int left, int top, int width, int height)
{ {
int x,y;//,yh=0; int x, y; //,yh=0;
//Todo: clean this up as there is a lot of duplicate code between the sections //Todo: clean this up as there is a lot of duplicate code between the sections
if (0) {//w.graphView()->usePixmapCache()) { if (0) {//w.graphView()->usePixmapCache()) {
/* if (w.invalidate_yAxisImage) { /* if (w.invalidate_yAxisImage) {
if (!m_image.isNull()) { if (!m_image.isNull()) {
w.graphView()->deleteTexture(m_textureID); w.graphView()->deleteTexture(m_textureID);
m_image=QImage(); m_image=QImage();
} }
if (height<0) return; if (height<0) return;
if (height>2000) return; if (height>2000) return;
int labelW=0; int labelW=0;
EventDataType miny=w.min_y; EventDataType miny=w.min_y;
EventDataType maxy=w.max_y; EventDataType maxy=w.max_y;
if (miny<0) { // even it up if it's starts negative if (miny<0) { // even it up if it's starts negative
miny=-MAX(fabs(miny),fabs(maxy)); miny=-MAX(fabs(miny),fabs(maxy));
} }
w.roundY(miny,maxy); w.roundY(miny,maxy);
EventDataType dy=maxy-miny; EventDataType dy=maxy-miny;
static QString fd="0"; static QString fd="0";
GetTextExtent(fd,x,y); GetTextExtent(fd,x,y);
yh=y; yh=y;
m_image=QImage(width,height+y+4,QImage::Format_ARGB32_Premultiplied); m_image=QImage(width,height+y+4,QImage::Format_ARGB32_Premultiplied);
m_image.fill(Qt::transparent); m_image.fill(Qt::transparent);
QPainter paint(&m_image); QPainter paint(&m_image);
double max_yticks=round(height / (y+14.0)); // plus spacing between lines double max_yticks=round(height / (y+14.0)); // plus spacing between lines
double mxy=MAX(fabs(maxy),fabs(miny)); double mxy=MAX(fabs(maxy),fabs(miny));
double mny=miny; double mny=miny;
if (miny<0) { if (miny<0) {
mny=-mxy; mny=-mxy;
} }
double rxy=mxy-mny; double rxy=mxy-mny;
int myt; int myt;
bool fnd=false; bool fnd=false;
for (myt=max_yticks;myt>2;myt--) { for (myt=max_yticks;myt>2;myt--) {
float v=rxy/float(myt); float v=rxy/float(myt);
if (v==int(v)) { if (v==int(v)) {
fnd=true; fnd=true;
break; break;
} }
} }
if (fnd) max_yticks=myt; if (fnd) max_yticks=myt;
double yt=1/max_yticks; double yt=1/max_yticks;
double ymult=height/rxy; double ymult=height/rxy;
double min_ytick=rxy*yt; double min_ytick=rxy*yt;
float ty,h; float ty,h;
if (min_ytick<=0) { if (min_ytick<=0) {
qDebug() << "min_ytick error in gYAxis::paint() in" << w.title(); qDebug() << "min_ytick error in gYAxis::paint() in" << w.title();
return; return;
} }
if (min_ytick>=1000000) { if (min_ytick>=1000000) {
min_ytick=100; min_ytick=100;
} }
//lines=w.backlines(); //lines=w.backlines();
for (double i=miny; i<=maxy+min_ytick-0.00001; i+=min_ytick) { for (double i=miny; i<=maxy+min_ytick-0.00001; i+=min_ytick) {
ty=(i - miny) * ymult; ty=(i - miny) * ymult;
if (dy<5) { if (dy<5) {
fd=Format(i*m_yaxis_scale,2); fd=Format(i*m_yaxis_scale,2);
} else { } else {
fd=Format(i*m_yaxis_scale,1); fd=Format(i*m_yaxis_scale,1);
}
GetTextExtent(fd,x,y);
if (x>labelW) labelW=x;
h=(height-2)-ty;
h+=yh;
#ifndef Q_OS_MAC
// stupid pixel alignment rubbish, I really should be using floats..
h+=1;
#endif
if (h<0)
continue;
paint.setBrush(Qt::black);
paint.drawText(width-8-x,h+y/2,fd);
paint.setPen(m_line_color);
paint.drawLine(width-4,h,width,h);
double z=(min_ytick/4)*ymult;
double g=h;
for (int i=0;i<3;i++) {
g+=z;
if (g>height+yh) break;
paint.drawLine(width-3,g,width,g);
}
}
paint.end();
m_image=QGLWidget::convertToGLFormat(m_image);
m_textureID=w.graphView()->bindTexture(m_image,GL_TEXTURE_2D,GL_RGBA,QGLContext::NoBindOption);
w.invalidate_yAxisImage=false;
} }
GetTextExtent(fd,x,y); if (!m_image.isNull()) {
glEnable(GL_BLEND);
if (x>labelW) labelW=x; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
h=(height-2)-ty; glEnable(GL_TEXTURE_2D);
h+=yh; w.graphView()->drawTexture(QPoint(left,(top+height)-m_image.height()+5),m_textureID);
#ifndef Q_OS_MAC glDisable(GL_TEXTURE_2D);
// stupid pixel alignment rubbish, I really should be using floats.. glDisable(GL_BLEND);
h+=1;
#endif
if (h<0)
continue;
paint.setBrush(Qt::black);
paint.drawText(width-8-x,h+y/2,fd);
paint.setPen(m_line_color);
paint.drawLine(width-4,h,width,h);
double z=(min_ytick/4)*ymult;
double g=h;
for (int i=0;i<3;i++) {
g+=z;
if (g>height+yh) break;
paint.drawLine(width-3,g,width,g);
} }
} */
paint.end();
m_image=QGLWidget::convertToGLFormat(m_image);
m_textureID=w.graphView()->bindTexture(m_image,GL_TEXTURE_2D,GL_RGBA,QGLContext::NoBindOption);
w.invalidate_yAxisImage=false;
}
if (!m_image.isNull()) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
w.graphView()->drawTexture(QPoint(left,(top+height)-m_image.height()+5),m_textureID);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}
*/
} else { } else {
if (height<0) return; if (height < 0) { return; }
if (height>2000) return;
int labelW=0; if (height > 2000) { return; }
int labelW = 0;
EventDataType miny; EventDataType miny;
EventDataType maxy; EventDataType maxy;
if (w.zoomY()==0 && PROFILE.appearance->allowYAxisScaling()) { if (w.zoomY() == 0 && PROFILE.appearance->allowYAxisScaling()) {
miny=w.physMinY(); miny = w.physMinY();
maxy=w.physMaxY(); maxy = w.physMaxY();
} else { } else {
miny=w.min_y; miny = w.min_y;
maxy=w.max_y; maxy = w.max_y;
if (miny<0) { // even it up if it's starts negative if (miny < 0) { // even it up if it's starts negative
miny=-MAX(fabs(miny),fabs(maxy)); miny = -MAX(fabs(miny), fabs(maxy));
} }
} }
w.roundY(miny,maxy);
EventDataType dy=maxy-miny; w.roundY(miny, maxy);
static QString fd="0"; EventDataType dy = maxy - miny;
GetTextExtent(fd,x,y);
double max_yticks=round(height / (y+14.0)); // plus spacing between lines static QString fd = "0";
GetTextExtent(fd, x, y);
double mxy=MAX(fabs(maxy),fabs(miny)); double max_yticks = round(height / (y + 14.0)); // plus spacing between lines
double mny=miny;
if (miny<0) { double mxy = MAX(fabs(maxy), fabs(miny));
mny=-mxy; double mny = miny;
if (miny < 0) {
mny = -mxy;
} }
double rxy=mxy-mny; double rxy = mxy - mny;
int myt; int myt;
bool fnd=false; bool fnd = false;
for (myt=max_yticks;myt>2;myt--) {
float v=rxy/float(myt); for (myt = max_yticks; myt > 2; myt--) {
if (v==int(v)) { float v = rxy / float(myt);
fnd=true;
if (v == int(v)) {
fnd = true;
break; break;
} }
} }
if (fnd) max_yticks=myt;
double yt=1/max_yticks;
double ymult=height/rxy; if (fnd) { max_yticks = myt; }
double min_ytick=rxy*yt; double yt = 1 / max_yticks;
double ymult = height / rxy;
double min_ytick = rxy * yt;
//if (dy>5) { //if (dy>5) {
@ -330,106 +354,128 @@ void gYAxis::paint(gGraph & w,int left,int top, int width, int height)
//} //}
float ty,h; float ty, h;
if (min_ytick<=0) { if (min_ytick <= 0) {
qDebug() << "min_ytick error in gYAxis::paint() in" << w.title(); qDebug() << "min_ytick error in gYAxis::paint() in" << w.title();
return; return;
} }
if (min_ytick>=1000000) {
min_ytick=100;
}
lines=w.backlines();
GLuint line_color=m_line_color.rgba(); if (min_ytick >= 1000000) {
for (double i=miny; i<=maxy+min_ytick-0.00001; i+=min_ytick) { min_ytick = 100;
ty=(i - miny) * ymult; }
if (dy<5) {
fd=Format(i*m_yaxis_scale,2); lines = w.backlines();
GLuint line_color = m_line_color.rgba();
for (double i = miny; i <= maxy + min_ytick - 0.00001; i += min_ytick) {
ty = (i - miny) * ymult;
if (dy < 5) {
fd = Format(i * m_yaxis_scale, 2);
} else { } else {
fd=Format(i*m_yaxis_scale,1); fd = Format(i * m_yaxis_scale, 1);
} }
GetTextExtent(fd,x,y); // performance bottleneck.. GetTextExtent(fd, x, y); // performance bottleneck..
if (x>labelW) labelW=x; if (x > labelW) { labelW = x; }
h=top+height-ty;
if (h<top) continue;
w.renderText(fd,left+width-8-x,(h+(y/2.0)),0,m_text_color,defaultfont);
lines->add(left+width-4,h,left+width,h,line_color); h = top + height - ty;
if (h < top) { continue; }
w.renderText(fd, left + width - 8 - x, (h + (y / 2.0)), 0, m_text_color, defaultfont);
lines->add(left + width - 4, h, left + width, h, line_color);
double z = (min_ytick / 4) * ymult;
double g = h;
for (int i = 0; i < 3; i++) {
g += z;
if (g > top + height) { break; }
lines->add(left + width - 3, g, left + width, g, line_color);
double z=(min_ytick/4)*ymult;
double g=h;
for (int i=0;i<3;i++) {
g+=z;
if (g>top+height) break;
lines->add(left+width-3,g,left+width,g,line_color);
if (lines->full()) { if (lines->full()) {
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick; qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<
miny << "MaxY =" << maxy << "min_ytick=" << min_ytick;
break; break;
} }
} }
if (lines->full()) { if (lines->full()) {
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick; qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<
miny << "MaxY =" << maxy << "min_ytick=" << min_ytick;
break; break;
} }
} }
} }
} }
const QString gYAxis::Format(EventDataType v, int dp) { const QString gYAxis::Format(EventDataType v, int dp)
return QString::number(v,'f',dp); {
return QString::number(v, 'f', dp);
} }
bool gYAxis::mouseMoveEvent(QMouseEvent * event, gGraph * graph) bool gYAxis::mouseMoveEvent(QMouseEvent *event, gGraph *graph)
{ {
if (!p_profile->appearance->graphTooltips()) if (!p_profile->appearance->graphTooltips()) {
return false; return false;
int x=event->x();
int y=event->y();
if (!graph->units().isEmpty()) {
graph->ToolTip(graph->units(),x,y-20,0);
// graph->redraw();
} }
int x = event->x();
int y = event->y();
if (!graph->units().isEmpty()) {
graph->ToolTip(graph->units(), x, y - 20, 0);
// graph->redraw();
}
return true; return true;
} }
bool gYAxis::mouseDoubleClickEvent(QMouseEvent * event, gGraph * graph) bool gYAxis::mouseDoubleClickEvent(QMouseEvent *event, gGraph *graph)
{ {
if (graph) { if (graph) {
// int x=event->x(); // int x=event->x();
// int y=event->y(); // int y=event->y();
short z=(graph->zoomY()+1) % gGraph::maxZoomY; short z = (graph->zoomY() + 1) % gGraph::maxZoomY;
graph->setZoomY(z); graph->setZoomY(z);
qDebug() << "Mouse double clicked for" << graph->title() << z; qDebug() << "Mouse double clicked for" << graph->title() << z;
} }
Q_UNUSED(event); Q_UNUSED(event);
return false; return false;
} }
const QString gYAxisTime::Format(EventDataType v, int dp) const QString gYAxisTime::Format(EventDataType v, int dp)
{ {
int h=int(v) % 24; int h = int(v) % 24;
int m=int(v*60) % 60; int m = int(v * 60) % 60;
int s=int(v*3600) % 60; int s = int(v * 3600) % 60;
char pm[3]={"am"}; char pm[3] = {"am"};
if (show_12hr) { if (show_12hr) {
h>=12 ? pm[0]='p' : pm[0]='a'; h >= 12 ? pm[0] = 'p' : pm[0] = 'a';
h %= 12; h %= 12;
if (h==0) h=12;
if (h == 0) { h = 12; }
} else { } else {
pm[0]=0; pm[0] = 0;
} }
if (dp>2) return QString().sprintf("%02i:%02i:%02i%s",h,m,s,pm);
return QString().sprintf("%i:%02i%s",h,m,pm); if (dp > 2) { return QString().sprintf("%02i:%02i:%02i%s", h, m, s, pm); }
return QString().sprintf("%i:%02i%s", h, m, pm);
} }
const QString gYAxisWeight::Format(EventDataType v, int dp) const QString gYAxisWeight::Format(EventDataType v, int dp)
{ {
Q_UNUSED(dp) Q_UNUSED(dp)
return weightString(v,m_unitsystem); return weightString(v, m_unitsystem);
} }

View File

@ -18,28 +18,28 @@
/*! \class gXGrid /*! \class gXGrid
\brief Draws the horizintal major/minor grids over graphs \brief Draws the horizintal major/minor grids over graphs
*/ */
class gXGrid:public Layer class gXGrid: public Layer
{ {
public: public:
//! \brief Constructs an gXGrid object with default settings, and col for line colour. //! \brief Constructs an gXGrid object with default settings, and col for line colour.
gXGrid(QColor col=QColor("black")); gXGrid(QColor col = QColor("black"));
virtual ~gXGrid(); virtual ~gXGrid();
//! \brief Draw the horizontal lines by adding the to the Vertex GLbuffers //! \brief Draw the horizontal lines by adding the to the Vertex GLbuffers
virtual void paint(gGraph & w,int left,int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
//! \brief set the visibility status of Major lines //! \brief set the visibility status of Major lines
void setShowMinorLines(bool b) { m_show_minor_lines=b; } void setShowMinorLines(bool b) { m_show_minor_lines = b; }
//! \brief set the visibility status of Minor lines //! \brief set the visibility status of Minor lines
void setShowMajorLines(bool b) { m_show_major_lines=b; } void setShowMajorLines(bool b) { m_show_major_lines = b; }
//! \brief Returns the visibility status of minor lines //! \brief Returns the visibility status of minor lines
bool showMinorLines() { return m_show_minor_lines; } bool showMinorLines() { return m_show_minor_lines; }
//! \brief Returns the visibility status of Major lines //! \brief Returns the visibility status of Major lines
bool showMajorLines() { return m_show_major_lines; } bool showMajorLines() { return m_show_major_lines; }
protected: protected:
bool m_show_major_lines; bool m_show_major_lines;
bool m_show_minor_lines; bool m_show_minor_lines;
QColor m_major_color; QColor m_major_color;
@ -49,73 +49,73 @@ protected:
/*! \class gYAxis /*! \class gYAxis
\brief Draws the YAxis tick markers, and numeric labels \brief Draws the YAxis tick markers, and numeric labels
*/ */
class gYAxis:public Layer class gYAxis: public Layer
{ {
public: public:
//! \brief Construct a gYAxis object, with QColor col for tickers & text //! \brief Construct a gYAxis object, with QColor col for tickers & text
gYAxis(QColor col=Qt::black); gYAxis(QColor col = Qt::black);
virtual ~gYAxis(); virtual ~gYAxis();
//! \brief Draw the horizontal tickers display //! \brief Draw the horizontal tickers display
virtual void paint(gGraph & w,int left,int top, int width, int height); virtual void paint(gGraph &w, int left, int top, int width, int height);
// void SetShowMinorLines(bool b) { m_show_minor_lines=b; } // void SetShowMinorLines(bool b) { m_show_minor_lines=b; }
// void SetShowMajorLines(bool b) { m_show_major_lines=b; } // void SetShowMajorLines(bool b) { m_show_major_lines=b; }
// bool ShowMinorLines() { return m_show_minor_lines; } // bool ShowMinorLines() { return m_show_minor_lines; }
// bool ShowMajorLines() { return m_show_major_lines; } // bool ShowMajorLines() { return m_show_major_lines; }
//! \brief Sets the visibility status of minor ticks //! \brief Sets the visibility status of minor ticks
void SetShowMinorTicks(bool b) { m_show_minor_ticks=b; } void SetShowMinorTicks(bool b) { m_show_minor_ticks = b; }
//! \brief Sets the visibility status of Major ticks //! \brief Sets the visibility status of Major ticks
void SetShowMajorTicks(bool b) { m_show_major_ticks=b; } void SetShowMajorTicks(bool b) { m_show_major_ticks = b; }
//! \brief Returns the visibility status of Minor ticks //! \brief Returns the visibility status of Minor ticks
bool ShowMinorTicks() { return m_show_minor_ticks; } bool ShowMinorTicks() { return m_show_minor_ticks; }
//! \brief Returns the visibility status of Major ticks //! \brief Returns the visibility status of Major ticks
bool ShowMajorTicks() { return m_show_major_ticks; } bool ShowMajorTicks() { return m_show_major_ticks; }
//! \brief Formats the ticker value.. Override to implement other types //! \brief Formats the ticker value.. Override to implement other types
virtual const QString Format(EventDataType v, int dp); virtual const QString Format(EventDataType v, int dp);
//! \brief Left Margin space in pixels //! \brief Left Margin space in pixels
static const int Margin=60; static const int Margin = 60;
//! \brief Set the scale of the Y axis values.. Values can be multiplied by this to convert formats //! \brief Set the scale of the Y axis values.. Values can be multiplied by this to convert formats
void SetScale(float f) { m_yaxis_scale=f; } void SetScale(float f) { m_yaxis_scale = f; }
//! \brief Returns the scale of the Y axis values.. Values can be multiplied by this to convert formats //! \brief Returns the scale of the Y axis values.. Values can be multiplied by this to convert formats
float Scale() { return m_yaxis_scale; } float Scale() { return m_yaxis_scale; }
protected: protected:
//bool m_show_major_lines; //bool m_show_major_lines;
//bool m_show_minor_lines; //bool m_show_minor_lines;
bool m_show_minor_ticks; bool m_show_minor_ticks;
bool m_show_major_ticks; bool m_show_major_ticks;
float m_yaxis_scale; float m_yaxis_scale;
QColor m_line_color; QColor m_line_color;
QColor m_text_color; QColor m_text_color;
gVertexBuffer * lines; gVertexBuffer *lines;
virtual bool mouseMoveEvent(QMouseEvent * event,gGraph * graph); virtual bool mouseMoveEvent(QMouseEvent *event, gGraph *graph);
virtual bool mouseDoubleClickEvent(QMouseEvent * event, gGraph * graph); virtual bool mouseDoubleClickEvent(QMouseEvent *event, gGraph *graph);
QImage m_image; QImage m_image;
GLuint m_textureID; GLuint m_textureID;
}; };
/*! \class gYAxisTime /*! \class gYAxisTime
\brief Draws the YAxis tick markers, and labels in time format \brief Draws the YAxis tick markers, and labels in time format
*/ */
class gYAxisTime:public gYAxis class gYAxisTime: public gYAxis
{ {
public: public:
//! \brief Construct a gYAxisTime object, with QColor col for tickers & times //! \brief Construct a gYAxisTime object, with QColor col for tickers & times
gYAxisTime(bool hr12=true, QColor col=Qt::black) : gYAxis(col), show_12hr(hr12) {} gYAxisTime(bool hr12 = true, QColor col = Qt::black) : gYAxis(col), show_12hr(hr12) {}
virtual ~gYAxisTime() {} virtual ~gYAxisTime() {}
protected: protected:
//! \brief Overrides gYAxis Format to display Time format //! \brief Overrides gYAxis Format to display Time format
virtual const QString Format(EventDataType v, int dp); virtual const QString Format(EventDataType v, int dp);
@ -127,19 +127,19 @@ protected:
/*! \class gYAxisWeight /*! \class gYAxisWeight
\brief Draws the YAxis tick markers, and labels in weight format \brief Draws the YAxis tick markers, and labels in weight format
*/ */
class gYAxisWeight:public gYAxis class gYAxisWeight: public gYAxis
{ {
public: public:
//! \brief Construct a gYAxisWeight object, with QColor col for tickers & weight values //! \brief Construct a gYAxisWeight object, with QColor col for tickers & weight values
gYAxisWeight(UnitSystem us=US_Metric, QColor col=Qt::black) :gYAxis(col), m_unitsystem(us) {} gYAxisWeight(UnitSystem us = US_Metric, QColor col = Qt::black) : gYAxis(col), m_unitsystem(us) {}
virtual ~gYAxisWeight() {} virtual ~gYAxisWeight() {}
//! \brief Returns the current UnitSystem displayed (eg, US_Metric (the rest of the world), US_Archiac (American) ) //! \brief Returns the current UnitSystem displayed (eg, US_Metric (the rest of the world), US_Archiac (American) )
UnitSystem unitSystem() { return m_unitsystem; } UnitSystem unitSystem() { return m_unitsystem; }
//! \brief Set the unit system displayed by this YTicker //! \brief Set the unit system displayed by this YTicker
void setUnitSystem(UnitSystem us) { m_unitsystem=us; } void setUnitSystem(UnitSystem us) { m_unitsystem = us; }
protected: protected:
//! \brief Overrides gYAxis Format to display Time format //! \brief Overrides gYAxis Format to display Time format
virtual const QString Format(EventDataType v, int dp); virtual const QString Format(EventDataType v, int dp);
UnitSystem m_unitsystem; UnitSystem m_unitsystem;

View File

@ -15,59 +15,80 @@
#ifdef BUILD_WITH_MSVC #ifdef BUILD_WITH_MSVC
double round(double number) double round(double number)
{ {
return number < 0.0 ? ceil(number - 0.5) : floor(number+0.5); return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5);
} }
#endif #endif
void RoundedRectangle(int x,int y,int w,int h,int radius,const QColor color) void RoundedRectangle(int x, int y, int w, int h, int radius, const QColor color)
{ {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4ub(color.red(),color.green(),color.blue(),color.alpha()); glColor4ub(color.red(), color.green(), color.blue(), color.alpha());
glBegin(GL_POLYGON); glBegin(GL_POLYGON);
glVertex2i(x+radius,y); glVertex2i(x + radius, y);
glVertex2i(x+w-radius,y); glVertex2i(x + w - radius, y);
for(float i=(float)M_PI*1.5f;i<M_PI*2;i+=0.1f)
glVertex2f(x+w-radius+cos(i)*radius,y+radius+sin(i)*radius); for (float i = (float)M_PI * 1.5f; i < M_PI * 2; i += 0.1f) {
glVertex2i(x+w,y+radius); glVertex2f(x + w - radius + cos(i)*radius, y + radius + sin(i)*radius);
glVertex2i(x+w,y+h-radius); }
for(float i=0;i<(float)M_PI*0.5f;i+=0.1f)
glVertex2f(x+w-radius+cos(i)*radius,y+h-radius+sin(i)*radius); glVertex2i(x + w, y + radius);
glVertex2i(x+w-radius,y+h); glVertex2i(x + w, y + h - radius);
glVertex2i(x+radius,y+h);
for(float i=(float)M_PI*0.5f;i<M_PI;i+=0.1f) for (float i = 0; i < (float)M_PI * 0.5f; i += 0.1f) {
glVertex2f(x+radius+cos(i)*radius,y+h-radius+sin(i)*radius); glVertex2f(x + w - radius + cos(i)*radius, y + h - radius + sin(i)*radius);
glVertex2i(x,y+h-radius); }
glVertex2i(x,y+radius);
for(float i=(float)M_PI;i<M_PI*1.5f;i+=0.1f) glVertex2i(x + w - radius, y + h);
glVertex2f(x+radius+cos(i)*radius,y+radius+sin(i)*radius); glVertex2i(x + radius, y + h);
for (float i = (float)M_PI * 0.5f; i < M_PI; i += 0.1f) {
glVertex2f(x + radius + cos(i)*radius, y + h - radius + sin(i)*radius);
}
glVertex2i(x, y + h - radius);
glVertex2i(x, y + radius);
for (float i = (float)M_PI; i < M_PI * 1.5f; i += 0.1f) {
glVertex2f(x + radius + cos(i)*radius, y + radius + sin(i)*radius);
}
glEnd(); glEnd();
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
void LinedRoundedRectangle(int x,int y,int w,int h,int radius,int lw,QColor color) void LinedRoundedRectangle(int x, int y, int w, int h, int radius, int lw, QColor color)
{ {
//glDisable(GL_TEXTURE_2D); //glDisable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4ub(color.red(),color.green(),color.blue(),color.alpha()); glColor4ub(color.red(), color.green(), color.blue(), color.alpha());
glLineWidth((GLfloat)lw); glLineWidth((GLfloat)lw);
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
for(float i=(float)M_PI;i<=1.5f*M_PI;i+=0.1f)
glVertex2f(radius*cos(i)+x+radius,radius*sin(i)+y+radius); for (float i = (float)M_PI; i <= 1.5f * M_PI; i += 0.1f) {
for(float i=1.5f*(float)M_PI;i<=2*M_PI; i+=0.1f) glVertex2f(radius * cos(i) + x + radius, radius * sin(i) + y + radius);
glVertex2f(radius*cos(i)+x+w-radius,radius*sin(i)+y+radius); }
for(float i=0;i<=0.5f*M_PI; i+=0.1f)
glVertex2f(radius*cos(i)+x+w-radius,radius*sin(i)+y+h-radius); for (float i = 1.5f * (float)M_PI; i <= 2 * M_PI; i += 0.1f) {
for(float i=0.5f*(float)M_PI;i<=M_PI;i+=0.1f) glVertex2f(radius * cos(i) + x + w - radius, radius * sin(i) + y + radius);
glVertex2f(radius*cos(i)+x+radius,radius*sin(i)+y+h-radius); }
glVertex2i(x,y+radius);
for (float i = 0; i <= 0.5f * M_PI; i += 0.1f) {
glVertex2f(radius * cos(i) + x + w - radius, radius * sin(i) + y + h - radius);
}
for (float i = 0.5f * (float)M_PI; i <= M_PI; i += 0.1f) {
glVertex2f(radius * cos(i) + x + radius, radius * sin(i) + y + h - radius);
}
glVertex2i(x, y + radius);
glEnd(); glEnd();
//glEnable(GL_TEXTURE_2D); //glEnable(GL_TEXTURE_2D);

View File

@ -15,37 +15,39 @@
#include <QtOpenGL/qgl.h> #include <QtOpenGL/qgl.h>
#include <QColor> #include <QColor>
const QColor COLOR_Black=Qt::black; const QColor COLOR_Black = Qt::black;
const QColor COLOR_LightGreen=QColor("light green"); const QColor COLOR_LightGreen = QColor("light green");
const QColor COLOR_DarkGreen=Qt::darkGreen; const QColor COLOR_DarkGreen = Qt::darkGreen;
const QColor COLOR_Purple=QColor("purple"); const QColor COLOR_Purple = QColor("purple");
const QColor COLOR_Aqua=QColor("#40c0ff"); const QColor COLOR_Aqua = QColor("#40c0ff");
const QColor COLOR_Magenta=Qt::magenta; const QColor COLOR_Magenta = Qt::magenta;
const QColor COLOR_Blue=Qt::blue; const QColor COLOR_Blue = Qt::blue;
const QColor COLOR_LightBlue=QColor("light blue"); const QColor COLOR_LightBlue = QColor("light blue");
const QColor COLOR_Gray=Qt::gray; const QColor COLOR_Gray = Qt::gray;
const QColor COLOR_LightGray=Qt::lightGray; const QColor COLOR_LightGray = Qt::lightGray;
const QColor COLOR_DarkGray=Qt::darkGray; const QColor COLOR_DarkGray = Qt::darkGray;
const QColor COLOR_Cyan=Qt::cyan; const QColor COLOR_Cyan = Qt::cyan;
const QColor COLOR_DarkCyan=Qt::darkCyan; const QColor COLOR_DarkCyan = Qt::darkCyan;
const QColor COLOR_DarkBlue=Qt::darkBlue; const QColor COLOR_DarkBlue = Qt::darkBlue;
const QColor COLOR_DarkMagenta=Qt::darkMagenta; const QColor COLOR_DarkMagenta = Qt::darkMagenta;
const QColor COLOR_Gold=QColor("gold"); const QColor COLOR_Gold = QColor("gold");
const QColor COLOR_White=Qt::white; const QColor COLOR_White = Qt::white;
const QColor COLOR_Red=Qt::red; const QColor COLOR_Red = Qt::red;
const QColor COLOR_Pink=QColor("pink"); const QColor COLOR_Pink = QColor("pink");
const QColor COLOR_DarkRed=Qt::darkRed; const QColor COLOR_DarkRed = Qt::darkRed;
const QColor COLOR_Yellow=Qt::yellow; const QColor COLOR_Yellow = Qt::yellow;
const QColor COLOR_DarkYellow=Qt::darkYellow; const QColor COLOR_DarkYellow = Qt::darkYellow;
const QColor COLOR_Orange=QColor("orange"); const QColor COLOR_Orange = QColor("orange");
const QColor COLOR_Green=Qt::green; const QColor COLOR_Green = Qt::green;
const QColor COLOR_Brown=QColor("brown"); const QColor COLOR_Brown = QColor("brown");
const QColor COLOR_Text=Qt::black; const QColor COLOR_Text = Qt::black;
const QColor COLOR_Outline=Qt::black; const QColor COLOR_Outline = Qt::black;
const QColor COLOR_ALT_BG1=QColor(0xd8,0xff,0xd8,0xff); // Alternating Background Color 1 (Event Flags) const QColor COLOR_ALT_BG1 = QColor(0xd8, 0xff, 0xd8,
const QColor COLOR_ALT_BG2=COLOR_White; // Alternating Background Color 2 (Event Flags) 0xff); // Alternating Background Color 1 (Event Flags)
const QColor COLOR_ALT_BG2 =
COLOR_White; // Alternating Background Color 2 (Event Flags)
/*! \brief Draw an outline of a rounded rectangle /*! \brief Draw an outline of a rounded rectangle
@ -53,17 +55,17 @@ const QColor COLOR_ALT_BG2=COLOR_White; // Alternating Backgroun
\param lw Line Width \param lw Line Width
\param color Color of drawn lines \param color Color of drawn lines
*/ */
void LinedRoundedRectangle(int x,int y,int w,int h,int radius,int lw,QColor color); void LinedRoundedRectangle(int x, int y, int w, int h, int radius, int lw, QColor color);
/*! \brief Draws a filled rounded rectangle /*! \brief Draws a filled rounded rectangle
\param radius Radius of corner rounding \param radius Radius of corner rounding
\param color Color of entire rectangle \param color Color of entire rectangle
*/ */
void RoundedRectangle(int x,int y,int w,int h,int radius,const QColor color); void RoundedRectangle(int x, int y, int w, int h, int radius, const QColor color);
#ifdef BUILD_WITH_MSVC #ifdef BUILD_WITH_MSVC
// Visual C++ doesn't have either of these in it's maths header.. I'm not surprised at Microsofts maths abilities.. // Visual C++ doesn't have either of these in it's maths header.. I'm not surprised at Microsofts maths abilities..
const double M_PI=3.141592653589793; const double M_PI = 3.141592653589793;
double round(double number); double round(double number);
#endif #endif

View File

@ -12,7 +12,7 @@
#include "gspacer.h" #include "gspacer.h"
gSpacer::gSpacer(int space) gSpacer::gSpacer(int space)
:Layer(NoChannel) : Layer(NoChannel)
{ {
m_space=space; m_space = space;
} }

View File

@ -18,21 +18,21 @@
/*! \class gSpacer /*! \class gSpacer
\brief A dummy graph spacer layer object \brief A dummy graph spacer layer object
*/ */
class gSpacer:public Layer class gSpacer: public Layer
{ {
public: public:
gSpacer(int space=20); // orientation? gSpacer(int space = 20); // orientation?
virtual void paint(gGraph & g,int left,int top, int width, int height) { virtual void paint(gGraph &g, int left, int top, int width, int height) {
Q_UNUSED(g) Q_UNUSED(g)
Q_UNUSED(left) Q_UNUSED(left)
Q_UNUSED(top) Q_UNUSED(top)
Q_UNUSED(width) Q_UNUSED(width)
Q_UNUSED(height) Q_UNUSED(height)
} }
int space() { return m_space; } int space() { return m_space; }
protected: protected:
int m_space; int m_space;
}; };
#endif // GSPACER_H #endif // GSPACER_H