Minor Ticks for gXAxis

This commit is contained in:
Mark Watkins 2011-08-06 19:17:26 +10:00
parent 5444092e76
commit 4dd741db6f

View File

@ -32,7 +32,7 @@ gXAxis::~gXAxis()
} }
void gXAxis::Plot(gGraphWindow & w,float scrx,float scry) void gXAxis::Plot(gGraphWindow & w,float scrx,float scry)
{ {
float px,py; double px,py;
int start_px=w.GetLeftMargin(); int start_px=w.GetLeftMargin();
int start_py=w.GetBottomMargin(); int start_py=w.GetBottomMargin();
@ -53,25 +53,23 @@ void gXAxis::Plot(gGraphWindow & w,float scrx,float scry)
qint64 xx=maxx-minx; qint64 xx=maxx-minx;
if (xx<=0) return; if (xx<=0) return;
qint64 rxx=w.rmax_x-w.rmin_x;
QString fd,fmt; QString fd,tmpstr;
int divisors[]={86400000,3600000,2700000,1800000,1200000,900000,600000,300000,120000,60000,45000,30000,20000,15000,10000,5000,2000,1000,100,50}; int divisors[]={86400000,3600000,2700000,1800000,1200000,900000,600000,300000,120000,60000,45000,30000,20000,15000,10000,5000,2000,1000,100,50};
int divcnt=sizeof(divisors)/sizeof(int); int divcnt=sizeof(divisors)/sizeof(int);
int divmax,dividx; int divmax,dividx;
int fitmode; int fitmode;
if (xx>86400000L) { // Day if (xx>86400000L) { // Day
fd="00 MMM"; fd="00 MMM";
fmt="dd MMM";
dividx=0; dividx=0;
divmax=1; divmax=1;
fitmode=0; fitmode=0;
} else if (xx>60000) { // Minutes } else if (xx>600000) { // Minutes
fd="00:00"; fd="00:00";
dividx=1; dividx=1;
divmax=10; divmax=10;
fitmode=1; fitmode=1;
} else if (xx>5000) { // Seconds } else if (xx>60000) { // Seconds
fd="00:00:00"; fd="00:00:00";
dividx=9; dividx=9;
divmax=16; divmax=16;
@ -107,48 +105,48 @@ void gXAxis::Plot(gGraphWindow & w,float scrx,float scry)
} }
} }
if (fit_ticks==0) { if (fit_ticks==0) {
qDebug() << "FitTicks==0!"; qDebug() << "gXAxis::Plot() FitTicks==0!";
return; return;
} }
if (div<0) { if ((div<0) || (div>divcnt)) {
qDebug() << "div<0"; qDebug() << "gXAxis::Plot() div out of bounds";
return; return;
} }
qint64 step=divisors[div]; qint64 step=divisors[div];
qint64 zqvx=minx-w.rmin_x; // Amount of time before minx //Align left minimum to divisor by losing precision
qint64 zz=zqvx/step; // Number of ticks that fit up to minx
//Align left minimum to divisor
qint64 aligned_start=minx/step; qint64 aligned_start=minx/step;
aligned_start*=step; aligned_start*=step;
/*qint64 rm=w.rmin_x % step; // Offset from rminx of an aligned time qint32 vertcnt=0;
rm=step-rm; GLshort * vertarray=vertex_array[0];
rm+=w.rmin_x; if (vertarray==NULL) {
//qint64 rd=w.rmin_x / divisors[div]; qWarning() << "VertArray==NULL";
//rd*=divisors[div]; return;
qint64 aligned_start=(zz*step)+rm; // First location of aligned point. }
*/
while (aligned_start<minx) { while (aligned_start<minx) {
aligned_start+=step; aligned_start+=step;
} }
aligned_start/=step;
aligned_start*=step;
double xmult=double(width)/double(xx); double xmult=double(width)/double(xx);
w.qglColor(Qt::black); double step_pixels=double(step/10.0)*xmult;
QString tmpstr; py=start_px+double(aligned_start-minx)*xmult;
for (int i=0;i<10;i++) {
py-=step_pixels;
if (py<start_px) continue;
vertarray[vertcnt++]=py;
vertarray[vertcnt++]=start_py;
vertarray[vertcnt++]=py;
vertarray[vertcnt++]=start_py-4;
}
for (qint64 i=aligned_start;i<maxx;i+=step) { for (qint64 i=aligned_start;i<maxx;i+=step) {
px=double(i-minx)*xmult; px=double(i-minx)*xmult;
px+=start_px; px+=start_px;
glBegin(GL_LINES); vertarray[vertcnt++]=px;
glVertex2f(px,start_py); vertarray[vertcnt++]=start_py;
glVertex2f(px,start_py-6); vertarray[vertcnt++]=px;
glEnd(); vertarray[vertcnt++]=start_py-6;
if (fitmode==0) { if (fitmode==0) {
} else { } else {
qint64 j=i+tz_offset; qint64 j=i+tz_offset;
@ -164,160 +162,34 @@ void gXAxis::Plot(gGraphWindow & w,float scrx,float scry)
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')); 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'));
} }
} }
DrawText(w,tmpstr,px-(x/2),scry-(w.GetBottomMargin()-12),0); DrawText(w,tmpstr,px-(x/2),scry-(w.GetBottomMargin()-18),0);
py=px;
} for (int j=1;j<10;j++) {
int i=0; py+=step_pixels;
/* return; if (py>=scrx-w.GetRightMargin()) break;
// subtract 1.. align to first div unit
float zwv2=zqvx/max_ticks; // Number of ticks that would fit before
float gv;
float res=fmodf(zwv2,gv);
double jj=1/max_ticks;
double minor_tick=max_ticks*double(xx);
double st2=minx; //double(int(frac*1440.0))/1440.0;
double st,q;
bool show_seconds=false;
bool show_milliseconds=false;
bool show_time=true;
double min_tick;
if (xx<86400000) {
//double rounding[16]={12,24,48,72,96,144,288,720,1440,2880,5760,8640,17280,86400,172800,345600}; // time rounding
double rounding[16]={7200000,3600000,1800000,1200000,900000,600000,300000,120000,60000,45000,30000,15000,10000,5000,2000,1000};
int ri;
for (ri=0;ri<16;ri++) {
st=round(st2*rounding[ri])/rounding[ri];
min_tick=round(minor_tick*rounding[ri])/rounding[ri];
q=xx/min_tick; // number of ticks that fits in range
if (q<=jj) break; // compared to number of ticks that fit on screen.
}
if (min_tick<60000) show_seconds=true;
if (min_tick<10000) show_milliseconds=true;
if (min_tick<=1000)
min_tick=1000;
} else { // Day ticks..
show_time=false;
st=st2;
min_tick=1.0;
double mtiks=(x+20.0)/width;
double mt=mtiks*xx;
min_tick=mt;
//if (min_tick<1.0) min_tick=1.0;
//if (min_tick>10) min_tick=10;
}
if (min_tick<=0) {
qWarning() << "gXAxis::Plot() min_tick<=0 :(";
return;
}
double st3=st;
//while (st3>minx) {
// st3-=min_tick/10.0;
//}
//st3+=min_tick/10.0;
py=w.GetBottomMargin();
qint32 vertcnt=0;
GLshort * vertarray=vertex_array[0];
if (vertarray==NULL) {
qWarning() << "VertArray==NULL";
return;
}
if (m_show_minor_ticks) {
for (double i=st3; i<=maxx; i+=min_tick/10.0) {
if (i<minx) continue;
px=(i-minx)*xmult+w.GetLeftMargin();
vertarray[vertcnt++]=px;
vertarray[vertcnt++]=py; vertarray[vertcnt++]=py;
vertarray[vertcnt++]=px; vertarray[vertcnt++]=start_py;
vertarray[vertcnt++]=py-4;
if (vertcnt>=maxverts) {
qWarning() << "gXAxis::Plot() maxverts exceeded trying to draw minor ticks";
return;
}
}
}
//while (st<minx) {
// st+=min_tick/10.0; // mucking with this changes the scrollyness of the ticker.
//}
int hour,minute,second,millisecond;
QDateTime d;
// Need to use Qpainter clipping..
// messy. :(
glScissor(w.GetLeftMargin()-20,0,width+20,w.GetBottomMargin());
glEnable(GL_SCISSOR_TEST);
//const double extra=min_tick/10.0;
const double extra=0;
for (double i=st; i<=maxx+extra; i+=min_tick) {
d=QDateTime::fromMSecsSinceEpoch(i);
if (show_time) {
minute=d.time().minute();
hour=d.time().hour();
second=d.time().second();
millisecond=d.time().msec();
if (show_milliseconds) {
fd.sprintf("%02i:%02i:%02i:%03i",hour,minute,second,millisecond);
} else if (show_seconds) {
fd.sprintf("%02i:%02i:%02i",hour,minute,second);
} else {
fd.sprintf("%02i:%02i",hour,minute);
}
} else {
fd=d.toString("MMM dd");
}
px=(i-minx)*xmult+w.GetLeftMargin();
if ((i>=st && i<=maxx) && (m_show_major_ticks)) {
vertarray[vertcnt++]=px;
vertarray[vertcnt++]=py; vertarray[vertcnt++]=py;
vertarray[vertcnt++]=px; vertarray[vertcnt++]=start_py-4;
vertarray[vertcnt++]=py-6;
if (vertcnt>=maxverts) { if (vertcnt>=maxverts) {
qWarning() << "gXAxis::Plot() maxverts exceeded trying to draw Major ticks"; break;
return;
} }
} }
GetTextExtent(fd,x,y);
if (!show_time) {
DrawText(w,fd, px+y, scry-(py-(x/2)-8), 90.0);
} else {
DrawText(w,fd, px-(x/2), scry-(py-8-y));
}
}
// Draw the little ticks.
if (vertcnt>=maxverts) { if (vertcnt>=maxverts) {
qWarning() << "maxverts exceeded in gYAxis::Plot()"; qWarning() << "maxverts exceeded in gXAxis::Plot()";
return; break;
}
} }
glLineWidth(1);
glColor3f(0,0,0);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glLineWidth(1);
w.qglColor(Qt::black);
glVertexPointer(2, GL_SHORT, 0, vertarray); glVertexPointer(2, GL_SHORT, 0, vertarray);
glDrawArrays(GL_LINES, 0, vertcnt>>1); glDrawArrays(GL_LINES, 0, vertcnt>>1);
glDisableClientState(GL_VERTEX_ARRAY); // deactivate vertex arrays after drawing glDisableClientState(GL_VERTEX_ARRAY); // deactivate vertex arrays after drawing
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
*/
} }