2011-08-25 08:02:04 +00:00
/*
2011-06-26 08:30:44 +00:00
gYAxis Implementation
Copyright ( c ) 2011 Mark Watkins < jedimark @ users . sourceforge . net >
License : GPL
2011-08-25 08:02:04 +00:00
*/
2011-06-26 08:30:44 +00:00
# include <math.h>
2011-07-19 15:31:51 +00:00
# include <QDebug>
2011-06-26 08:30:44 +00:00
# include "gYAxis.h"
2011-08-25 08:02:04 +00:00
gYSpacer : : gYSpacer ( int spacer ) : Layer ( EmptyChannel )
2011-08-25 06:11:44 +00:00
{
} ;
2011-08-25 10:38:42 +00:00
gXGrid : : gXGrid ( QColor col )
: Layer ( EmptyChannel )
{
m_major_color = QColor ( 190 , 190 , 190 , 64 ) ;
m_minor_color = QColor ( 220 , 220 , 220 , 64 ) ;
m_show_major_lines = true ;
m_show_minor_lines = true ;
}
gXGrid : : ~ gXGrid ( )
{
}
void gXGrid : : paint ( gGraph & w , int left , int top , int width , int height )
{
float x , y ;
double miny = w . min_y ;
double maxy = w . max_y ;
if ( miny < 0 ) {
miny = - MAX ( fabs ( miny ) , fabs ( maxy ) ) ;
}
double dy = maxy - miny ;
if ( dy < = 0 ) {
2011-08-29 07:13:58 +00:00
if ( ( maxy = = 0 ) & & ( miny = = 0 ) )
return ;
2011-08-25 10:38:42 +00:00
//miny=miny;
maxy + + ;
dy = 1 ;
}
int m ;
if ( maxy > 500 ) {
m = ceil ( maxy / 100.0 ) ;
maxy = m * 100 ;
m = floor ( miny / 100.0 ) ;
miny = m * 100 ;
} else if ( maxy > 150 ) {
m = ceil ( maxy / 50.0 ) ;
maxy = m * 50 ;
m = floor ( miny / 50.0 ) ;
miny = m * 50 ;
} else if ( maxy > 80 ) {
m = ceil ( maxy / 20.0 ) ;
maxy = m * 20 ;
m = floor ( miny / 20.0 ) ;
miny = m * 20 ;
} else if ( maxy > 30 ) {
m = ceil ( maxy / 10.0 ) ;
maxy = m * 10 ;
m = floor ( miny / 10.0 ) ;
miny = m * 10 ;
} else if ( maxy > 5 ) {
m = ceil ( maxy / 5.0 ) ;
maxy = m * 5 ;
m = floor ( miny / 5.0 ) ;
miny = m * 5 ;
}
if ( height < 0 ) return ;
QString fd = " 0 " ;
GetTextExtent ( fd , x , y ) ;
double max_yticks = round ( height / ( y + 15.0 ) ) ; // plus spacing between lines
double yt = 1 / max_yticks ;
double mxy = MAX ( fabs ( maxy ) , fabs ( miny ) ) ;
double mny = miny ;
if ( miny < 0 ) {
mny = - mxy ;
}
double rxy = mxy - mny ;
double ymult = height / rxy ;
double min_ytick = rxy * yt ;
float ty , h ;
qint32 vertcnt = 0 ;
GLshort * vertarray = ( GLshort * ) vertex_array [ 0 ] ;
qint32 minorvertcnt = 0 ;
GLshort * minorvertarray = ( GLshort * ) vertex_array [ 1 ] ;
qint32 majorvertcnt = 0 ;
GLshort * majorvertarray = ( GLshort * ) vertex_array [ 2 ] ;
if ( ( vertarray = = NULL ) | | ( minorvertarray = = NULL ) | | ( majorvertarray = = NULL ) ) {
qWarning ( ) < < " gXGrid::Paint() VertArray==NULL " ;
return ;
}
if ( min_ytick < = 0 ) {
qDebug ( ) < < " min_ytick error in gXGrid::paint() " ;
return ;
}
if ( min_ytick > = 1000000 ) {
min_ytick = 100 ;
}
double q = ( ( maxy - ( miny + ( min_ytick / 2.0 ) ) ) / min_ytick ) * 4 ;
if ( q > = maxverts ) {
qDebug ( ) < < " Would exeed maxverts. Should be another two bounds exceeded messages after this. (I can do a minor optimisation by disabling the other checks if this turns out to be consistent) " < < q < < maxverts ;
}
for ( double i = miny ; i < = maxy + min_ytick - 0.00001 ; i + = min_ytick ) {
ty = ( i - miny ) * ymult ;
h = top + height - ty ;
if ( m_show_major_lines & & ( i > miny ) ) {
majorvertarray [ majorvertcnt + + ] = left ;
majorvertarray [ majorvertcnt + + ] = h ;
majorvertarray [ majorvertcnt + + ] = left + width ;
majorvertarray [ majorvertcnt + + ] = h ;
}
double z = ( min_ytick / 4 ) * ymult ;
double g = h ;
for ( int i = 0 ; i < 3 ; i + + ) {
g + = z ;
if ( g > top + height ) break ;
if ( vertcnt > = maxverts ) {
qWarning ( ) < < " vertarray bounds exceeded in gYAxis for " < < w . title ( ) < < " graph " < < " MinY = " < < miny < < " MaxY = " < < maxy < < " min_ytick= " < < min_ytick ;
break ;
}
if ( m_show_minor_lines ) { // && (i > miny)) {
minorvertarray [ minorvertcnt + + ] = left ;
minorvertarray [ minorvertcnt + + ] = g ;
minorvertarray [ minorvertcnt + + ] = left + width ;
minorvertarray [ minorvertcnt + + ] = g ;
}
2011-08-29 07:13:58 +00:00
if ( minorvertcnt > = maxverts ) {
break ;
}
2011-08-25 10:38:42 +00:00
}
2011-08-29 07:13:58 +00:00
if ( ( majorvertcnt > = maxverts ) | | ( minorvertcnt > = maxverts ) ) {
2011-08-25 10:38:42 +00:00
qWarning ( ) < < " vertarray bounds exceeded in gYAxis for " < < w . title ( ) < < " graph " < < " MinY = " < < miny < < " MaxY = " < < maxy < < " min_ytick= " < < min_ytick ;
break ;
}
}
if ( vertcnt > = maxverts ) {
qWarning ( ) < < " gXGrid tickers and display should be corrupted, because something dumb is happening in " < < w . title ( ) < < " graph " ;
return ;
}
// Draw the lines & ticks
// Turn on blending??
2011-08-26 05:36:41 +00:00
2011-08-25 10:38:42 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
2011-08-26 05:36:41 +00:00
glLineWidth ( 1 ) ;
2011-08-25 10:38:42 +00:00
w . qglColor ( m_minor_color ) ;
glVertexPointer ( 2 , GL_SHORT , 0 , minorvertarray ) ;
glDrawArrays ( GL_LINES , 0 , minorvertcnt > > 1 ) ;
w . qglColor ( m_major_color ) ;
glVertexPointer ( 2 , GL_SHORT , 0 , majorvertarray ) ;
glDrawArrays ( GL_LINES , 0 , majorvertcnt > > 1 ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ; // deactivate vertex arrays after drawing
}
2011-06-26 08:30:44 +00:00
gYAxis : : gYAxis ( QColor col )
2011-08-25 06:11:44 +00:00
: Layer ( EmptyChannel )
2011-06-26 08:30:44 +00:00
{
2011-08-02 04:20:26 +00:00
m_line_color = col ;
m_text_color = col ;
2011-08-25 10:38:42 +00:00
//m_major_color=QColor(190,190,190,64);
//m_minor_color=QColor(220,220,220,64);
2011-06-26 08:30:44 +00:00
2011-07-11 01:58:51 +00:00
m_yaxis_scale = 1 ;
2011-06-26 08:30:44 +00:00
}
gYAxis : : ~ gYAxis ( )
{
}
2011-08-25 06:11:44 +00:00
void gYAxis : : paint ( gGraph & w , int left , int top , int width , int height )
2011-06-26 08:30:44 +00:00
{
float x , y ;
int labelW = 0 ;
double miny = w . min_y ;
double maxy = w . max_y ;
2011-07-27 09:21:53 +00:00
2011-08-07 11:37:56 +00:00
if ( miny < 0 ) {
miny = - MAX ( fabs ( miny ) , fabs ( maxy ) ) ;
}
2011-07-27 09:21:53 +00:00
double dy = maxy - miny ;
2011-08-07 06:21:09 +00:00
if ( dy < = 0 ) {
2011-08-29 07:13:58 +00:00
if ( ( maxy = = 0 ) & & ( miny = = 0 ) )
return ;
2011-08-07 08:52:12 +00:00
//miny=miny;
maxy + + ;
dy = 1 ;
2011-08-07 06:21:09 +00:00
}
2011-07-27 09:21:53 +00:00
2011-08-07 11:37:56 +00:00
2011-07-27 09:21:53 +00:00
int m ;
if ( maxy > 500 ) {
m = ceil ( maxy / 100.0 ) ;
maxy = m * 100 ;
m = floor ( miny / 100.0 ) ;
miny = m * 100 ;
} else if ( maxy > 150 ) {
m = ceil ( maxy / 50.0 ) ;
maxy = m * 50 ;
m = floor ( miny / 50.0 ) ;
miny = m * 50 ;
} else if ( maxy > 80 ) {
m = ceil ( maxy / 20.0 ) ;
maxy = m * 20 ;
m = floor ( miny / 20.0 ) ;
miny = m * 20 ;
} else if ( maxy > 30 ) {
m = ceil ( maxy / 10.0 ) ;
maxy = m * 10 ;
m = floor ( miny / 10.0 ) ;
miny = m * 10 ;
} else if ( maxy > 5 ) {
m = ceil ( maxy / 5.0 ) ;
maxy = m * 5 ;
m = floor ( miny / 5.0 ) ;
miny = m * 5 ;
} else {
2011-08-07 08:52:12 +00:00
//maxy=ceil(maxy);
//if (maxy<1) maxy=1;
//miny=floor(miny);
2011-08-01 08:27:03 +00:00
//if (miny<1) miny=0;
2011-07-27 09:21:53 +00:00
}
2011-07-18 02:33:25 +00:00
//if ((w.max_x-w.min_x)==0)
// return;
2011-06-26 08:30:44 +00:00
if ( height < 0 ) return ;
QString fd = " 0 " ;
GetTextExtent ( fd , x , y ) ;
double max_yticks = round ( height / ( y + 15.0 ) ) ; // plus spacing between lines
double yt = 1 / max_yticks ;
2011-08-07 08:52:12 +00:00
double mxy = MAX ( fabs ( maxy ) , fabs ( miny ) ) ;
2011-08-07 11:37:56 +00:00
double mny = miny ;
if ( miny < 0 ) {
mny = - mxy ;
} else {
}
//double mny=MIN(fabs(maxy),fabs(miny));
//if (miny<0) mny=-mny;
//if (maxy<0) mxy=-mxy;
2011-08-07 08:52:12 +00:00
//mny=miny;
//mxy=maxy;
2011-06-26 08:30:44 +00:00
double rxy = mxy - mny ;
double ymult = height / rxy ;
double min_ytick = rxy * yt ;
float ty , h ;
2011-06-28 01:51:21 +00:00
qint32 vertcnt = 0 ;
2011-08-02 04:20:26 +00:00
GLshort * vertarray = ( GLshort * ) vertex_array [ 0 ] ;
qint32 minorvertcnt = 0 ;
GLshort * minorvertarray = ( GLshort * ) vertex_array [ 1 ] ;
qint32 majorvertcnt = 0 ;
GLshort * majorvertarray = ( GLshort * ) vertex_array [ 2 ] ;
if ( ( vertarray = = NULL ) | | ( minorvertarray = = NULL ) | | ( majorvertarray = = NULL ) ) {
qWarning ( ) < < " gYAxis::Plot() VertArray==NULL " ;
2011-07-24 16:34:53 +00:00
return ;
}
2011-06-26 08:30:44 +00:00
2011-07-23 03:50:30 +00:00
if ( min_ytick < = 0 ) {
qDebug ( ) < < " min_ytick error in gYAxis::Plot() " ;
return ;
}
2011-07-02 16:07:38 +00:00
if ( min_ytick > = 1000000 ) {
min_ytick = 100 ;
}
2011-06-26 08:30:44 +00:00
2011-08-02 04:42:41 +00:00
double q = ( ( maxy - ( miny + ( min_ytick / 2.0 ) ) ) / min_ytick ) * 4 ;
if ( q > = maxverts ) {
qDebug ( ) < < " Would exeed maxverts. Should be another two bounds exceeded messages after this. (I can do a minor optimisation by disabling the other checks if this turns out to be consistent) " < < q < < maxverts ;
}
2011-08-06 12:46:27 +00:00
w . qglColor ( m_text_color ) ;
2011-06-30 09:37:24 +00:00
for ( double i = miny ; i < = maxy + min_ytick - 0.00001 ; i + = min_ytick ) {
2011-06-26 08:30:44 +00:00
ty = ( i - miny ) * ymult ;
2011-07-11 01:58:51 +00:00
fd = Format ( i * m_yaxis_scale ) ; // Override this as a function.
2011-06-26 08:30:44 +00:00
GetTextExtent ( fd , x , y ) ;
if ( x > labelW ) labelW = x ;
2011-08-25 06:11:44 +00:00
h = top + height - ty ;
2011-08-07 00:53:33 +00:00
//w.renderText(start_px-12-x,scry-(h-(y/2.0)),fd);
2011-08-25 06:11:44 +00:00
//DrawText(w,fd,left+width-8-x,(h+(y/2.0)),0,m_text_color);
w . renderText ( fd , left + width - 8 - x , ( h + ( y / 2.0 ) ) , 0 , m_text_color ) ;
2011-06-26 08:30:44 +00:00
2011-08-25 06:11:44 +00:00
vertarray [ vertcnt + + ] = left + width - 4 ;
2011-06-26 08:30:44 +00:00
vertarray [ vertcnt + + ] = h ;
2011-08-25 06:11:44 +00:00
vertarray [ vertcnt + + ] = left + width ;
2011-06-26 08:30:44 +00:00
vertarray [ vertcnt + + ] = h ;
2011-08-07 08:52:12 +00:00
double z = ( min_ytick / 4 ) * ymult ;
double g = h ;
for ( int i = 0 ; i < 3 ; i + + ) {
g + = z ;
2011-08-25 06:11:44 +00:00
if ( g > top + height ) break ;
vertarray [ vertcnt + + ] = left + width - 3 ;
2011-08-07 08:52:12 +00:00
vertarray [ vertcnt + + ] = g ;
2011-08-25 06:11:44 +00:00
vertarray [ vertcnt + + ] = left + width ;
2011-08-07 08:52:12 +00:00
vertarray [ vertcnt + + ] = g ;
if ( vertcnt > = maxverts ) {
2011-08-25 06:11:44 +00:00
qWarning ( ) < < " vertarray bounds exceeded in gYAxis for " < < w . title ( ) < < " graph " < < " MinY = " < < miny < < " MaxY = " < < maxy < < " min_ytick= " < < min_ytick ;
2011-08-07 08:52:12 +00:00
break ;
}
}
if ( vertcnt > = maxverts ) {
2011-08-25 06:11:44 +00:00
qWarning ( ) < < " vertarray bounds exceeded in gYAxis for " < < w . title ( ) < < " graph " < < " MinY = " < < miny < < " MaxY = " < < maxy < < " min_ytick= " < < min_ytick ;
2011-08-07 08:52:12 +00:00
break ;
}
2011-06-26 08:30:44 +00:00
}
2011-07-19 15:31:51 +00:00
if ( vertcnt > = maxverts ) {
2011-08-25 06:11:44 +00:00
qWarning ( ) < < " yAxis tickers and display should be corrupted, because something dumb is happening in " < < w . title ( ) < < " graph " ;
2011-07-19 15:31:51 +00:00
return ;
}
2011-06-26 08:30:44 +00:00
2011-08-02 04:20:26 +00:00
// Draw the lines & ticks
// Turn on blending??
2011-06-26 08:30:44 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
2011-08-26 05:36:41 +00:00
glLineWidth ( 1 ) ;
2011-08-25 15:58:52 +00:00
w . qglColor ( m_line_color ) ;
2011-06-26 08:30:44 +00:00
glVertexPointer ( 2 , GL_SHORT , 0 , vertarray ) ;
glDrawArrays ( GL_LINES , 0 , vertcnt > > 1 ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ; // deactivate vertex arrays after drawing
}