/* gXAxis Implementation Copyright (c)2011 Mark Watkins License: GPL */ #include #include #include "gXAxis.h" gXAxis::gXAxis(QColor col) :gLayer(EmptyChannel) { m_line_color=col; m_text_color=col; m_major_color=Qt::darkGray; m_minor_color=Qt::lightGray; m_show_major_lines=false; m_show_minor_lines=false; m_show_minor_ticks=true; m_show_major_ticks=true; } gXAxis::~gXAxis() { } void gXAxis::Plot(gGraphWindow & w,float scrx,float scry) { float px,py; int start_px=w.GetLeftMargin(); int start_py=w.GetBottomMargin(); float width=scrx-(w.GetLeftMargin()+w.GetRightMargin()); // float height=scry-(w.GetTopMargin()+w.GetBottomMargin()); if (width<40) return; qint64 minx; qint64 maxx; if (w.BlockZoom()) { minx=w.rmin_x; maxx=w.rmax_x; } else { minx=w.min_x; maxx=w.max_x; } qint64 xx=maxx-minx; if (xx<=0) return; qint64 rxx=w.rmax_x-w.rmin_x; QString fd,fmt; 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 divmax,dividx; int fitmode; if (xx>86400000L) { // Day fd="00 MMM"; fmt="dd MMM"; dividx=0; divmax=1; fitmode=0; } else if (xx>60000) { // Minutes fd="00:00"; dividx=1; divmax=10; fitmode=1; } else if (xx>5000) { // Seconds fd="00:00:00"; dividx=9; divmax=16; fitmode=2; } else { // Microseconds fd="00:00:00:000"; dividx=15; divmax=divcnt; fitmode=3; } float x,y; GetTextExtent(fd,x,y); if (x<=0) { // font size bug qWarning() << "gXAxis::Plot() x<=0"; return; } float max_ticks=float(width)/(x+10); // Max number of ticks that will fit float fit_ticks=0; int div=-1; float closest=0,tmp,tmpft; for (int i=dividx;iclosest) { // Find the closest scale to the number closest=tmpft; // that will fit div=i; fit_ticks=tmpft; } } if (fit_ticks==0) { qDebug() << "FitTicks==0!"; return; } if (div<0) { qDebug() << "div<0"; return; } qint64 step=divisors[div]; qint64 zqvx=minx-w.rmin_x; // Amount of time before minx qint64 zz=zqvx/step; // Number of ticks that fit up to minx //Align left minimum to divisor qint64 rm=w.rmin_x % step; // Offset from rminx of an aligned time rm=step-rm; rm+=w.rmin_x; //qint64 rd=w.rmin_x / divisors[div]; //rd*=divisors[div]; qint64 aligned_start=(zz*step)+rm; // First location of aligned point. aligned_start/=step; aligned_start*=step; while (aligned_start10) 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=maxverts) { qWarning() << "gXAxis::Plot() maxverts exceeded trying to draw minor ticks"; return; } } } //while (st=st && i<=maxx) && (m_show_major_ticks)) { vertarray[vertcnt++]=px; vertarray[vertcnt++]=py; vertarray[vertcnt++]=px; vertarray[vertcnt++]=py-6; if (vertcnt>=maxverts) { qWarning() << "gXAxis::Plot() maxverts exceeded trying to draw Major ticks"; 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) { qWarning() << "maxverts exceeded in gYAxis::Plot()"; return; } glLineWidth(1); glColor3f(0,0,0); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_SHORT, 0, vertarray); glDrawArrays(GL_LINES, 0, vertcnt>>1); glDisableClientState(GL_VERTEX_ARRAY); // deactivate vertex arrays after drawing glDisable(GL_SCISSOR_TEST); }